libnetlink.c, ss.c: properly handle fread() errors

fread(3) returns size_t data type which is unsigned, thus check
`if (fread(...) < 0)' is always false. To check if fread(3) has
failed, user should check error indicator with ferror(3).

This commit also changes read logic a little bit by being less
forgiving for errors. Previous logic was checking if fread(3)
read *at least* required ammount of data, now code checks if
fread(3) read *exactly* expected ammount of data. This makes
sense because code parses very specific binary file, and reading
even 1 less/more byte than expected, will later corrupt data anyway.

Signed-off-by: Michał Łyszczek <michal.lyszczek@bofc.pl>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
Michał Łyszczek 2019-10-29 12:13:11 +01:00 committed by Stephen Hemminger
parent cb83101626
commit eca5123948
2 changed files with 26 additions and 26 deletions

View File

@ -1174,7 +1174,7 @@ int rtnl_listen(struct rtnl_handle *rtnl,
int rtnl_from_file(FILE *rtnl, rtnl_listen_filter_t handler,
void *jarg)
{
int status;
size_t status;
char buf[16384];
struct nlmsghdr *h = (struct nlmsghdr *)buf;
@ -1184,14 +1184,15 @@ int rtnl_from_file(FILE *rtnl, rtnl_listen_filter_t handler,
status = fread(&buf, 1, sizeof(*h), rtnl);
if (status < 0) {
if (errno == EINTR)
continue;
perror("rtnl_from_file: fread");
if (status == 0 && feof(rtnl))
return 0;
if (status != sizeof(*h)) {
if (ferror(rtnl))
perror("rtnl_from_file: fread");
if (feof(rtnl))
fprintf(stderr, "rtnl-from_file: truncated message\n");
return -1;
}
if (status == 0)
return 0;
len = h->nlmsg_len;
l = len - sizeof(*h);
@ -1204,12 +1205,11 @@ int rtnl_from_file(FILE *rtnl, rtnl_listen_filter_t handler,
status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl);
if (status < 0) {
perror("rtnl_from_file: fread");
return -1;
}
if (status < l) {
fprintf(stderr, "rtnl-from_file: truncated message\n");
if (status != NLMSG_ALIGN(l)) {
if (ferror(rtnl))
perror("rtnl_from_file: fread");
if (feof(rtnl))
fprintf(stderr, "rtnl-from_file: truncated message\n");
return -1;
}

View File

@ -3329,28 +3329,28 @@ static int tcp_show_netlink_file(struct filter *f)
}
while (1) {
int status, err2;
int err2;
size_t status, nitems;
struct nlmsghdr *h = (struct nlmsghdr *)buf;
struct sockstat s = {};
status = fread(buf, 1, sizeof(*h), fp);
if (status < 0) {
perror("Reading header from $TCPDIAG_FILE");
break;
}
if (status != sizeof(*h)) {
perror("Unexpected EOF reading $TCPDIAG_FILE");
if (ferror(fp))
perror("Reading header from $TCPDIAG_FILE");
if (feof(fp))
fprintf(stderr, "Unexpected EOF reading $TCPDIAG_FILE");
break;
}
status = fread(h+1, 1, NLMSG_ALIGN(h->nlmsg_len-sizeof(*h)), fp);
nitems = NLMSG_ALIGN(h->nlmsg_len - sizeof(*h));
status = fread(h+1, 1, nitems, fp);
if (status < 0) {
perror("Reading $TCPDIAG_FILE");
break;
}
if (status + sizeof(*h) < h->nlmsg_len) {
perror("Unexpected EOF reading $TCPDIAG_FILE");
if (status != nitems) {
if (ferror(fp))
perror("Reading $TCPDIAG_FILE");
if (feof(fp))
fprintf(stderr, "Unexpected EOF reading $TCPDIAG_FILE");
break;
}