From d851f5695dfd520b16f73574af037d24fb9e077d Mon Sep 17 00:00:00 2001 From: JingPiao Chen Date: Thu, 22 Jun 2017 00:24:23 +0800 Subject: [PATCH] netlink: introduce a basic netlink attributes parser * linux/unix_diag.h (UNIX_DIAG_*): New enum. * nlattr.c: New file. * nlattr.h: Likewise. * Makefile.am (strace_SOURCES): Add them. * netlink_sock_diag.c: Include "nlattr.h" and "xlat/unix_diag_attrs.h". (decode_unix_diag_msg): Use decode_nlattr. * xlat/unix_diag_attrs.in: New file. Co-authored-by: Fabien Siron --- Makefile.am | 2 + linux/unix_diag.h | 11 +++- netlink_sock_diag.c | 13 +++- nlattr.c | 130 ++++++++++++++++++++++++++++++++++++++++ nlattr.h | 37 ++++++++++++ xlat/unix_diag_attrs.in | 8 +++ 6 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 nlattr.c create mode 100644 nlattr.h create mode 100644 xlat/unix_diag_attrs.in diff --git a/Makefile.am b/Makefile.am index 0d759700..76be3ca3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -175,6 +175,8 @@ strace_SOURCES = \ netlink.c \ netlink.h \ netlink_sock_diag.c \ + nlattr.c \ + nlattr.h \ nsfs.c \ nsfs.h \ nsig.h \ diff --git a/linux/unix_diag.h b/linux/unix_diag.h index a6b62bab..3c9d99f8 100644 --- a/linux/unix_diag.h +++ b/linux/unix_diag.h @@ -27,7 +27,14 @@ struct unix_diag_msg { uint32_t udiag_cookie[2]; }; -#define UNIX_DIAG_NAME 0 -#define UNIX_DIAG_PEER 2 +enum { + UNIX_DIAG_NAME, + UNIX_DIAG_VFS, + UNIX_DIAG_PEER, + UNIX_DIAG_ICONS, + UNIX_DIAG_RQLEN, + UNIX_DIAG_MEMINFO, + UNIX_DIAG_SHUTDOWN, +}; #endif /* !STRACE_LINUX_UNIX_DIAG_H */ diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c index bdefe8b6..d854808e 100644 --- a/netlink_sock_diag.c +++ b/netlink_sock_diag.c @@ -29,6 +29,7 @@ #include "defs.h" #include "netlink.h" +#include "nlattr.h" #include #include @@ -54,6 +55,7 @@ # include "xlat/smc_states.h" #endif +#include "xlat/unix_diag_attrs.h" #include "xlat/unix_diag_show.h" static void @@ -112,7 +114,8 @@ decode_unix_diag_msg(struct tcb *const tcp, const kernel_ulong_t len) { struct unix_diag_msg msg = { .udiag_family = family }; - const size_t offset = sizeof(msg.udiag_family); + size_t offset = sizeof(msg.udiag_family); + bool decode_nla = false; tprints("{udiag_family="); printxval(addrfams, msg.udiag_family, "AF_???"); @@ -130,10 +133,18 @@ decode_unix_diag_msg(struct tcb *const tcp, ", udiag_cookie=[%" PRIu32 ", %" PRIu32 "]", msg.udiag_ino, msg.udiag_cookie[0], msg.udiag_cookie[1]); + decode_nla = true; } } else tprints("..."); tprints("}"); + + offset = NLMSG_ALIGN(sizeof(msg)); + if (decode_nla && len > offset) { + tprints(", "); + decode_nlattr(tcp, addr + offset, len - offset, + unix_diag_attrs, "UNIX_DIAG_???"); + } } static void diff --git a/nlattr.c b/nlattr.c new file mode 100644 index 00000000..8c516293 --- /dev/null +++ b/nlattr.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016 Fabien Siron + * Copyright (c) 2017 JingPiao Chen + * Copyright (c) 2016-2017 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "defs.h" +#include "netlink.h" + +static bool +fetch_nlattr(struct tcb *const tcp, struct nlattr *const nlattr, + const kernel_ulong_t addr, const kernel_ulong_t len) +{ + if (len < sizeof(struct nlattr)) { + printstrn(tcp, addr, len); + return false; + } + + if (umove_or_printaddr(tcp, addr, nlattr)) + return false; + + return true; +} + +static void +print_nlattr(const struct nlattr *const nla, + const struct xlat *const table, + const char *const dflt) +{ + tprintf("{nla_len=%u, nla_type=", nla->nla_len); + if (nla->nla_type & NLA_F_NESTED) + tprints("NLA_F_NESTED|"); + if (nla->nla_type & NLA_F_NET_BYTEORDER) + tprints("NLA_F_NET_BYTEORDER|"); + printxval(table, nla->nla_type & NLA_TYPE_MASK, dflt); + tprints("}"); +} + +static void +decode_nlattr_with_data(struct tcb *tcp, + const struct nlattr *const nla, + kernel_ulong_t addr, + kernel_ulong_t len, + const struct xlat *const table, + const char *const dflt) +{ + const unsigned int nla_len = nla->nla_len > len ? len : nla->nla_len; + + if (nla_len > NLA_HDRLEN) + tprints("{"); + + print_nlattr(nla, table, dflt); + + if (nla_len > NLA_HDRLEN) { + tprints(", "); + printstrn(tcp, addr + NLA_HDRLEN, nla_len - NLA_HDRLEN); + tprints("}"); + } +} + +void +decode_nlattr(struct tcb *const tcp, + kernel_ulong_t addr, + kernel_ulong_t len, + const struct xlat *const table, + const char *const dflt) +{ + struct nlattr nla; + bool print_array = false; + unsigned int elt; + + for (elt = 0; fetch_nlattr(tcp, &nla, addr, len); elt++) { + if (abbrev(tcp) && elt == max_strlen) { + tprints("..."); + break; + } + + const unsigned long nla_len = NLA_ALIGN(nla.nla_len); + kernel_ulong_t next_addr = 0; + kernel_ulong_t next_len = 0; + + if (nla.nla_len >= NLA_HDRLEN) { + next_len = (len >= nla_len) ? len - nla_len : 0; + + if (next_len && addr + nla_len > addr) + next_addr = addr + nla_len; + } + + if (!print_array && next_addr) { + tprints("["); + print_array = true; + } + + decode_nlattr_with_data(tcp, &nla, addr, len, table, dflt); + + if (!next_addr) + break; + + tprints(", "); + addr = next_addr; + len = next_len; + } + + if (print_array) { + tprints("]"); + } +} diff --git a/nlattr.h b/nlattr.h new file mode 100644 index 00000000..ade2271b --- /dev/null +++ b/nlattr.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Fabien Siron + * Copyright (c) 2017 JingPiao Chen + * Copyright (c) 2016-2017 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef STRACE_NLATTR_H +#define STRACE_NLATTR_H + +extern void +decode_nlattr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len, + const struct xlat *, const char *); + +#endif /* !STRACE_NLATTR_H */ diff --git a/xlat/unix_diag_attrs.in b/xlat/unix_diag_attrs.in new file mode 100644 index 00000000..4c3d9b2e --- /dev/null +++ b/xlat/unix_diag_attrs.in @@ -0,0 +1,8 @@ +#unconditional +UNIX_DIAG_NAME +UNIX_DIAG_VFS +UNIX_DIAG_PEER +UNIX_DIAG_ICONS +UNIX_DIAG_RQLEN +UNIX_DIAG_MEMINFO +UNIX_DIAG_SHUTDOWN -- 2.40.0