WSL Ubuntu 22.04下使用zip.h库触发MemorySanitizer未初始化内存告警
问题:MemorySanitizer检测加密Zip读取代码时报告未初始化内存异常
我写了一段C语言代码用来打开加密Zip文件并读取内容,程序运行正常,但用Google MemorySanitizer(Msan)检测时,出现未初始化内存的告警;Valgrind和其他Google sanitizer工具都没报问题。当前环境是最新版WSL Ubuntu 22.04.2,所有包都是最新的。这个问题在另一台WSL Ubuntu 22.04机器上能复现,但WSL Ubuntu 20.04下没有告警。想问这段代码有没有疏漏?这个告警是库的bug还是Msan的误报?
错误栈信息
Uninitialized bytes in __interceptor_fopen64 at offset 0 inside [0x702000006ba0, 25) ==4630==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x7f944a1ed197 in BIO_new_file (/lib/x86_64-linux-gnu/libcrypto.so.3+0xe2197) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #1 0x7f944a2243ed (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1193ed) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #2 0x7f944a225051 in CONF_modules_load_file_ex (/lib/x86_64-linux-gnu/libcrypto.so.3+0x11a051) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #3 0x7f944a2c9d2f (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1bed2f) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #4 0x7f944a5faf67 in __pthread_once_slow nptl/./nptl/pthread_once.c:116:7 #5 0x7f944a2cd76c in CRYPTO_THREAD_run_once (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1c276c) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #6 0x7f944a2ca795 in OPENSSL_init_crypto (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1bf795) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #7 0x7f944a2f3b1d (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1e8b1d) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #8 0x7f944a2976de (/lib/x86_64-linux-gnu/libcrypto.so.3+0x18c6de) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #9 0x7f944a39f927 (/lib/x86_64-linux-gnu/libcrypto.so.3+0x294927) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #10 0x7f944a3a007d (/lib/x86_64-linux-gnu/libcrypto.so.3+0x29507d) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #11 0x7f944a28b4b2 in EVP_MD_fetch (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1804b2) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #12 0x7f944a2ac9e5 in PKCS5_PBKDF2_HMAC_SHA1 (/lib/x86_64-linux-gnu/libcrypto.so.3+0x1a19e5) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) #13 0x7f944a8a2e48 (/lib/x86_64-linux-gnu/libzip.so.4+0x12e48) (BuildId: 02d1d621ce8e46311d39fa109b824b70dc2a7e1e) #14 0x7f944a8a545a (/lib/x86_64-linux-gnu/libzip.so.4+0x1545a) (BuildId: 02d1d621ce8e46311d39fa109b824b70dc2a7e1e) #15 0x7f944a898f8a (/lib/x86_64-linux-gnu/libzip.so.4+0x8f8a) (BuildId: 02d1d621ce8e46311d39fa109b824b70dc2a7e1e) #16 0x7f944a8a3e91 in zip_source_open (/lib/x86_64-linux-gnu/libzip.so.4+0x13e91) (BuildId: 02d1d621ce8e46311d39fa109b824b70dc2a7e1e) #17 0x7f944a8a3e7f in zip_source_open (/lib/x86_64-linux-gnu/libzip.so.4+0x13e7f) (BuildId: 02d1d621ce8e46311d39fa109b824b70dc2a7e1e) #18 0x7f944a89c974 in zip_fopen_index_encrypted (/lib/x86_64-linux-gnu/libzip.so.4+0xc974) (BuildId: 02d1d621ce8e46311d39fa109b824b70dc2a7e1e) SUMMARY: MemorySanitizer: use-of-uninitialized-value (/lib/x86_64-linux-gnu/libcrypto.so.3+0xe2197) (BuildId: f41db69553ac874b43c3ab46a4e0973d2405a1d1) in BIO_new_file Exiting
最小复现代码
#include <stdio.h> #include <stdlib.h> #include <zip.h> #define MAX_STRING_LEN 256 int main() { char* file = (char*)calloc(MAX_STRING_LEN, sizeof(char)); if (scanf("%s", file) != 1) { fprintf(stderr, "Error reading file path\n"); return EXIT_FAILURE; } int32_t error = EXIT_SUCCESS; zip_error_t zip_error; zip_t* zip = zip_open(file, ZIP_RDONLY, &error); free(file); if (zip == NULL) { zip_error_init_with_code(&zip_error, error); fprintf(stderr, "Failed to open zip archive: %s\n", zip_error_strerror(&zip_error)); return EXIT_FAILURE; } zip_file_t* open_zip = zip_fopen_index_encrypted(zip, 0, ZIP_FL_ENC_GUESS, "0000"); // Change this String for the password of the Zip file if (open_zip == NULL) { zip_close(zip); return EXIT_FAILURE; } else { printf("Zip was opened\n"); } zip_fclose(open_zip); zip_close(zip); return EXIT_SUCCESS; }
编译命令
mkdir -p build/ clang -c -Wall -Wextra -g -fsanitize=memory -std=c17 -I. -I./build -MMD main.c -o build/main.o mkdir -p bin/ clang -Wall -Wextra -g -fsanitize=memory -I. -I./bin -I./build build/main.o -o bin/zipmem -lzip
分析与解答
你的代码本身没有明显疏漏:
- 用
calloc初始化了文件路径缓冲区,避免了未初始化内存风险 - 正确处理了所有库函数的返回值,资源释放逻辑完整
- 密码字符串是常量,不存在未初始化问题
这个告警不是你的代码导致的,而是依赖库的兼容性问题,具体原因如下:
- 错误栈显示问题出在OpenSSL 3.x的
BIO_new_file调用中,属于OpenSSL初始化加载配置文件的内部逻辑,和你的业务代码完全无关 - Ubuntu 20.04默认使用OpenSSL 1.1.1,而22.04升级到了OpenSSL 3.x,这是两个环境表现不同的核心原因
- MemorySanitizer对未初始化内存的检测极为严格,但系统预编译的OpenSSL库并没有用Msan编译,导致Msan无法追踪库内部的内存初始化状态,从而产生误报(或者库内部确实存在不影响功能的未初始化内存)
验证与解决建议
- 手动用Msan编译OpenSSL和libzip,再链接到你的程序,如果告警消失,就能确认是预编译库的问题
- 若不想重新编译库,可以添加Msan抑制规则,忽略OpenSSL相关的未初始化告警,不会影响对业务代码的检测
- 由于Valgrind和其他sanitizer都未报告问题,且程序运行正常,这个告警不影响实际功能,可暂时忽略
内容的提问来源于stack exchange,提问作者CodingQuestions
相关产品推荐
相关产品推荐

