]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ss: Don't leak fd in tcp_show_netlink_file()
authorPhil Sutter <phil@nwl.cc>
Thu, 17 Aug 2017 17:09:30 +0000 (19:09 +0200)
committerStephen Hemminger <stephen@networkplumber.org>
Fri, 18 Aug 2017 16:16:59 +0000 (09:16 -0700)
Signed-off-by: Phil Sutter <phil@nwl.cc>
misc/ss.c

index f0d1c22f75cffce3411b0d7da927d3d72cb8fdf0..b0bc435606be1972fc711ad367885b6b0ce51bba 100644 (file)
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2688,41 +2688,44 @@ static int tcp_show_netlink_file(struct filter *f)
 {
        FILE    *fp;
        char    buf[16384];
+       int     err = -1;
 
        if ((fp = fopen(getenv("TCPDIAG_FILE"), "r")) == NULL) {
                perror("fopen($TCPDIAG_FILE)");
-               return -1;
+               return err;
        }
 
        while (1) {
-               int status, err;
+               int status, err2;
                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");
-                       return -1;
+                       break;
                }
                if (status != sizeof(*h)) {
                        perror("Unexpected EOF reading $TCPDIAG_FILE");
-                       return -1;
+                       break;
                }
 
                status = fread(h+1, 1, NLMSG_ALIGN(h->nlmsg_len-sizeof(*h)), fp);
 
                if (status < 0) {
                        perror("Reading $TCPDIAG_FILE");
-                       return -1;
+                       break;
                }
                if (status + sizeof(*h) < h->nlmsg_len) {
                        perror("Unexpected EOF reading $TCPDIAG_FILE");
-                       return -1;
+                       break;
                }
 
                /* The only legal exit point */
-               if (h->nlmsg_type == NLMSG_DONE)
-                       return 0;
+               if (h->nlmsg_type == NLMSG_DONE) {
+                       err = 0;
+                       break;
+               }
 
                if (h->nlmsg_type == NLMSG_ERROR) {
                        struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
@@ -2733,7 +2736,7 @@ static int tcp_show_netlink_file(struct filter *f)
                                errno = -err->error;
                                perror("TCPDIAG answered");
                        }
-                       return -1;
+                       break;
                }
 
                parse_diag_msg(h, &s);
@@ -2742,10 +2745,15 @@ static int tcp_show_netlink_file(struct filter *f)
                if (f && f->f && run_ssfilter(f->f, &s) == 0)
                        continue;
 
-               err = inet_show_sock(h, &s);
-               if (err < 0)
-                       return err;
+               err2 = inet_show_sock(h, &s);
+               if (err2 < 0) {
+                       err = err2;
+                       break;
+               }
        }
+
+       fclose(fp);
+       return err;
 }
 
 static int tcp_show(struct filter *f, int socktype)