[PATCH v2 01/16] netlink: introduce a dummy netlink attributes parser

JingPiao Chen chenjingpiao at gmail.com
Sun Jun 18 05:18:28 UTC 2017


* defs.h (decode_nlattr): New prototype.
* linux/unix_diag.h (UNIX_DIAG_*): New enum.
* nlattr.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* netlink_sock_diag.c: Include "xlat/unix_diag_attrs.h".
(decode_unix_diag_msg): Use decode_nlattr.
* xlat/unix_diag_attrs.in: New file.

co-authored-by: Fabien Siron <fabien.siron at epita.fr>
---
 Makefile.am             |   1 +
 defs.h                  |   3 ++
 linux/unix_diag.h       |  11 +++-
 netlink_sock_diag.c     |   8 +++
 nlattr.c                | 131 ++++++++++++++++++++++++++++++++++++++++++++++++
 xlat/unix_diag_attrs.in |   8 +++
 6 files changed, 160 insertions(+), 2 deletions(-)
 create mode 100644 nlattr.c
 create mode 100644 xlat/unix_diag_attrs.in

diff --git a/Makefile.am b/Makefile.am
index e22d480..132b5e1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -173,6 +173,7 @@ strace_SOURCES =	\
 	net.c		\
 	netlink.c       \
 	netlink_sock_diag.c \
+	nlattr.c	\
 	nsfs.c          \
 	nsfs.h          \
 	nsig.h		\
diff --git a/defs.h b/defs.h
index 487e51b..19653f3 100644
--- a/defs.h
+++ b/defs.h
@@ -632,6 +632,9 @@ tprint_iov_upto(struct tcb *, kernel_ulong_t len, kernel_ulong_t addr,
 
 extern void
 decode_netlink(struct tcb *, int fd, kernel_ulong_t addr, kernel_ulong_t len);
+extern void
+decode_nlattr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len,
+	      const struct xlat *, const char *);
 
 extern void tprint_open_modes(unsigned int);
 extern const char *sprint_open_modes(unsigned int);
diff --git a/linux/unix_diag.h b/linux/unix_diag.h
index a6b62ba..3c9d99f 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 8dbfd07..e515810 100644
--- a/netlink_sock_diag.c
+++ b/netlink_sock_diag.c
@@ -55,6 +55,7 @@
 # include "xlat/smc_states.h"
 #endif
 
+#include "xlat/unix_diag_attrs.h"
 #include "xlat/unix_diag_show.h"
 
 static void
@@ -135,6 +136,13 @@ decode_unix_diag_msg(struct tcb *const tcp,
 	} else
 		tprints("...");
 	tprints("}");
+
+	if (len > NLA_ALIGN(sizeof(msg))) {
+		tprints(", ");
+		decode_nlattr(tcp, addr + NLA_ALIGN(sizeof(msg)),
+			      len - NLA_ALIGN(sizeof(msg)),
+			      unix_diag_attrs, "UNIX_DIAG_???");
+	}
 }
 
 static void
diff --git a/nlattr.c b/nlattr.c
new file mode 100644
index 0000000..827f109
--- /dev/null
+++ b/nlattr.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016 Fabien Siron <fabien.siron at epita.fr>
+ * Copyright (c) 2017 JingPiao Chen <chenjingpiao at gmail.com>
+ * 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 <linux/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)
+{
+	tprints("{");
+
+	print_nlattr(nla, table, dflt);
+
+	unsigned int nla_len = nla->nla_len > len ? len : nla->nla_len;
+
+	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;
+		}
+
+		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/xlat/unix_diag_attrs.in b/xlat/unix_diag_attrs.in
new file mode 100644
index 0000000..4c3d9b2
--- /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.7.4





More information about the Strace-devel mailing list