Re: [PATCH iproute2 v2] ss: Fix crash when dump stats from /proc with '-p'

2015-07-21 Thread Stephen Hemminger
On Tue, 21 Jul 2015 16:18:36 +0300
Vadim Kochan  wrote:

> From: Vadim Kochan 
> 
> It really partially reverts:
> 
> ec4d0d8a9def35 (ss: Replace unixstat struct by new sockstat struct)
> 
> but adds few fields (name & peer_name) from removed unixstat to sockstat 
> struct to easy
> return original code.
> 
> Fixes: ec4d0d8a9def35 (ss: Replace unixstat struct by new sockstat struct)
> Reported-by: Marc Dietrich 
> Signed-off-by: Vadim Kochan 

I applied this one after resolving merge conflicts.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH iproute2 v2] ss: Fix crash when dump stats from /proc with '-p'

2015-07-21 Thread Vadim Kochan
From: Vadim Kochan 

It really partially reverts:

ec4d0d8a9def35 (ss: Replace unixstat struct by new sockstat struct)

but adds few fields (name & peer_name) from removed unixstat to sockstat struct 
to easy
return original code.

Fixes: ec4d0d8a9def35 (ss: Replace unixstat struct by new sockstat struct)
Reported-by: Marc Dietrich 
Signed-off-by: Vadim Kochan 
---
v2:
Get rid of check for NULL before free(...) func.

 misc/ss.c | 71 ---
 1 file changed, 31 insertions(+), 40 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 03f92fa..320 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -676,18 +676,6 @@ static int get_slabstat(struct slabstat *s)
return 0;
 }
 
-static inline void sock_addr_set_str(inet_prefix *prefix, char **ptr)
-{
-memcpy(prefix->data, ptr, sizeof(char *));
-}
-
-static inline char *sock_addr_get_str(const inet_prefix *prefix)
-{
-char *tmp ;
-memcpy(&tmp, prefix->data, sizeof(char *));
-return tmp;
-}
-
 static unsigned long long cookie_sk_get(const uint32_t *cookie)
 {
return (((unsigned long long)cookie[1] << 31) << 1) | cookie[0];
@@ -739,6 +727,8 @@ struct sockstat
int refcnt;
unsigned intiface;
unsigned long long  sk;
+   char *name;
+   char *peer_name;
 };
 
 struct dctcpstat
@@ -1063,9 +1053,9 @@ static int inet2_addr_match(const inet_prefix *a, const 
inet_prefix *p,
 
 static int unix_match(const inet_prefix *a, const inet_prefix *p)
 {
-   char *addr = sock_addr_get_str(a);
-   char *pattern = sock_addr_get_str(p);
-
+   char *addr, *pattern;
+   memcpy(&addr, a->data, sizeof(addr));
+   memcpy(&pattern, p->data, sizeof(pattern));
if (pattern == NULL)
return 1;
if (addr == NULL)
@@ -1081,7 +1071,8 @@ static int run_ssfilter(struct ssfilter *f, struct 
sockstat *s)
 static int low, high=65535;
 
if (s->local.family == AF_UNIX) {
-   char *p = sock_addr_get_str(&s->local);
+   char *p;
+   memcpy(&p, s->local.data, sizeof(p));
return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
 strspn(p+1, "0123456789abcdef") == 
5);
}
@@ -1401,7 +1392,7 @@ void *parse_hostcond(char *addr, bool is_port)
addr+=5;
p = strdup(addr);
a.addr.bitlen = 8*strlen(p);
-   sock_addr_set_str(&a.addr, &p);
+   memcpy(a.addr.data, &p, sizeof(p));
fam = AF_UNIX;
goto out;
}
@@ -2508,12 +2499,9 @@ static void unix_list_free(struct sockstat *list)
 {
while (list) {
struct sockstat *s = list;
-   char *name = sock_addr_get_str(&s->local);
-
list = list->next;
 
-   if (name)
-   free(name);
+   free(s->name);
free(s);
}
 }
@@ -2556,7 +2544,7 @@ static bool unix_use_proc(void)
 static void unix_stats_print(struct sockstat *list, struct filter *f)
 {
struct sockstat *s;
-   char *local, *peer;
+   char *peer;
char *ctx_buf = NULL;
bool use_proc = unix_use_proc();
char port_name[30] = {};
@@ -2567,8 +2555,9 @@ static void unix_stats_print(struct sockstat *list, 
struct filter *f)
if (unix_type_skip(s, f))
continue;
 
-   local = sock_addr_get_str(&s->local);
-   peer  = "*";
+   peer = "*";
+   if (s->peer_name)
+   peer = s->peer_name;
 
if (s->rport && use_proc) {
struct sockstat *p;
@@ -2581,24 +2570,26 @@ static void unix_stats_print(struct sockstat *list, 
struct filter *f)
if (!p) {
peer = "?";
} else {
-   peer = sock_addr_get_str(&p->local);
-   peer = peer ? : "*";
+   peer = p->name ? : "*";
}
}
 
if (use_proc && f->f) {
+   struct sockstat st;
+   st.local.family = AF_UNIX;
+   st.remote.family = AF_UNIX;
+   memcpy(st.local.data, &s->name, sizeof(s->name));
if (strcmp(peer, "*") == 0)
-   memset(s->remote.data, 0, sizeof(char *));
+   memset(st.remote.data, 0, sizeof(peer));
else
-   sock_addr_set_str(&s->remote, &peer);
-
-   if (run_ssfilter(f->f, s) == 0)
+   memcpy(st.remote.data, &peer, sizeof(peer));
+   i