read() - 如果在包含递归循环的循环中使用,则检查缓冲区边界

Per*_*dal 5 c io buffer-overflow flawfinder

我有这个代码并用 Flawinder 运行它,我在 read() 函数上得到这个输出:

如果在包含递归循环的循环中使用,请检查缓冲区边界

任何人都可以看到问题吗?

#include <stdlib.h>
void func(int fd)
{

char *buf;
size_t len;
read(fd, &len, sizeof(len));

if (len > 1024)
return;
buf = malloc(len+1); 
read(fd, buf, len); 
buf[len] = '\0';
}
Run Code Online (Sandbox Code Playgroud)

Ach*_*hal 4

您应该检查 的返回值read()以了解调用是read()成功还是失败,或者是否read()被信号中断,然后设置errno. 例如

ssize_t ret = read(fd, &len, sizeof len);
if( (ret == -1 || ret != sizeof len) {
   /* error handling @TODO */
}
Run Code Online (Sandbox Code Playgroud)

最重要的是这里

ret = read(fd, buf, len); /* read() may read less than len characters */ 
Run Code Online (Sandbox Code Playgroud)

read()返回读取的字节数,因此代替此

buf[len] = '\0';
Run Code Online (Sandbox Code Playgroud)

使用

buf[ret] = '\0'; /* correct way */
Run Code Online (Sandbox Code Playgroud)

示例代码

void func(int fd) { /* assume fd is a valid file descriptor */
        char *buf = NULL;
        size_t len;
        errno = 0; /* set this to 0 */
        ssize_t ret = read(fd, &len, sizeof len);
        if( (ret == -1 || ret != sizeof len) {
                /* error handling @TODO */
        }
        if (len > 1024) {
                return;
        }
        buf = malloc(len+1); 
        if(buf == NULL) {
                /* error handling @TODO */
        }
        ret = read(fd, buf, len);
        if(ret!=-1) {
                buf[ret] = '\0';
                /* do something with buf and free it once usage is done*/
        }       free(buf); /* free the buf */
        else { /* if read failed */
                free(buf); /* free the buf */
        }
}
Run Code Online (Sandbox Code Playgroud)