lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <1423858444-10158-4-git-send-email-vadim4j@gmail.com> Date: Fri, 13 Feb 2015 22:14:00 +0200 From: Vadim Kochan <vadim4j@...il.com> To: netdev@...r.kernel.org Cc: Vadim Kochan <vadim4j@...il.com> Subject: [PATCH iproute2 3/7] ss: Replace unixstat struct by new sockstat struct From: Vadim Kochan <vadim4j@...il.com> Signed-off-by: Vadim Kochan <vadim4j@...il.com> --- misc/ss.c | 141 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 75 insertions(+), 66 deletions(-) diff --git a/misc/ss.c b/misc/ss.c index f033892..54f2e21 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -660,6 +660,18 @@ 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 const char *sstate_name[] = { "UNKNOWN", [SS_ESTABLISHED] = "ESTAB", @@ -692,7 +704,8 @@ static const char *sstate_namel[] = { struct sockstat { - uint8_t type; + struct sockstat *next; + unsigned int type; uint16_t prot; inet_prefix local; inet_prefix remote; @@ -996,9 +1009,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, *pattern; - memcpy(&addr, a->data, sizeof(addr)); - memcpy(&pattern, p->data, sizeof(pattern)); + char *addr = sock_addr_get_str(a); + char *pattern = sock_addr_get_str(p); + if (pattern == NULL) return 1; if (addr == NULL) @@ -1014,8 +1027,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s) static int low, high=65535; if (s->local.family == AF_UNIX) { - char *p; - memcpy(&p, s->local.data, sizeof(p)); + char *p = sock_addr_get_str(&s->local); return p == NULL || (p[0] == '@' && strlen(p) == 6 && strspn(p+1, "0123456789abcdef") == 5); } @@ -1338,7 +1350,7 @@ void *parse_hostcond(char *addr) addr+=5; p = strdup(addr); a.addr.bitlen = 8*strlen(p); - memcpy(a.addr.data, &p, sizeof(p)); + sock_addr_set_str(&a.addr, &p); fam = AF_UNIX; goto out; } @@ -2415,31 +2427,21 @@ outerr: } while (0); } -struct unixstat -{ - struct unixstat *next; - int ino; - int peer; - char *peer_name; - int rq; - int wq; - int state; - int type; - char *name; -}; - int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT, SS_ESTABLISHED, SS_CLOSING }; -#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct unixstat)) +#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat)) -static void unix_list_free(struct unixstat *list) +static void unix_list_free(struct sockstat *list) { while (list) { - struct unixstat *s = list; + struct sockstat *s = list; + char *name = sock_addr_get_str(&s->local); + list = list->next; - if (s->name) - free(s->name); + + if (name) + free(name); free(s); } } @@ -2463,7 +2465,7 @@ static const char *unix_netid_name(int type) return netid; } -static bool unix_type_skip(struct unixstat *s, struct filter *f) +static bool unix_type_skip(struct sockstat *s, struct filter *f) { if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB))) return true; @@ -2474,44 +2476,49 @@ static bool unix_type_skip(struct unixstat *s, struct filter *f) return false; } -static void unix_stats_print(struct unixstat *list, struct filter *f) +static bool unix_use_proc(void) +{ + return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT"); +} + +static void unix_stats_print(struct sockstat *list, struct filter *f) { - struct unixstat *s; - char *peer; + struct sockstat *s; + char *local, *peer; + bool use_proc = unix_use_proc(); for (s = list; s; s = s->next) { - if (!(f->states & (1<<s->state))) + if (!(f->states & (1 << s->state))) continue; if (unix_type_skip(s, f)) continue; - peer = "*"; - if (s->peer_name) - peer = s->peer_name; + local = sock_addr_get_str(&s->local); + peer = "*"; + + if (s->rport && use_proc) { + struct sockstat *p; - if (s->peer && !s->peer_name) { - struct unixstat *p; for (p = list; p; p = p->next) { - if (s->peer == p->ino) + if (s->rport == p->lport) break; } + if (!p) { peer = "?"; } else { - peer = p->name ? : "*"; + peer = sock_addr_get_str(&p->local); + peer = peer ? : "*"; } } if (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(st.remote.data, 0, sizeof(peer)); + memset(s->remote.data, 0, sizeof(char *)); else - memcpy(st.remote.data, &peer, sizeof(peer)); - if (run_ssfilter(f->f, &st) == 0) + sock_addr_set_str(&s->remote, &peer); + + if (run_ssfilter(f->f, s) == 0) continue; } @@ -2522,8 +2529,8 @@ static void unix_stats_print(struct unixstat *list, struct filter *f) printf("%-*s ", state_width, sstate_name[s->state]); printf("%-6d %-6d ", s->rq, s->wq); printf("%*s %-*d %*s %-*d", - addr_width, s->name ? : "*", serv_width, s->ino, - addr_width, peer, serv_width, s->peer); + addr_width, local ? : "*", serv_width, + s->lport, addr_width, peer, serv_width, s->rport); char *buf = NULL; if (show_proc_ctx || show_sock_ctx) { @@ -2549,15 +2556,16 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh, struct filter *f = (struct filter *)arg; struct unix_diag_msg *r = NLMSG_DATA(nlh); struct rtattr *tb[UNIX_DIAG_MAX+1]; - char name[128]; - struct unixstat stat = { .name = "*" , .peer_name = "*" }; + char *name = NULL; + struct sockstat stat = {}; parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1), nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); stat.type = r->udiag_type; stat.state = r->udiag_state; - stat.ino = r->udiag_ino; + stat.ino = stat.lport = r->udiag_ino; + stat.local.family = stat.remote.family = AF_UNIX; if (unix_type_skip(&stat, f)) return 0; @@ -2570,14 +2578,15 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh, if (tb[UNIX_DIAG_NAME]) { int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]); + name = malloc(len + 1); memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len); name[len] = '\0'; if (name[0] == '\0') name[0] = '@'; - stat.name = &name[0]; + sock_addr_set_str(&stat.local, &name); } if (tb[UNIX_DIAG_PEER]) - stat.peer = rta_getattr_u32(tb[UNIX_DIAG_PEER]); + stat.rport = rta_getattr_u32(tb[UNIX_DIAG_PEER]); unix_stats_print(&stat, f); @@ -2594,6 +2603,9 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh, } if (show_mem || show_details) printf("\n"); + + if (name) + free(name); return 0; } @@ -2640,13 +2652,12 @@ static int unix_show(struct filter *f) char name[128]; int newformat = 0; int cnt; - struct unixstat *list = NULL; + struct sockstat *list = NULL; if (!filter_af_get(f, AF_UNIX)) return 0; - if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT") - && unix_show_netlink(f) == 0) + if (!unix_use_proc() && unix_show_netlink(f) == 0) return 0; if ((fp = net_unix_open()) == NULL) @@ -2658,31 +2669,30 @@ static int unix_show(struct filter *f) cnt = 0; while (fgets(buf, sizeof(buf)-1, fp)) { - struct unixstat *u, **insp; + struct sockstat *u, **insp; int flags; if (!(u = malloc(sizeof(*u)))) break; - u->name = NULL; - u->peer_name = NULL; if (sscanf(buf, "%x: %x %x %x %x %x %d %s", - &u->peer, &u->rq, &u->wq, &flags, &u->type, + &u->rport, &u->rq, &u->wq, &flags, &u->type, &u->state, &u->ino, name) < 8) name[0] = 0; - if (flags&(1<<16)) { + u->lport = u->ino; + u->local.family = u->remote.family = AF_UNIX; + + if (flags & (1 << 16)) { u->state = SS_LISTEN; } else { u->state = unix_state_map[u->state-1]; - if (u->type == SOCK_DGRAM && - u->state == SS_CLOSE && - u->peer) + if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport) u->state = SS_ESTABLISHED; } if (!newformat) { - u->peer = 0; + u->rport = 0; u->rq = 0; u->wq = 0; } @@ -2699,9 +2709,8 @@ static int unix_show(struct filter *f) *insp = u; if (name[0]) { - if ((u->name = malloc(strlen(name)+1)) == NULL) - break; - strcpy(u->name, name); + char *tmp = strdup(name); + sock_addr_set_str(&u->local, &tmp); } if (++cnt > MAX_UNIX_REMEMBER) { unix_stats_print(list, f); -- 2.2.2 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists