结构内的字符串 malloc 溢出
Posted
技术标签:
【中文标题】结构内的字符串 malloc 溢出【英文标题】:Malloc of string inside struct overflows 【发布时间】:2021-07-12 22:44:52 【问题描述】:以下代码是我目前正在进行的项目的示例,用 C 编码。
我首先 malloc 一个结构,然后作为示例 malloc 将第一个内部的字符串。当我尝试将文本从另一个字符串复制到其中并使用printf
函数打印时,当我使用-fsanitize=address
作为编译标志进行编译时,它会溢出。
但我不明白为什么,因为我认为我正在为字符串分配足够的内存,因为我只是使用另一个字符串的strlen
来获取长度,而\0
有一个额外的字符。
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef struct s_word
int length;
char *str;
t_word;
typedef struct s_list
t_word *word;
t_list;
int main(void)
int i;
char *line = "this is a test";
t_list test;
i = -1;
test.word = malloc(sizeof(t_word) * 10);
test.word[0].str = malloc(sizeof(char) * (strlen(line) + 1));
while (line[++i])
test.word[0].str[i] = line[i];
printf("%s\n", test.word[0].str);
return (0);
=================================================================
==48531==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x00010940071f at pc 0x00010543ef60 bp 0x00016aee76a0 sp 0x00016aee6e28
READ of size 16 at 0x00010940071f thread T0
#0 0x10543ef5c in printf_common(void*, char const*, char*)+0x750 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x1ef5c)
#1 0x10543f7b8 in wrap_printf+0x78 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x1f7b8)
#2 0x104f1bc64 in main+0x3ac (a.out:arm64+0x100003c64)
#3 0x193291f30 in start+0x0 (libdyld.dylib:arm64e+0x16f30)
0x00010940071f is located 0 bytes to the right of 15-byte region [0x000109400710,0x00010940071f)
allocated by thread T0 here:
#0 0x10545fa6c in wrap_malloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3fa6c)
#1 0x104f1ba20 in main+0x168 (a.out:arm64+0x100003a20)
#2 0x193291f30 in start+0x0 (libdyld.dylib:arm64e+0x16f30)
SUMMARY: AddressSanitizer: heap-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x1ef5c) in printf_common(void*, char const*, char*)+0x750
Shadow bytes around the buggy address:
0x0070212a0090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a00a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a00b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a00c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a00d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0070212a00e0: fa fa 00[07]fa fa 00 06 fa fa 00 00 fa fa 00 fa
0x0070212a00f0: fa fa 00 00 fa fa fd fd fa fa fa fa fa fa fa fa
0x0070212a0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a0110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a0120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0070212a0130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==48531==ABORTING
【问题讨论】:
【参考方案1】:当line[++i]
变为零时,循环while (line[++i])
被中断,因此终止的空字符不会复制到test.word[0].str
。复制应该是这样的:
do
++i;
test.word[0].str[i] = line[i];
while (line[i]);
另一种选择是简单地使用strcpy()
:
strcpy(test.word[0].str, line);
【讨论】:
谢谢!那为我修好了。欣赏它。以上是关于结构内的字符串 malloc 溢出的主要内容,如果未能解决你的问题,请参考以下文章