【问题标题】:How to avoid buffer overflow with C struct array of strings如何使用 C 结构字符串数组避免缓冲区溢出
【发布时间】:2020-01-26 05:21:35
【问题描述】:

在读取 C 文件和复制字符数组时,我遇到了缓冲区溢出。有三段可能有问题的代码,我不知道哪里出错了。

第一个读取文件并将其填充到哈希图中:

bool load_file(const char* in_file, hmap hashtable[]) {

    for(int x = 0; x < HASH_SIZE; x++) {
        hashtable[x] = NULL;
    }

    FILE *fptr = fopen(in_file, "r");

    char c[LENGTH] = "";
    c[0] = '\0';

    while (fgets(c, sizeof(c)-1, fptr) != NULL) {

        node *n = malloc(sizeof(node));
        hmap new_node = n;      
        new_node->next = NULL;
        strncpy(new_node->content, c, LENGTH-1);

        // do stuff to put it into the hashtable
    }

    fclose(fptr);
    return true;
}

第二个检查给定的内容是否在hashmap中:

bool check_content(const char* content, hmap hashtable[]) {

    char c_content[LENGTH] = "";
    strncpy(c_content, content, LENGTH-1);

    // do stuff to check if it's in the hashmap

    return false;
}

第三个解析给定文件并检查其内容是否在哈希图中:

int check_file(FILE* fp, hmap hashtable[], char * not_found[]) {

    int num_not_found = 0;
    char c[1000] = "";

    while (fgets(c, sizeof(c)-1, fp) != NULL) {

        char * pch;
        char curToken[LENGTH] = "";

        pch = strtok (c," ");
        strncpy(curToken, pch, LENGTH-1);
        curToken[LENGTH]=0;

        if(!check_content(curToken, hashtable)) {
            not_found[num_not_found] = malloc(LENGTH*sizeof(not_found[num_not_found]));
            strncpy(not_found[num_not_found], curToken, LENGTH-1);
            num_not_found++;
        }
    }
    fclose(fp);
    return num_not_found;
}

最后,main 调用这些并释放 malloc:

int main (int argc, char *argv[])
{   
    hmap hashtable[HASH_SIZE];
    load_file(argv[2], hashtable);

    FILE *fptr = fopen(argv[1], "r");
    char * not_found[MAX_ENTRIES];
    int num_not_found = check_file(fptr, hashtable, not_found);

    for(int x=0; x<num_not_found; x++) {
        free(not_found[x]);
    }

    for(int y=0; hashtable[y] != NULL; y++) {
        free(hashtable[y]);
    }

  return 0;
}

我的问题是:对于三个代码 sn-ps 中的每一个,我做了什么导致缓冲区溢出?非常感谢!

【问题讨论】:

  • strncpy(curToken, pch, LENGTH-1);(此时pch是什么??)
  • 哎呀,抱歉。 pch 是从标记行返回的内容。更新了代码。
  • sizeof(not_found[num_not_found])sizeof(a_pointer) 相同,而不是not_found[num_not_found] 指向的大小。 (除非您想要分配LENGTH * sizeof (a_pointer))看起来它应该导致过度分配而不是分配不足,但是如果没有看到MCVE,则无法确定。
  • 另外,对于一般的哈希表开发,我发现Coding up a Hash TableHash tables - eternally confuzzled 很有用。
  • 我明白了,谢谢指出这一点。 not_found[num_not_found] 肯定是char 所以我可以把它改成malloc(LENGTH*sizeof(char))?抱歉,代码不是 MCVE,我试图删减以避免在这里倾倒一堆代码。

标签: c arrays struct malloc buffer-overflow


【解决方案1】:

我最终摆脱了缓冲区溢出问题,主要是通过在 cmets 中遵循 David 的建议,并发现我的 malloc 比我需要的多一个。修复是:

  1. new_node-&gt;next 需要一个 malloc
  2. new_node-&gt;next 的 malloc 只有在实际使用时才会发生。
  3. not_found[num_not_found] = malloc(LENGTH*sizeof(not_found[num_not_found])); 是错误的,应该是 notfound[num_not_found] = malloc(sizeof(char) * (strlen(pch)+1)) (假设 pch 不是以空值终止的)。 (旁注,无论出于何种原因,在我的电脑上,malloc(sizeof(char) * strlen(pch)+1)malloc(strlen(pch)+1) 不同)
  4. 确实必须验证每个 malloc 的返回。

【讨论】:

    猜你喜欢
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 2013-10-22
    相关资源
    最近更新 更多