C read()-如果在包含递归循环的循环中使用,请检查缓冲区边界
我有这段代码,并使用Failinder运行它,在read()函数中得到以下输出: 如果在包含递归循环的循环中使用,请检查缓冲区边界 有人看到问题了吗C read()-如果在包含递归循环的循环中使用,请检查缓冲区边界,c,io,buffer-overflow,flawfinder,C,Io,Buffer Overflow,Flawfinder,我有这段代码,并使用Failinder运行它,在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); b
#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';
}
#包括
无效函数(int-fd)
{
char*buf;
尺寸透镜;
读取(fd和len,sizeof(len));
如果(len>1024)
返回;
buf=malloc(len+1);
读取(fd、buf、len);
buf[len]='\0';
}
您应该检查read()
的返回值,以了解调用read()
是成功还是失败,或者read()
是否被信号中断,然后设置errno
。例如
ssize_t ret = read(fd, &len, sizeof len);
if( (ret == -1 || ret != sizeof len) {
/* error handling @TODO */
}
最重要的是在这里
ret = read(fd, buf, len); /* read() may read less than len characters */
read()
返回读取的字节数,因此
buf[len] = '\0';
使用
示例代码
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 */
}
}
我更关心的是,这如何完全忽略从
read
两次(以及malloc
)返回的潜在错误。第一个特别重要,因为它可能使len
不确定。不要违反;检查IO结果是否有错误。read()
返回的结果可能比要求的要少。至少在第一种情况下是致命的。因此,只测试-1
是不够的。而且read()
返回ssize\t
notint
,如果不是在Windows上。如果(ret!=sizeof len){就可以三思了。在ret>0和&ret
的任何情况下,人们都可以循环read()
读取,直到读取len的大小
字节。在ret==-1&&(errno==EAGAIN | | errno==EINTR)的情况下也可以这样做
。我还观察到,即使是ret==-1&&errno==EIO
也值得重试的罕见情况。这通常发生在从基于网络的文件系统读取时。@PerKristianGravdal这里ssize\t ret=read(fd,&len,sizeof(len))
从文件中读取一个整数值,并存储在len
中。如果读取的len
值大于1024
,则不要继续,从函数返回。
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 */
}
}