简体   繁体   English

无法修复我的 C 代码上的堆缓冲区溢出错误

[英]Can't fix heap-buffer-overflow error on my C code

I need help fixing an fsanitize=address error on this code.我需要帮助修复此代码上的 fsanitize=address 错误。 If I compile my.c program with the flags "fsanitize=address -g" I get the following error:如果我使用标志“fsanitize=address -g”编译 my.c 程序,我会收到以下错误:

==93042==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x000107903a7c at pc 0x0001052aa780 bp 0x00016b2af490 sp 0x00016b2aec48
READ of size 1 at 0x000107903a7c thread T0
    #0 0x1052aa77c in wrap_strchr+0x18c (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x1677c)
    #1 0x104b50b70 in processData front.c:50
    #2 0x104b509d0 in main front.c:27
    #3 0x104eb5088 in start+0x204 (dyld:arm64e+0x5088)

The function I'm having problems with is called "processData".我遇到问题的 function 称为“processData”。 It gets a "char * data" which contains an entire CSV file (which has been copied as a string to it), and divides the csv file in lines.它得到一个包含整个 CSV 文件(已作为字符串复制到其中)的“char * 数据”,并将 csv 文件分成几行。 Each line is then sent to a "loadData" function. The "processData()" function starts by declaring two pointers: "string", which points to the character string passed as an argument, and "line", which initially points to the '\n' character (new line) in the "data" string.然后将每一行发送到“loadData”function。“processData()”function 首先声明两个指针:“string”,它指向作为参数传递的字符串,以及“line”,它最初指向“数据”字符串中的 '\n' 字符(新行)。 Then, function enters a loop that runs while there are lines left in the "data" string.然后,function 进入一个循环,该循环在“数据”字符串中还有剩余行时运行。 Inside the loop, the function calculates the size of the current line by subtracting the value of "string" from the value of "line".在循环内部,function 通过从“line”的值中减去“string”的值来计算当前行的大小。 Then, it creates a "aux" variable to store the current line and copies the line into the "aux" variable using "strncpy()".然后,它创建一个“aux”变量来存储当前行,并使用“strncpy()”将该行复制到“aux”变量中。 Next, the function adds a null character at the end of the "aux" string to indicate the end of the string.接下来,function在“aux”字符串的末尾添加了一个null字符,表示字符串结束。 Then, it sends the line to the "loadLine()" function passed as an argument for processing.然后,它将行发送到作为参数传递的“loadLine()”function 进行处理。 Finally, it updates the "string" pointer to point to the beginning of the next line in the "data" string.最后,它更新“字符串”指针以指向“数据”字符串中下一行的开头。 Once all lines in the "data" string have been processed, the "processData()" function ends and returns control to the caller.一旦处理完“data”字符串中的所有行,“processData()”function 结束并将控制返回给调用者。

This is what the processData function looks like (I have highlighted line 50):这就是 processData function 的样子(我突出显示了第 50 行):

void processData(sensorADT s, char * data, loadLine loadData) {
  // Pointer to the "data" string
  char * string = data;

  // Pointer to the '\n' character (new line) in the "data" string
  char * line;
  
  // Loop that runs while there are lines left in the "data" string
  // THE FOLLOWING LINE IS LINE 50:
  while (string != NULL && (line = strchr(string,'\n')) != NULL) {
    // Calculates the size of the current line
    int len = line - string;

    // Creates a "aux" variable to store the current line
    char aux[len + 1];

    // Copies the current line in the "aux" variable
    strncpy(aux, string, len);

    // Adds a null character at the end of the line to indicate the end of the string
    aux[len] = 0;

    // Sends the line to the "loadLine()" function for processing
    loadData(s, aux);

    // Updates the "string" pointer to point to the beginning of the next line
    string = line + 1;
  }
}

If I try compiling and running the code without the sanitizer on, it works as intended.如果我尝试在没有消毒剂的情况下编译和运行代码,它会按预期工作。

Thanks!谢谢!

I tried compiling my program with the sanitize flag on, and I get that error.我尝试在启用清理标志的情况下编译我的程序,但出现了该错误。 If I compile it without the sanitizer flag, it runs flawlessly and gives me the expected results.如果我在没有 sanitizer 标志的情况下编译它,它会完美运行并给出预期的结果。

According to your error message, the culprit is wrap_strchr() , which is reading after the allocated space of the string.根据您的错误消息,罪魁祸首是wrap_strchr() ,它在分配的字符串空间之后读取。

Since strchr() should stop at the final '\0' of the string and return NULL , my guess is that your data is not null-terminated at all.由于strchr()应该在字符串的最后一个'\0'处停止并返回NULL ,我猜你的data根本不是以 null 结尾的。

By the way, that also means that strlen() will trigger the same error.顺便说一句,这也意味着strlen()将触发相同的错误。

There is no easy way out of this error inside the function. Either you add a size_t len parameter or ensure that the string is null-terminated in the caller .没有简单的方法可以解决 function 中的此错误。要么添加size_t len参数,要么确保字符串在 caller 中以null 结尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM