如果在调用函数时缓冲区的数据类型不匹配(int *与unsigned int *)会发生什么?

时间:2017-06-28 11:35:42

标签: c heap-memory buffer-overflow

假设一个人有功能:

int somefunc(int* buf)

但我们通过以下方式调用somefunc:

somefunc(buf2)

其中buf2是由alloca分配的堆缓冲区,其数据类型为unsigned int(因此指针buf2的类型为unsigned int*)。< / p>

这样做有什么危险?这会是什么问题?我认为这可能与堆(缓冲区)溢出有关,但我不确定那会是什么。代码可能还有其他一些问题,如果是这样,我也想知道这些问题。

示例代码:

void typecastfunc(FILE *p, int *buf, unsigned int index) {
    unsigned int a;
    for (a = 0; a < index; a++) {
        if (fread(&buf[a], sizeof(unsigned int), 1, p) < 1) {
            break;
        }
    }
}

void caller(char *filen) {
    FILE *p = fopen(filen, "rb");
    if (!p) {
        return;
    }
    unsigned int index;
    fread(&index, sizeof(unsigned int), 1, p);
    unsigned int *buf = alloca(index * sizeof(unsigned int));
    if (!buf) {
        return;
    }
    typecastfunc(p, buf, index);
}

int main(int argc, char *argv[]) {
    caller(argv[1]);
}

正在问这个问题,因为通过随机模糊测试,我能够得到溢出的迹象,但我不知道类型不匹配会如何发生溢出。其他代码似乎无害,所以我认为它必须是因为类型不匹配。

2 个答案:

答案 0 :(得分:0)

您正在通过大小为int的块将二进制流中的数据读取到sizeof(unsigned int)数组中。

虽然使用正确的类型会更好,但是由于int的大小与unsigned int的大小相同,unsigned int的大小保证不会产生不良后果。 }。

int的表示可能会在将值用作for line2 in before_makeover: to_be_replaced = [] no_letters = "" flag = re.findall(".*[_!@#$%^&*]+.*", line2) if len(flag) == 0: n_log.write(line2) print line2 continue for letter in line2: if letter in string.letters + "\n" + " " + string.digits: if len(no_letters) > 0: if no_letters in rules.keys(): to_be_replaced.append(no_letters) no_letters = '' continue else: no_letters = '' else: continue else: no_letters += letter continue self.logging("to be replaced %s\n" % to_be_replaced) self.logging("Line %s" % line2) for to_be in to_be_replaced: line2 = string.replace(line2, to_be, rules[to_be], 1) self.logging("after replace %s" % line2) n_log.writelines(line2) print line2 并超出此类型的范围时产生意外行为,但对于大多数当前体系结构,它不会构成真正的问题。

答案 1 :(得分:0)

混合相同整数类型的有符号和无符号版本时总是存在危险。隐式转换可能会导致无意中更改签名。当您希望签名时,计算可以是无符号的,反之亦然。无符号类型可表示的值可能无法通过签名类型表示。等等。

至于指针相同类型(在本例中为int)的签名/未签名版本的特定情况,除此之外没有其他危险从上面提到的。这些指针转换被认为是安全的,作为C标准(1)中的特殊例外。

因此,int*unsigned int*之间的转换本身就是安全的。请注意,如果使用两种不同类型,则安全!例如,从int*short*的转换可能会导致各种微妙的错误。

(1)在C标准乱码中,​​C11 6.5 / 7(&#34;严格别名规则&#34;):

  

&#34;对象的存储值只能由左值访问   具有以下类型之一的表达式:&#34;
  ...
   - &#34;与对象的有效类型对应的有符号或无符号类型&#34;