首页 > 解决方案 > 修复 AddressSanitizer:strcpy-param-overlap 与 memmove?

问题描述

我在一个老旧且漏洞百出的 C 程序中闲逛。使用编译时,gcc -fsanitize=address在运行程序本身时出现此错误:

==635==ERROR: AddressSanitizer: strcpy-param-overlap: memory ranges [0x7f37e8cfd5b5,0x7f37e8cfd5b8) and [0x7f37e8cfd5b5, 0x7f37e8cfd5b8) overlap
    #0 0x7f390c3a8552 in __interceptor_strcpy /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cc:429
    #1 0x56488e5c1a08 in backupExon src/BackupGenes.c:72
    #2 0x56488e5c2df1 in backupGene src/BackupGenes.c:134
    #3 0x56488e5c426e in BackupArrayD src/BackupGenes.c:227
    #4 0x56488e5c0bb1 in main src/geneid.c:583
    #5 0x7f390b6bfee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
    #6 0x56488e5bf46d in _start (/home/darked89/proj_soft/geneidc/crg_github/geneidc/bin/geneid+0x1c46d)

0x7f37e8cfd5b5 is located 3874229 bytes inside of 37337552-byte region [0x7f37e894b800,0x7f37eace71d0)
allocated by thread T0 here:
    #0 0x7f390c41bce8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x56488e618728 in RequestMemoryDumpster src/RequestMemory.c:801
    #2 0x56488e5bfcea in main src/geneid.c:305
    #3 0x7f390b6bfee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)

错误是由这一行引起的:

/* backupExon src/BackupGenes.c:65 */
strcpy(d->dumpSites[d->ndumpSites].subtype, E->Acceptor->subtype);

我已将其替换为:

memmove(d->dumpSites[d->ndumpSites].subtype, E->Acceptor->subtype, 
strlen(d->dumpSites[d->ndumpSites].subtype));

错误消失了,使用 2 个不同的数据输入产生的程序输出与更改前获得的结果相同。顺便说一句,更多的 strcpy 错误仍然存​​在于源代码中。我需要确认这是修复它的方法。

问题和其余代码在这里: https ://github.com/darked89/geneidc/issues/2

标签: cstrcpyaddress-sanitizermemmove

解决方案


假设E->Acceptor->subtype至少只要d->dumpSites[d->ndumpSites].subtype 那么就没有问题。如果您还没有,您可能想先检查一下。 实际上,您还需要一个 +1 来复制字符串终止符 ( \0),感谢@R..发现它。

您之前的代码做出了不同的假设:它假设d->dumpSites[d->ndumpSites].subtype至少与E->Acceptor->subtype(基本上相反)一样长。

真正的等价物是:

memmove(
    d->dumpSites[d->ndumpSites].subtype,
    E->Acceptor->subtype,
    strlen(E->Acceptor->subtype) + 1
);

这是修复代码以允许重叠的正确方法。


推荐阅读