C 这容易受到堆栈溢出的攻击吗?

C 这容易受到堆栈溢出的攻击吗?,c,stack,overflow,C,Stack,Overflow,从我所读到的内容来看,当您想要限制输入的大小时,应该使用fgets。所以这段代码不应该有漏洞,对吗 人们这样称呼它: void gctinp (char *inp, int siz) { puts ("Input value: "); fgets (inp, siz, stdin); printf ("buffer3 getinp read %s", inp); } 感谢您的时间。fgets读取的字节数最多比指定的字节数少一个,并且将确保读取字符串以null结尾。因此,只要传递正

从我所读到的内容来看,当您想要限制输入的大小时,应该使用fgets。所以这段代码不应该有漏洞,对吗

人们这样称呼它:

void gctinp (char *inp, int siz)
{

  puts ("Input value: ");
  fgets (inp, siz, stdin);
  printf ("buffer3 getinp read %s", inp);
}

感谢您的时间。

fgets读取的字节数最多比指定的字节数少一个,并且将确保读取字符串以null结尾。因此,只要传递正确的大小,就可以了,尽管字符串可能不会以换行符结尾。

fgets读取的字节数最多比指定的字节数少一个,并确保读取的字符串以null结尾。因此,只要传递正确的大小,就可以了,尽管字符串可能不会以换行符结尾。

不,它不容易出现堆栈溢出

您是否碰巧混淆了堆栈溢出和缓冲区溢出


不,它不容易出现堆栈溢出

您是否碰巧混淆了堆栈溢出和缓冲区溢出


如果输入的字符超过安全存储的字符数,则不会出现缓冲区溢出问题,因为fgets限制输入。当然,它还添加了一个空终止符,假设缓冲区大小大于0

但是,当您下次尝试读取某些内容时,您会遇到信息留在输入缓冲区中的问题-这是用户会觉得非常烦人的事情,再次输入类似hello的内容,并将其作为两个单独的输入,例如hello ag和ain。fgets并没有给出它在行尾之前停止检索输入的指示,所以,就您的代码所知,一切都很好

您需要注意的主要问题是输入上的重新缓冲区溢出至少是scanf,它带有一个无界的%s格式字符串和get,它没有限制大小的参数,这两个参数都不在您的代码中

如果您正在寻找具有大小限制、提示和缓冲区清除功能的更健壮的输入解决方案,请查看此代码,它提供了所有这些功能:

int main (int argc, char *argv[])

{

 char buf[16];

 getinp (buf, sizeof (buf));

 display (buf);

 printf ("buffer3 done\n");

}
进行一些基本测试:

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        // Extra NL since my system doesn't output that on EOF.
        printf ("\nNo input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long [%s]\n", buff);
        rc = getLine ("Hit ENTER to check remains> ", buff, sizeof(buff));
        printf ("Excess [%s]\n", buff);
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

如果输入的字符超过安全存储的字符数,则不会出现缓冲区溢出问题,因为fgets限制输入。当然,它还添加了一个空终止符,假设缓冲区大小大于0

但是,当您下次尝试读取某些内容时,您会遇到信息留在输入缓冲区中的问题-这是用户会觉得非常烦人的事情,再次输入类似hello的内容,并将其作为两个单独的输入,例如hello ag和ain。fgets并没有给出它在行尾之前停止检索输入的指示,所以,就您的代码所知,一切都很好

您需要注意的主要问题是输入上的重新缓冲区溢出至少是scanf,它带有一个无界的%s格式字符串和get,它没有限制大小的参数,这两个参数都不在您的代码中

如果您正在寻找具有大小限制、提示和缓冲区清除功能的更健壮的输入解决方案,请查看此代码,它提供了所有这些功能:

int main (int argc, char *argv[])

{

 char buf[16];

 getinp (buf, sizeof (buf));

 display (buf);

 printf ("buffer3 done\n");

}
进行一些基本测试:

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        // Extra NL since my system doesn't output that on EOF.
        printf ("\nNo input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long [%s]\n", buff);
        rc = getLine ("Hit ENTER to check remains> ", buff, sizeof(buff));
        printf ("Excess [%s]\n", buff);
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

我认为您混淆了堆栈溢出和缓冲区溢出。堆栈溢出问题最常见的原因是递归函数多次调用自身而不返回。是的,aschepler所说的是正确的,但另外,堆栈上可能发生缓冲区溢出。如果您使用了gets,它将容易受到堆栈上缓冲区溢出的攻击,而不是堆栈溢出。我认为您混淆了堆栈溢出和缓冲区溢出。堆栈溢出问题最常见的原因是递归函数多次调用自身而不返回。是的,aschepler所说的是正确的,但另外,堆栈上可能发生缓冲区溢出。如果您使用了gets,它将容易受到堆栈缓冲区溢出的攻击,而不是堆栈溢出。。不可以。只要提供的大小至少为1,fgets always nul将终止结果。抱歉,应该使该大小必须足够大,以容纳终止符,否则它在第一段中存储不清楚-已修复。错误。。否。只要提供的大小至少为1,fgets总是nul终止结果。抱歉,应该使该大小必须足够大,以容纳终止符,否则它在第一段中存储不清楚-已修复。