这会导致溢出吗?

时间:2011-02-02 16:00:28

标签: c string overflow

我有以下代码,我认为它会导致readlink()函数溢出。

pid_t get_pid_from_proc_self()
{
    char buffer[4];
    pid_t pid;

    readlink("/proc/self", buffer, sizeof(buffer));

    sscanf(buffer, "%d",(int *)&pid);

    return pid;
}

由于在Linux中PID为4字节,readlink()将32位从“/ proc / self”复制到target[]。然后,根据我的说法,'\0'应该使用一个额外的字节,这使得它成为5个字节。

此外,readlink()是否会在结尾处自动插入'\0'字符串,还是必须将其专门分配给最后一个字节?

5 个答案:

答案 0 :(得分:3)

不,它不会导致溢出。它将读入最多sizeof(buffer)个字节,然后停止。它不会终止你的字符串,所以你必须这样做。在确保最后一个字节为buffer之前阅读\0将导致未定义的行为(这是您的sscanf()调用正在进行的操作)。

答案 1 :(得分:2)

根据此处显示的示例:

http://pubs.opengroup.org/onlinepubs/009695399/functions/readlink.html

if ((len = readlink("/modules/pass1", buf, sizeof(buf)-1)) != -1)
    buf[len] = '\0';

编辑:

我想知道:

  

由于在Linux中PID是4字节,readlink()从“/ proc / self”复制32位......

你不回来PID的字符串版本,而不是一个实际的4字节整数?你的价值难以达到 10位? 5位数? (关于最大过程值的评论远远小于最大4字节的内部值 - 感谢@Karl)

答案 2 :(得分:1)

readlink不会溢出,因为它不会将'\ 0'放在最后。但是sscanf会。你应该这样做:

你应该这样做:

char buf[5];
ssizet_t len;
...
if ((len = readlink("/proc/self", buf, sizeof(buf)-1)) != -1)
    buf[len] = '\0';

答案 3 :(得分:1)

readlink()不会导致溢出,但它不会追加尾随\0sscanf()可能会造成严重损害(缓冲区溢出)。来自readlink()联机帮助页。

  

readlink()放置的内容   缓冲区中的符号链接路径,   其大小为bufsiz。 readlink()的确如此   不向buf附加空字节。它会   截断内容(长度为   bufsiz字符),以防缓冲区   太小了,无法容纳所有人   内容。

此外,readlink()读取PID的文本,该文本可能大于"9999"。仅使用四个字节将PID值存储在文本中是不够的。

答案 4 :(得分:1)

你的假设是完全偏离基础的。 sizeof(pid_t)为4并不意味着需要4个字节来存储表示数字的十进制字符串。典型的16位pid(如12345)显然需要6个字节作为字符串存储,如果Linux已配置为允许超过32768个进程,则可能会更长。

foo_t整数类型保存为十进制字符串的缓冲区的正确大小为3*sizeof(foo_t)+2。如果你愿意的话,你可以在边界上做得稍微好些,但我不介意在源代码中为了简单(和明显的正确性)而浪费几个字节。

(注意我假设8位字节,POSIX需要,因为pids是POSIX概念。如果你想支持更大的字节,你需要使用CHAR_BIT来调整边界。)< / p>