Исправление AddressSanitizer: strcpy-param-overlap с memmove? - PullRequest
2 голосов
/ 03 октября 2019

Я ковыряюсь в старой и довольно глючной 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));

Ошибка исчезла, и выходные данные программы с двумя различными входными данными идентичны результатам, полученным до изменения. Кстати, больше ошибок strcpy остаются ниже в источнике. Мне нужно подтверждение, что это способ исправить это.

Проблема и остальной код здесь: https://github.com/darked89/geneidc/issues/2

1 Ответ

1 голос
/ 03 октября 2019

Если предположить, что E->Acceptor->subtype по крайней мере равен d->dumpSites[d->ndumpSites].subtype , то проблем нет. Возможно, вы захотите проверить это в первую очередь, если вы этого еще не сделали. На самом деле , вам нужно +1, чтобы также скопировать терминатор строки (\0), спасибо @ R .. для его обнаружения.

Ваш предыдущий код делал другое предположение: он предполагал, что d->dumpSites[d->ndumpSites].subtype был по крайней мере таким же, как E->Acceptor->subtype (в основном обратное).

Эквивалент real будет выглядеть следующим образом:

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

Это правильный способ исправить код, допуская перекрытие.

...