[PATCH] Implemented parser for NS_* ioctl commands.

Nikolay Marchuk marchuk.nikolay.a at gmail.com
Sat Mar 18 12:27:14 UTC 2017


Sorry, sent wrong commit.
>From 6618b4fdc99e07e09fd8d8049a347f0153c85ab5 Mon Sep 17 00:00:00 2001
From: Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
Date: Thu, 16 Mar 2017 17:49:25 +0700
Subject: [PATCH 1/2] Add ioctl namespace entries from Linux 4.11

---
 linux/32/ioctls_inc_align16.h | 2 ++
 linux/32/ioctls_inc_align32.h | 2 ++
 linux/32/ioctls_inc_align64.h | 2 ++
 linux/64/ioctls_inc.h         | 2 ++
 linux/x32/ioctls_inc0.h       | 2 ++
 5 files changed, 10 insertions(+)

diff --git a/linux/32/ioctls_inc_align16.h b/linux/32/ioctls_inc_align16.h
index 71c9d18..4e90801 100644
--- a/linux/32/ioctls_inc_align16.h
+++ b/linux/32/ioctls_inc_align16.h
@@ -1455,6 +1455,8 @@
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c,
0x10 },
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18
},
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
+{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
 { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
 { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
0x4e41, 0x48 },
diff --git a/linux/32/ioctls_inc_align32.h b/linux/32/ioctls_inc_align32.h
index 699eb90..4fcada1 100644
--- a/linux/32/ioctls_inc_align32.h
+++ b/linux/32/ioctls_inc_align32.h
@@ -1455,6 +1455,8 @@
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c,
0x10 },
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18
},
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
+{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
 { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
 { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
0x4e41, 0x48 },
diff --git a/linux/32/ioctls_inc_align64.h b/linux/32/ioctls_inc_align64.h
index fcd9d8c..3734082 100644
--- a/linux/32/ioctls_inc_align64.h
+++ b/linux/32/ioctls_inc_align64.h
@@ -1455,6 +1455,8 @@
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c,
0x10 },
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18
},
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
+{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
 { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
 { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
0x4e41, 0x48 },
diff --git a/linux/64/ioctls_inc.h b/linux/64/ioctls_inc.h
index f59fe11..b75abec 100644
--- a/linux/64/ioctls_inc.h
+++ b/linux/64/ioctls_inc.h
@@ -1455,6 +1455,8 @@
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c,
0x10 },
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18
},
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
+{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
 { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
 { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
0x4e41, 0x48 },
diff --git a/linux/x32/ioctls_inc0.h b/linux/x32/ioctls_inc0.h
index 46303d1..81dd21c 100644
--- a/linux/x32/ioctls_inc0.h
+++ b/linux/x32/ioctls_inc0.h
@@ -1455,6 +1455,8 @@
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c,
0x10 },
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18
},
 { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
+{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
 { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
 { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
0x4e41, 0x48 },
-- 
2.1.4


>From c9d54f099021f69ead791da8c5a533f14bb40a8a Mon Sep 17 00:00:00 2001
From: Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
Date: Sat, 18 Mar 2017 19:23:06 +0700
Subject: [PATCH 2/2] Implemented parser for NS_* ioctl commands.

---
 Makefile.am           |   1 +
 configure.ac          |   1 +
 defs.h                |   1 +
 ioctl.c               |   2 +
 nsfs.c                |  94 ++++++++++++++++++++++++++++++++++++
 tests/.gitignore      |   1 +
 tests/Makefile.am     |   2 +
 tests/ioctl_nsfs.c    | 131
++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/ioctl_nsfs.test |  13 +++++
 9 files changed, 246 insertions(+)
 create mode 100644 nsfs.c
 create mode 100644 tests/ioctl_nsfs.c
 create mode 100755 tests/ioctl_nsfs.test

diff --git a/Makefile.am b/Makefile.am
index c77f463..338fb62 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -172,6 +172,7 @@ strace_SOURCES = \
  net.c \
  netlink.c       \
  nsig.h \
+ nsfs.c \
  numa.c \
  oldstat.c \
  open.c \
diff --git a/configure.ac b/configure.ac
index 9e5087b..dc49fdc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -366,6 +366,7 @@ AC_CHECK_HEADERS(m4_normalize([
  linux/ipc.h
  linux/mmtimer.h
  linux/msg.h
+ linux/nsfs.h
  linux/perf_event.h
  linux/quota.h
  linux/seccomp.h
diff --git a/defs.h b/defs.h
index 793971e..0f3ec14 100644
--- a/defs.h
+++ b/defs.h
@@ -640,6 +640,7 @@ name ## _ioctl(struct tcb *, unsigned int request,
kernel_ulong_t arg)
 DECL_IOCTL(dm);
 DECL_IOCTL(file);
 DECL_IOCTL(fs_x);
+DECL_IOCTL(nsfs);
 DECL_IOCTL(ptp);
 DECL_IOCTL(scsi);
 DECL_IOCTL(term);
diff --git a/ioctl.c b/ioctl.c
index aa1880f..4511e0b 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -280,6 +280,8 @@ ioctl_decode(struct tcb *tcp)
  case 0x94:
  return btrfs_ioctl(tcp, code, arg);
 #endif
+ case 0xb7:
+ return nsfs_ioctl(tcp, code, arg);
 #ifdef HAVE_LINUX_DM_IOCTL_H
  case 0xfd:
  return dm_ioctl(tcp, code, arg);
diff --git a/nsfs.c b/nsfs.c
new file mode 100644
index 0000000..0baeda1
--- /dev/null
+++ b/nsfs.c
@@ -0,0 +1,94 @@
+/*
+ * Support for decoding of NS_* ioctl commands.
+ *
+ * Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
+ * 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/ioctl.h>
+
+/* Definitions for commands */
+#ifdef HAVE_LINUX_NSFS_H
+# include <linux/nsfs.h>
+#else
+# ifndef NSIO
+#  define NSIO 0xb7
+# endif
+# ifndef NS_GET_USERNS
+#  define NS_GET_USERNS _IO(NSIO, 0x1)
+# endif
+# ifndef NS_GET_PARENT
+#  define NS_GET_PARENT _IO(NSIO, 0x2)
+# endif
+#endif
+
+#ifndef NS_GET_NSTYPE
+# define NS_GET_NSTYPE _IO(NSIO, 0x3)
+#endif
+#ifndef NS_GET_OWNER_UID
+# define NS_GET_OWNER_UID _IO(NSIO, 0x4)
+#endif
+
+#include <sys/types.h>
+#include "xlat/setns_types.h"
+
+int
+nsfs_ioctl(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ const char *outstr;
+ uid_t uid;
+ if (entering(tcp)) {
+ switch (code) {
+ case NS_GET_USERNS:
+ case NS_GET_PARENT:
+ return RVAL_DECODED | (1 + RVAL_FD);
+ default:
+ return 0;
+ }
+ } else {
+ switch (code) {
+ case NS_GET_NSTYPE:
+ if (!syserror(tcp)) {
+ outstr = xlookup(setns_types, tcp->u_rval);
+ if (outstr) {
+ tcp->auxstr = outstr;
+ return 1 + RVAL_STR;
+ }
+ }
+ return 1 + RVAL_DECIMAL;
+ case NS_GET_OWNER_UID:
+ tprints(", ");
+ if (!umove_or_printaddr(tcp, arg, &uid)) {
+ printuid("[", uid);
+ tprints("]");
+ }
+ return 1 + RVAL_DECIMAL;
+ default:
+ return 0;
+ }
+ }
+}
diff --git a/tests/.gitignore b/tests/.gitignore
index a1ed6d0..aa38105 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -122,6 +122,7 @@ ioctl_loop
 ioctl_loop-nv
 ioctl_loop-v
 ioctl_mtd
+ioctl_nsfs
 ioctl_rtc
 ioctl_rtc-v
 ioctl_scsi
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a75b7fc..a4d6c88 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -185,6 +185,7 @@ check_PROGRAMS = \
  ioctl_loop-nv \
  ioctl_loop-v \
  ioctl_mtd \
+ ioctl_nsfs \
  ioctl_rtc \
  ioctl_rtc-v \
  ioctl_scsi \
@@ -594,6 +595,7 @@ DECODER_TESTS = \
  ioctl_loop-v.test \
  ioctl_loop.test \
  ioctl_mtd.test \
+ ioctl_nsfs.test \
  ioctl_rtc-v.test \
  ioctl_rtc.test \
  ioctl_scsi.test \
diff --git a/tests/ioctl_nsfs.c b/tests/ioctl_nsfs.c
new file mode 100644
index 0000000..05aa513
--- /dev/null
+++ b/tests/ioctl_nsfs.c
@@ -0,0 +1,131 @@
+/*
+ * Check decoding of NS_* commands of ioctl syscall.
+ *
+ * Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
+ * 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 "tests.h"
+
+# include <fcntl.h>
+# include <linux/ioctl.h>
+
+/* Definitions for commands */
+#ifdef HAVE_LINUX_NSFS_H
+# include <linux/nsfs.h>
+#else
+# ifndef NSIO
+#  define NSIO 0xb7
+# endif
+# ifndef NS_GET_USERNS
+#  define NS_GET_USERNS _IO(NSIO, 0x1)
+# endif
+# ifndef NS_GET_PARENT
+#  define NS_GET_PARENT _IO(NSIO, 0x2)
+# endif
+#endif
+
+#ifndef NS_GET_NSTYPE
+# define NS_GET_NSTYPE _IO(NSIO, 0x3)
+#endif
+#ifndef NS_GET_OWNER_UID
+# define NS_GET_OWNER_UID _IO(NSIO, 0x4)
+#endif
+
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static void
+test_no_namespace(void)
+{
+ ioctl(-1, NS_GET_USERNS);
+ printf("ioctl(-1, NS_GET_USERNS) = -1 EBADF (%m)\n");
+ ioctl(-1, NS_GET_PARENT);
+ printf("ioctl(-1, NS_GET_PARENT) = -1 EBADF (%m)\n");
+ ioctl(-1, NS_GET_NSTYPE);
+ printf("ioctl(-1, NS_GET_NSTYPE) = -1 EBADF (%m)\n");
+ ioctl(-1, NS_GET_OWNER_UID, NULL);
+ printf("ioctl(-1, NS_GET_OWNER_UID, NULL) = -1 EBADF (%m)\n");
+}
+
+static void
+test_user_namespace(void)
+{
+ int ns_fd, userns_fd, parent_ns_fd, nstype, rc;
+ uid_t uid;
+ const char *errstr;
+
+ rc = unshare(CLONE_NEWUSER);
+ if (rc == -1)
+ perror_msg_and_skip("Unshare user namespace error");
+
+ ns_fd = open("/proc/self/ns/user", O_RDONLY);
+ if (rc == -1)
+ perror_msg_and_skip("Open user namespace file error");
+
+ userns_fd = ioctl(ns_fd, NS_GET_USERNS);
+ errstr = sprintrc(userns_fd);
+ printf("ioctl(%d, NS_GET_USERNS) = %s\n", ns_fd, errstr);
+
+ parent_ns_fd = ioctl(userns_fd, NS_GET_PARENT);
+ errstr = sprintrc(parent_ns_fd);
+ printf("ioctl(%d, NS_GET_PARENT) = %s\n", userns_fd, errstr);
+
+ nstype = ioctl(userns_fd, NS_GET_NSTYPE);
+ errstr = sprintrc(nstype);
+ if (nstype == CLONE_NEWUSER) {
+ printf("ioctl(%d, NS_GET_NSTYPE) = %d (CLONE_NEWUSER)\n", userns_fd,
+   nstype);
+ } else {
+ printf("ioctl(%d, NS_GET_NSTYPE) = %s\n", userns_fd, errstr);
+ }
+
+ rc = ioctl(userns_fd, NS_GET_OWNER_UID, &uid);
+ errstr = sprintrc(rc);
+ if (rc == -1) {
+ printf("ioctl(%d, NS_GET_OWNER_UID, %p) = %s\n", userns_fd, &uid,
+   errstr);
+ } else {
+ printf("ioctl(%d, NS_GET_OWNER_UID, [", userns_fd, &uid);
+ if ((uid_t) -1U == (uid_t) uid)
+ printf("-1]) = %s\n", errstr);
+ else
+ printf("%u]) = %s\n", uid, errstr);
+ }
+}
+
+int
+main(void)
+{
+ test_no_namespace();
+ test_user_namespace();
+ puts("+++ exited with 0 +++");
+ return 0;
+}
diff --git a/tests/ioctl_nsfs.test b/tests/ioctl_nsfs.test
new file mode 100755
index 0000000..8fe8da5
--- /dev/null
+++ b/tests/ioctl_nsfs.test
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# Check decoding of NS_* ioctls.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+run_strace -a16 -eioctl $args > "$EXP"
+check_prog grep
+grep -v '^ioctl([012],' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
+
+rm -f "$EXP" "$OUT"
-- 
2.1.4


On Sat, Mar 18, 2017 at 3:55 PM, Nikolay Marchuk <
marchuk.nikolay.a at gmail.com> wrote:

> From 33d0341f2705e067b7617a6ec30e442d707714d0 Mon Sep 17 00:00:00 2001
> From: Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
> Date: Thu, 16 Mar 2017 17:49:25 +0700
> Subject: [PATCH 1/2] Add ioctl namespace entries from Linux 4.11
>
> ---
>  linux/32/ioctls_inc_align16.h | 2 ++
>  linux/32/ioctls_inc_align32.h | 2 ++
>  linux/32/ioctls_inc_align64.h | 2 ++
>  linux/64/ioctls_inc.h         | 2 ++
>  linux/x32/ioctls_inc0.h       | 2 ++
>  5 files changed, 10 insertions(+)
>
> diff --git a/linux/32/ioctls_inc_align16.h b/linux/32/ioctls_inc_align16.h
> index 71c9d18..4e90801 100644
> --- a/linux/32/ioctls_inc_align16.h
> +++ b/linux/32/ioctls_inc_align16.h
> @@ -1455,6 +1455,8 @@
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE,
> 0x6e8c, 0x10 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d,
> 0x18 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
> +{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
> +{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
>  { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
>  { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
>  { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
> 0x4e41, 0x48 },
> diff --git a/linux/32/ioctls_inc_align32.h b/linux/32/ioctls_inc_align32.h
> index 699eb90..4fcada1 100644
> --- a/linux/32/ioctls_inc_align32.h
> +++ b/linux/32/ioctls_inc_align32.h
> @@ -1455,6 +1455,8 @@
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE,
> 0x6e8c, 0x10 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d,
> 0x18 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
> +{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
> +{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
>  { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
>  { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
>  { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
> 0x4e41, 0x48 },
> diff --git a/linux/32/ioctls_inc_align64.h b/linux/32/ioctls_inc_align64.h
> index fcd9d8c..3734082 100644
> --- a/linux/32/ioctls_inc_align64.h
> +++ b/linux/32/ioctls_inc_align64.h
> @@ -1455,6 +1455,8 @@
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE,
> 0x6e8c, 0x10 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d,
> 0x18 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
> +{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
> +{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
>  { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
>  { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
>  { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
> 0x4e41, 0x48 },
> diff --git a/linux/64/ioctls_inc.h b/linux/64/ioctls_inc.h
> index f59fe11..b75abec 100644
> --- a/linux/64/ioctls_inc.h
> +++ b/linux/64/ioctls_inc.h
> @@ -1455,6 +1455,8 @@
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE,
> 0x6e8c, 0x10 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d,
> 0x18 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
> +{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
> +{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
>  { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
>  { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
>  { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
> 0x4e41, 0x48 },
> diff --git a/linux/x32/ioctls_inc0.h b/linux/x32/ioctls_inc0.h
> index 46303d1..81dd21c 100644
> --- a/linux/x32/ioctls_inc0.h
> +++ b/linux/x32/ioctls_inc0.h
> @@ -1455,6 +1455,8 @@
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE,
> 0x6e8c, 0x10 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d,
> 0x18 },
>  { "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
> +{ "linux/nsfs.h", "NS_GET_NSTYPE", _IOC_NONE, 0xb703, 0x00 },
> +{ "linux/nsfs.h", "NS_GET_OWNER_UID", _IOC_NONE, 0xb704, 0x00 },
>  { "linux/nsfs.h", "NS_GET_PARENT", _IOC_NONE, 0xb702, 0x00 },
>  { "linux/nsfs.h", "NS_GET_USERNS", _IOC_NONE, 0xb701, 0x00 },
>  { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE,
> 0x4e41, 0x48 },
> --
> 2.1.4
>
>
> From 994940e890a539143311a97050bf7024caeb3c7b Mon Sep 17 00:00:00 2001
> From: Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
> Date: Sat, 18 Mar 2017 15:49:27 +0700
> Subject: [PATCH 2/2] Implemented parser for NS_* ioctl commands.
>
> ---
>  Makefile.am           |   1 +
>  configure.ac          |   1 +
>  defs.h                |   1 +
>  ioctl.c               |   2 +
>  nsfs.c                |  93 ++++++++++++++++++++++++++++++++++
>  tests/.gitignore      |   1 +
>  tests/Makefile.am     |   2 +
>  tests/ioctl_nsfs.c    | 138 ++++++++++++++++++++++++++++++
> ++++++++++++++++++++
>  tests/ioctl_nsfs.test |  13 +++++
>  9 files changed, 252 insertions(+)
>  create mode 100644 nsfs.c
>  create mode 100644 tests/ioctl_nsfs.c
>  create mode 100755 tests/ioctl_nsfs.test
>
> diff --git a/Makefile.am b/Makefile.am
> index c77f463..338fb62 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -172,6 +172,7 @@ strace_SOURCES = \
>   net.c \
>   netlink.c       \
>   nsig.h \
> + nsfs.c \
>   numa.c \
>   oldstat.c \
>   open.c \
> diff --git a/configure.ac b/configure.ac
> index 9e5087b..dc49fdc 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -366,6 +366,7 @@ AC_CHECK_HEADERS(m4_normalize([
>   linux/ipc.h
>   linux/mmtimer.h
>   linux/msg.h
> + linux/nsfs.h
>   linux/perf_event.h
>   linux/quota.h
>   linux/seccomp.h
> diff --git a/defs.h b/defs.h
> index 793971e..0f3ec14 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -640,6 +640,7 @@ name ## _ioctl(struct tcb *, unsigned int request,
> kernel_ulong_t arg)
>  DECL_IOCTL(dm);
>  DECL_IOCTL(file);
>  DECL_IOCTL(fs_x);
> +DECL_IOCTL(nsfs);
>  DECL_IOCTL(ptp);
>  DECL_IOCTL(scsi);
>  DECL_IOCTL(term);
> diff --git a/ioctl.c b/ioctl.c
> index aa1880f..4511e0b 100644
> --- a/ioctl.c
> +++ b/ioctl.c
> @@ -280,6 +280,8 @@ ioctl_decode(struct tcb *tcp)
>   case 0x94:
>   return btrfs_ioctl(tcp, code, arg);
>  #endif
> + case 0xb7:
> + return nsfs_ioctl(tcp, code, arg);
>  #ifdef HAVE_LINUX_DM_IOCTL_H
>   case 0xfd:
>   return dm_ioctl(tcp, code, arg);
> diff --git a/nsfs.c b/nsfs.c
> new file mode 100644
> index 0000000..508716d
> --- /dev/null
> +++ b/nsfs.c
> @@ -0,0 +1,93 @@
> +/*
> + * Support for decoding of NS_* ioctl commands.
> + *
> + * Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
> + * 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/ioctl.h>
> +
> +/* Definitions for commands */
> +#ifdef HAVE_LINUX_NSFS_H
> +# include <linux/nsfs.h>
> +#else
> +# ifndef NSIO
> +#  define NSIO 0xb7
> +# endif
> +# ifndef NS_GET_USERNS
> +#  define NS_GET_USERNS _IO(NSIO, 0x1)
> +# endif
> +# ifndef NS_GET_PARENT
> +#  define NS_GET_PARENT _IO(NSIO, 0x2)
> +# endif
> +# ifndef NS_GET_NSTYPE
> +#  define NS_GET_NSTYPE _IO(NSIO, 0x3)
> +# endif
> +# ifndef NS_GET_OWNER_UID
> +#  define NS_GET_OWNER_UID _IO(NSIO, 0x4)
> +# endif
> +#endif
> +
> +#include <sys/types.h>
> +#include "xlat/setns_types.h"
> +
> +int
> +nsfs_ioctl(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
> +{
> + const char *outstr;
> + uid_t uid;
> + if (entering(tcp)) {
> + switch (code) {
> + case NS_GET_USERNS:
> + case NS_GET_PARENT:
> + return RVAL_DECODED | (1 + RVAL_FD);
> + default:
> + return 0;
> + }
> + } else {
> + switch (code) {
> + case NS_GET_NSTYPE:
> + if (!syserror(tcp)) {
> + outstr = xlookup(setns_types, tcp->u_rval);
> + if (outstr) {
> + tcp->auxstr = outstr;
> + return 1 + RVAL_STR;
> + }
> + }
> + return 1 + RVAL_DECIMAL;
> + case NS_GET_OWNER_UID:
> + tprints(", ");
> + if (!umove_or_printaddr(tcp, arg, &uid)) {
> + printuid("[", uid);
> + tprints("]");
> + }
> + return 1 + RVAL_DECIMAL;
> + default:
> + return 0;
> + }
> + }
> +}
> diff --git a/tests/.gitignore b/tests/.gitignore
> index a7754b6..060a391 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -121,6 +121,7 @@ ioctl_loop
>  ioctl_loop-nv
>  ioctl_loop-v
>  ioctl_mtd
> +ioctl_nsfs
>  ioctl_rtc
>  ioctl_rtc-v
>  ioctl_scsi
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index c5c124c..bc0c621 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -184,6 +184,7 @@ check_PROGRAMS = \
>   ioctl_loop-nv \
>   ioctl_loop-v \
>   ioctl_mtd \
> + ioctl_nsfs \
>   ioctl_rtc \
>   ioctl_rtc-v \
>   ioctl_scsi \
> @@ -593,6 +594,7 @@ DECODER_TESTS = \
>   ioctl_loop-v.test \
>   ioctl_loop.test \
>   ioctl_mtd.test \
> + ioctl_nsfs.test \
>   ioctl_rtc-v.test \
>   ioctl_rtc.test \
>   ioctl_scsi.test \
> diff --git a/tests/ioctl_nsfs.c b/tests/ioctl_nsfs.c
> new file mode 100644
> index 0000000..38c161b
> --- /dev/null
> +++ b/tests/ioctl_nsfs.c
> @@ -0,0 +1,138 @@
> +/*
> + * Check decoding of NS_* commands of ioctl syscall.
> + *
> + * Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
> + * 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 "tests.h"
> +
> +/* Definitions for commands */
> +#ifdef HAVE_LINUX_NSFS_H
> +# include <linux/nsfs.h>
> +#else
> +# ifndef NSIO
> +#  define NSIO 0xb7
> +# endif
> +# ifndef NS_GET_USERNS
> +#  define NS_GET_USERNS _IO(NSIO, 0x1)
> +# endif
> +# ifndef NS_GET_PARENT
> +#  define NS_GET_PARENT _IO(NSIO, 0x2)
> +# endif
> +# ifndef NS_GET_NSTYPE
> +#  define NS_GET_NSTYPE _IO(NSIO, 0x3)
> +# endif
> +# ifndef NS_GET_OWNER_UID
> +#  define NS_GET_OWNER_UID _IO(NSIO, 0x4)
> +# endif
> +#endif
> +
> +# include <fcntl.h>
> +# include <linux/ioctl.h>
> +# include <sched.h>
> +# include <stdio.h>
> +# include <stdlib.h>
> +# include <sys/ioctl.h>
> +# include <sys/types.h>
> +# include <sys/wait.h>
> +# include <unistd.h>
> +
> +/* Definitions for command which have been added later */
> +# ifndef NS_GET_NSTYPE
> +#  define NS_GET_NSTYPE _IO(NSIO, 0x3)
> +# endif
> +# ifndef NS_GET_OWNER_UID
> +#  define NS_GET_OWNER_UID _IO(NSIO, 0x4)
> +# endif
> +
> +static void
> +test_no_namespace(void)
> +{
> + uid_t uid = 1;
> + ioctl(-1, NS_GET_USERNS);
> + printf("ioctl(-1, NS_GET_USERNS) = -1 EBADF (%m)\n");
> + ioctl(-1, NS_GET_PARENT);
> + printf("ioctl(-1, NS_GET_PARENT) = -1 EBADF (%m)\n");
> + ioctl(-1, NS_GET_NSTYPE);
> + printf("ioctl(-1, NS_GET_NSTYPE) = -1 EBADF (%m)\n");
> + ioctl(-1, NS_GET_OWNER_UID, NULL);
> + printf("ioctl(-1, NS_GET_OWNER_UID, NULL) = -1 EBADF (%m)\n");
> +}
> +
> +static void
> +test_user_namespace(void)
> +{
> + int ns_fd, userns_fd, parent_ns_fd, nstype, rc;
> + uid_t uid;
> + const char *errstr;
> +
> + rc = unshare(CLONE_NEWUSER);
> + if (rc == -1)
> + perror_msg_and_skip("Unshare user namespace error");
> +
> + ns_fd = open("/proc/self/ns/user", O_RDONLY);
> + if (rc == -1)
> + perror_msg_and_skip("Open user namespace file error");
> +
> + userns_fd = ioctl(ns_fd, NS_GET_USERNS);
> + errstr = sprintrc(userns_fd);
> + printf("ioctl(%d, NS_GET_USERNS) = %s\n", ns_fd, errstr);
> +
> + parent_ns_fd = ioctl(userns_fd, NS_GET_PARENT);
> + errstr = sprintrc(parent_ns_fd);
> + printf("ioctl(%d, NS_GET_PARENT) = %s\n", userns_fd, errstr);
> +
> + nstype = ioctl(userns_fd, NS_GET_NSTYPE);
> + errstr = sprintrc(nstype);
> + if (nstype == CLONE_NEWUSER) {
> + printf("ioctl(%d, NS_GET_NSTYPE) = %d (CLONE_NEWUSER)\n", userns_fd,
> +   nstype);
> + } else {
> + printf("ioctl(%d, NS_GET_NSTYPE) = %s\n", userns_fd, errstr);
> + }
> +
> + rc = ioctl(userns_fd, NS_GET_OWNER_UID, &uid);
> + errstr = sprintrc(rc);
> + if (rc == -1) {
> + printf("ioctl(%d, NS_GET_OWNER_UID, %p) = %s\n", userns_fd, &uid,
> +   errstr);
> + } else {
> + printf("ioctl(%d, NS_GET_OWNER_UID, [", userns_fd, &uid);
> + if ((uid_t) -1U == (uid_t) uid)
> + printf("-1]) = %s\n", errstr);
> + else
> + printf("%u]) = %s\n", uid, errstr);
> + }
> +}
> +
> +int
> +main(void)
> +{
> + test_no_namespace();
> + test_user_namespace();
> + puts("+++ exited with 0 +++");
> + return 0;
> +}
> diff --git a/tests/ioctl_nsfs.test b/tests/ioctl_nsfs.test
> new file mode 100755
> index 0000000..8fe8da5
> --- /dev/null
> +++ b/tests/ioctl_nsfs.test
> @@ -0,0 +1,13 @@
> +#!/bin/sh
> +
> +# Check decoding of NS_* ioctls.
> +
> +. "${srcdir=.}/init.sh"
> +
> +run_prog > /dev/null
> +run_strace -a16 -eioctl $args > "$EXP"
> +check_prog grep
> +grep -v '^ioctl([012],' < "$LOG" > "$OUT"
> +match_diff "$OUT" "$EXP"
> +
> +rm -f "$EXP" "$OUT"
> --
> 2.1.4
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20170318/2edf769d/attachment.html>


More information about the Strace-devel mailing list