在一切正常安装的情况下,我在RHEL 6.9上遇到了带有lib crypto的段错误。我将其简化为以下测试程序:
extern "C" {
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <string.h>
}
int main ( int , char const** )
{
char const* publicKey = "-----BEGIN PUBLIC KEY-----\n"
"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs/6Nf24RG1cXBbww6MlM\n"
"7anHA4dvqjHyYDC3SENEqWtmW/yRXh9sJs3dfsBWIW610huTMvYRzqZ9c95t6h5W\n"
"EicsNC/396KNBLbDP3urDtKVq5z5djTPWQGpi3Jdx7OISszW4eOWQzArjGCYAwM8\n"
"XpmXm92JA3lFPQkCDW/yp8UyG/VKWV/t25YKqmkUhp6bvpVZpifAAQlDDZ6t60tq\n"
"dxMuDkYC+HyZS+Z63SCMErFqbXwwNSQS+5fgr7B7fgJb8c+8od+n8Fza2jEG9Qc5\n"
"jpGjrttT52DmVpIJvDQaqwFfswgMrnAE4KNIwZvmiQXCUVgbHz4b8Ftjotwqt7QX\n"
"ZyC5VGsW8pksVtV4Iqo5QTxi0ZVyFKLFX35VjwUrxiZCRx/44RXdveX2wbf3My+5\n"
"vS9fW1VGipxdfcebOqosvP7Q1aegx4MBqAUt71XqtOIWRHWQJaVHji+ohjqRp/gQ\n"
"XXqSvBLzTXAW530fSTC8Qjcdyd0IOwclCH4ZKYcTf74G70kdCo9tSkPUTvw3kqCz\n"
"2bev5BcVf4FUR1m1XF868vj+pQCBfGkm5AKvhJyXMuCGnTKAMMysJj9iCp73q5z0\n"
"jIYDKgWpfF3mBZJBHhqUL8/3s3ZmboeRrO1nWB0MVXBYIAUUy9YquQitMMjOhoZ1\n"
"+heBhiVxr2R10QvOg+yL68UCAwEAAQ==\n"
"-----END PUBLIC KEY-----" ;
FILE * f = fopen("out.pem","wb") ;
fwrite ( publicKey , 1 , strlen(publicKey) , f ) ;
fclose ( f ) ;
size_t bufferLen = strlen(publicKey) ;
char* buffer = (char*)malloc(bufferLen+1) ;
memcpy ( (void*)buffer , (void const*)publicKey , size_t(bufferLen+1) ) ;
BIO * keybio = BIO_new_mem_buf(buffer,bufferLen) ;
RSA* rsa (0) ;
PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
RSA_check_key ( rsa ) ;
return 0 ;
}
我可以使用由此编写的out.pem文件使用openssl成功加密内容,因此密钥是有效的。 (此外,此密钥是使用openssl命令行实用程序生成的。)
我用它来编译和调试该测试程序:
g++ -g -lcrypto rsa_test.cpp && gdb ./a.out
where
是:
#0 0x0000003caeea70b1 in BN_num_bits () from /usr/lib64/libcrypto.so.10
#1 0x0000003caeeadf0a in BN_is_prime_fasttest_ex () from /usr/lib64/libcrypto.so.10
#2 0x0000003caeec927a in RSA_check_key () from /usr/lib64/libcrypto.so.10
#3 0x00000000004009d7 in main () at rsa_test.cpp:37
info break
是:
(gdb) info shared
From To Syms Read Shared Object Library
0x0000003ca6600b30 0x0000003ca661a26b Yes (*) /lib64/ld-linux-x86-64.so.2
0x0000003caee69d80 0x0000003caef5ef98 Yes (*) /usr/lib64/libcrypto.so.10
0x0000003cada563f0 0x0000003cadac33a6 Yes (*) /usr/lib64/libstdc++.so.6
0x0000003ca7603e60 0x0000003ca76443d8 Yes (*) /lib64/libm.so.6
0x0000003caaa02910 0x0000003caaa12f78 Yes (*) /lib64/libgcc_s.so.1
0x0000003ca6a1ea60 0x0000003ca6b4032c Yes (*) /lib64/libc.so.6
0x0000003ca7200de0 0x0000003ca7201998 Yes (*) /lib64/libdl.so.2
0x0000003ca7a02120 0x0000003ca7a0d3a8 Yes (*) /lib64/libz.so.1
(*): Shared library is missing debugging information.
当我在反汇编中四处查看时,似乎将null传递给BN_is_prime_fasttest_ex,因此将BNNUM位数传递给BIGNUM指针。
(gdb) frame 3
#3 0x00000000004009d7 in main () at rsa_test.cpp:37
37 RSA_check_key ( rsa ) ;
(gdb) print *keybio
$1 = {method = 0x3caf1d8c60, callback = 0, cb_arg = 0x0, init = 1, shutdown = 1, flags = 512, retry_reason = 0, num = 0, ptr = 0x6025b0, next_bio = 0x0, prev_bio = 0x0,
references = 1, num_read = 0, num_write = 0, ex_data = {sk = 0x0, dummy = 0}}
(gdb) print *rsa
$2 = {pad = 0, version = 0, meth = 0x3caf1d6ce0, engine = 0x0, n = 0x602d80, e = 0x602fb0, d = 0x0, p = 0x0, q = 0x0, dmp1 = 0x0, dmq1 = 0x0, iqmp = 0x0, ex_data = {sk = 0x0,
dummy = 0}, references = 1, flags = 1030, _method_mod_n = 0x0, _method_mod_p = 0x0, _method_mod_q = 0x0, bignum_data = 0x0, blinding = 0x0, mt_blinding = 0x0}
此代码已在其他RHEL系统上运行,所以我不知道为什么突然在这里不起作用。我最初在调用memcpy
之后拥有BIO_new_mem_buf
(当它在其他RHEL 5系统上工作时),但是在调试过程中将其移至较早版本,以防万一。
以下是分段故障本身的反汇编:
(gdb) disas
Dump of assembler code for function BN_num_bits:
0x0000003caeea70b0 <+0>: push %rbx
=> 0x0000003caeea70b1 <+1>: mov 0x8(%rdi),%ebx
0x0000003caeea70b4 <+4>: xor %eax,%eax
0x0000003caeea70b6 <+6>: test %ebx,%ebx
0x0000003caeea70b8 <+8>: jne 0x3caeea70c0 <BN_num_bits+16>
0x0000003caeea70ba <+10>: pop %rbx
0x0000003caeea70bb <+11>: retq
0x0000003caeea70bc <+12>: nopl 0x0(%rax)
0x0000003caeea70c0 <+16>: mov (%rdi),%rax
0x0000003caeea70c3 <+19>: sub $0x1,%ebx
0x0000003caeea70c6 <+22>: movslq %ebx,%rdx
0x0000003caeea70c9 <+25>: shl $0x6,%ebx
0x0000003caeea70cc <+28>: mov (%rax,%rdx,8),%rdi
0x0000003caeea70d0 <+32>: callq 0x3caeea6f80 <BN_num_bits_word>
0x0000003caeea70d5 <+37>: add %ebx,%eax
0x0000003caeea70d7 <+39>: pop %rbx
0x0000003caeea70d8 <+40>: retq
End of assembler dump.
还有info reg
:
rax 0x1 1
rbx 0x2 2
rcx 0x0 0
rdx 0x0 0
rsi 0x3caf1c3c30 260635900976
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffdbb0 0x7fffffffdbb0
r8 0x0 0
r9 0x0 0
r10 0x40 64
r11 0x3caeec91d0 260632777168
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x602990 6302096
rip 0x3caeea70b1 0x3caeea70b1 <BN_num_bits+1>
eflags 0x10246 [ PF ZF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
所以...。为什么会发生段错误?