From 453eee90927d1c28951af40c3fd2c40365b07055 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 12 Aug 2015 08:35:54 -0700 Subject: [PATCH] Fix multiple programming errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a combination of 8 commits: commit 2f29d6bb5089271988a820d1f9596f9973ee2e4d Author: Stephen Hemminger Date: Wed Aug 12 08:35:54 2015 -0700 ipnetns: make net namespace cache variable size Save some space by using variable size for nsid cache elements. Signed-off-by: Stephen Hemminger commit e0dce0e5dc363b7e307984706c130f6ee769259b Author: Phil Sutter Date: Thu Aug 6 14:24:32 2015 +0200 misc/ss: avoid NULL pointer dereference This was working before, but only if realloc a) succeeded and b) did not move the buffer to a different location. ''**buf = **new_buf' then writes the value of *new_buf's first field into that of *buf. Signed-off-by: Phil Sutter commit 532ca40a52d4103816f2e50690a02e9dd6c1abe5 Author: Phil Sutter Date: Thu Aug 6 14:24:33 2015 +0200 misc/ss: simplify buffer realloc, fix checking realloc failure Signed-off-by: Phil Sutter commit b95d28c380c945ac760b128403dc82279cb9cc39 Author: Phil Sutter Date: Thu Aug 6 14:24:34 2015 +0200 misc/ss: add missing fclose() calls Signed-off-by: Phil Sutter commit 5950ba914e12b9c942e45e2dda6b1732a3efa058 Author: Phil Sutter Date: Thu Aug 6 14:24:35 2015 +0200 lib/namespace: don't leak fd in error case Signed-off-by: Phil Sutter commit a02371fb3831c8d3d9d53209f2389b250a1fb804 Author: Phil Sutter Date: Thu Aug 6 14:24:36 2015 +0200 misc/ss: fix memory leak in user_ent_hash_build() Signed-off-by: Phil Sutter commit 9e5ba07f491037f51472915477575d3e3fe0adcb Author: Phil Sutter Date: Tue Aug 18 18:11:08 2015 +0200 lib/namespace: fix fd leakage in non-error case My previous patch 5950ba9 ("lib/namespace: don't leak fd in error case") was a step in the wrong direction. Instead of closing the opened file descriptor in error case only, follow a better approach here and close the fd as soon as it is not used anymore. This way the inelegant goto statements can be dropped, and the fd leak in non-error case is fixed as well. Fixes: 5950ba9 ("lib/namespace: don't leak fd in error case") Signed-off-by: Phil Sutter commit b765eda924363caec99b760d8cff815ecf4a8de6 Author: Nicolas Dichtel Date: Wed Apr 22 10:27:06 2015 +0200 libnamespaces: fix warning about syscall() The warning was: In file included from namespace.c:14:0: ../include/namespace.h: In function ‘setns’: ../include/namespace.h:37:2: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration] Signed-off-by: Nicolas Dichtel --- include/namespace.h | 1 + ip/ipnetns.c | 6 +++--- lib/namespace.c | 2 ++ misc/ss.c | 17 +++++++++++------ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/namespace.h b/include/namespace.h index a2ac7dc..5add9d2 100644 --- a/include/namespace.h +++ b/include/namespace.h @@ -3,6 +3,7 @@ #include #include +#include #include #include diff --git a/ip/ipnetns.c b/ip/ipnetns.c index 019f954..00b6cc4 100644 --- a/ip/ipnetns.c +++ b/ip/ipnetns.c @@ -140,7 +140,7 @@ struct nsid_cache { struct hlist_node nsid_hash; struct hlist_node name_hash; int nsid; - char name[NAME_MAX]; + char name[0]; }; #define NSIDMAP_SIZE 128 @@ -165,7 +165,7 @@ static struct nsid_cache *netns_map_get_by_nsid(int nsid) return NULL; } -static int netns_map_add(int nsid, char *name) +static int netns_map_add(int nsid, const char *name) { struct nsid_cache *c; uint32_t h; @@ -173,7 +173,7 @@ static int netns_map_add(int nsid, char *name) if (netns_map_get_by_nsid(nsid) != NULL) return -EEXIST; - c = malloc(sizeof(*c)); + c = malloc(sizeof(*c) + strlen(name)); if (c == NULL) { perror("malloc"); return -ENOMEM; diff --git a/lib/namespace.c b/lib/namespace.c index c03a103..0549916 100644 --- a/lib/namespace.c +++ b/lib/namespace.c @@ -57,8 +57,10 @@ int netns_switch(char *name) if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n", name, strerror(errno)); + close(netns); return -1; } + close(netns); if (unshare(CLONE_NEWNS) < 0) { fprintf(stderr, "unshare failed: %s\n", strerror(errno)); diff --git a/misc/ss.c b/misc/ss.c index 951e1eb..5d0cc36 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -474,8 +474,10 @@ static void user_ent_hash_build(void) sprintf(name + nameoff, "%d/fd/", pid); pos = strlen(name); - if ((dir1 = opendir(name)) == NULL) + if ((dir1 = opendir(name)) == NULL) { + free(pid_context); continue; + } process[0] = '\0'; p = process; @@ -541,7 +543,7 @@ static int find_entry(unsigned ino, char **buf, int type) struct user_ent *p; int cnt = 0; char *ptr; - char **new_buf = buf; + char *new_buf; int len, new_buf_len; int buf_used = 0; int buf_len = 0; @@ -583,12 +585,12 @@ static int find_entry(unsigned ino, char **buf, int type) if (len < 0 || len >= buf_len - buf_used) { new_buf_len = buf_len + ENTRY_BUF_SIZE; - *new_buf = realloc(*buf, new_buf_len); + new_buf = realloc(*buf, new_buf_len); if (!new_buf) { fprintf(stderr, "ss: failed to malloc buffer\n"); abort(); } - **buf = **new_buf; + *buf = new_buf; buf_len = new_buf_len; continue; } else { @@ -2928,6 +2930,7 @@ static int packet_show_line(char *buf, const struct filter *f, int fam) static int packet_show(struct filter *f) { FILE *fp; + int rc = 0; if (!filter_af_get(f, AF_PACKET) || !(f->states & (1 << SS_CLOSE))) return 0; @@ -2939,9 +2942,10 @@ static int packet_show(struct filter *f) if ((fp = net_packet_open()) == NULL) return -1; if (generic_record_read(fp, packet_show_line, f, AF_PACKET)) - return -1; + rc = -1; - return 0; + fclose(fp); + return rc; } static int netlink_show_one(struct filter *f, @@ -3118,6 +3122,7 @@ static int netlink_show(struct filter *f) netlink_show_one(f, prot, pid, groups, 0, 0, 0, rq, wq, sk, cb); } + fclose(fp); return 0; } -- 1.8.3.1