diff options
author | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2019-10-29 12:13:11 +0100 |
---|---|---|
committer | Stephen Hemminger <stephen@networkplumber.org> | 2019-11-01 09:05:41 -0700 |
commit | eca51239480dfc154a07c496774bf7e7f4fb3d30 (patch) | |
tree | 5c9661ff4dc422ec17654bfc211008b75cb83e7e /misc/ss.c | |
parent | cb83101626316aed1cb68931ffc4d27e1b56c503 (diff) | |
download | iproute2-eca51239480dfc154a07c496774bf7e7f4fb3d30.tar.gz |
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>
Diffstat (limited to 'misc/ss.c')
-rw-r--r-- | misc/ss.c | 26 |
1 files changed, 13 insertions, 13 deletions
@@ -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; } |