Implement decoding of NS_* ioctl commands
* configure.ac (AC_CHECK_HEADERS): Add linux/nsfs.h. * defs.h (DECL_IOCTL(nsfs)): New prototype. (setns_types): Make global. * ioctl.c (ioctl_decode): Call nsfs_ioctl for 0xb7 code. * nsfs.c: New file. * nsfs.h: Likewise. * Makefile.am (strace_SOURCES): Add them. * tests/ioctl_nsfs.c: New file. * tests/ioctl_nsfs.test: Likewise. * tests/.gitignore: Add ioctl_nsfs. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add ioctl_nsfs.test. * NEWS: Mention this change.
This commit is contained in:
parent
0a3bb911c7
commit
2afd57decb
@ -171,6 +171,8 @@ strace_SOURCES = \
|
||||
native_defs.h \
|
||||
net.c \
|
||||
netlink.c \
|
||||
nsfs.c \
|
||||
nsfs.h \
|
||||
nsig.h \
|
||||
numa.c \
|
||||
oldstat.c \
|
||||
|
1
NEWS
1
NEWS
@ -18,6 +18,7 @@ Noteworthy changes in release ?.?? (????-??-??)
|
||||
powerpc, powerpc64, riscv, sh, sh64, sparc, sparc64, tile, x86, and xtensa
|
||||
architectures.
|
||||
* Implemented decoding of statx syscall.
|
||||
* Implemented decoding of NS_* ioctl commands.
|
||||
* Updated lists of ioctl commands from Linux 4.11.
|
||||
|
||||
* Bug fixes
|
||||
|
@ -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
|
||||
|
2
defs.h
2
defs.h
@ -301,6 +301,7 @@ extern const struct xlat netlink_protocols[];
|
||||
extern const struct xlat open_access_modes[];
|
||||
extern const struct xlat open_mode_flags[];
|
||||
extern const struct xlat resource_flags[];
|
||||
extern const struct xlat setns_types[];
|
||||
extern const struct xlat sg_io_info[];
|
||||
extern const struct xlat socketlayers[];
|
||||
extern const struct xlat whence_codes[];
|
||||
@ -642,6 +643,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);
|
||||
|
2
ioctl.c
2
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);
|
||||
|
65
nsfs.c
Normal file
65
nsfs.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Support for decoding of NS_* ioctl commands.
|
||||
*
|
||||
* Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a@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 "nsfs.h"
|
||||
|
||||
int
|
||||
nsfs_ioctl(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
|
||||
{
|
||||
unsigned int uid;
|
||||
switch (code) {
|
||||
case NS_GET_USERNS:
|
||||
case NS_GET_PARENT:
|
||||
return 1 + RVAL_FD + RVAL_DECODED;
|
||||
case NS_GET_NSTYPE:
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
if (!syserror(tcp)) {
|
||||
const char *outstr;
|
||||
outstr = xlookup(setns_types, tcp->u_rval);
|
||||
if (outstr) {
|
||||
tcp->auxstr = outstr;
|
||||
return 1 + RVAL_STR;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
case NS_GET_OWNER_UID:
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
tprints(", ");
|
||||
if (!umove_or_printaddr(tcp, arg, &uid)) {
|
||||
printuid("[", uid);
|
||||
tprints("]");
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
}
|
21
nsfs.h
Normal file
21
nsfs.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef STRACE_NSFS_H
|
||||
#define STRACE_NSFS_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#ifdef HAVE_LINUX_NSFS_H
|
||||
# include <linux/nsfs.h>
|
||||
#else
|
||||
# define NSIO 0xb7
|
||||
# define NS_GET_USERNS _IO(NSIO, 0x1)
|
||||
# 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 /* !STRACE_NSFS_H */
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -124,6 +124,7 @@ ioctl_loop
|
||||
ioctl_loop-nv
|
||||
ioctl_loop-v
|
||||
ioctl_mtd
|
||||
ioctl_nsfs
|
||||
ioctl_rtc
|
||||
ioctl_rtc-v
|
||||
ioctl_scsi
|
||||
|
@ -188,6 +188,7 @@ check_PROGRAMS = \
|
||||
ioctl_loop-nv \
|
||||
ioctl_loop-v \
|
||||
ioctl_mtd \
|
||||
ioctl_nsfs \
|
||||
ioctl_rtc \
|
||||
ioctl_rtc-v \
|
||||
ioctl_scsi \
|
||||
@ -507,6 +508,7 @@ DECODER_TESTS = \
|
||||
ioctl_dm-v.test \
|
||||
ioctl_dm.test \
|
||||
ioctl_loop-nv.test \
|
||||
ioctl_nsfs.test \
|
||||
ioctl_sock_gifconf.test \
|
||||
ipc_msgbuf.test \
|
||||
llseek.test \
|
||||
|
139
tests/ioctl_nsfs.c
Normal file
139
tests/ioctl_nsfs.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Check decoding of NS_* commands of ioctl syscall.
|
||||
*
|
||||
* Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a@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 <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include "nsfs.h"
|
||||
|
||||
#ifndef CLONE_NEWUSER
|
||||
# define CLONE_NEWUSER 0x10000000
|
||||
#endif
|
||||
|
||||
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_clone(pid_t pid)
|
||||
{
|
||||
char path[sizeof("/proc/%d/ns/user") + sizeof(int)*3];
|
||||
snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
|
||||
|
||||
int ns_fd = open(path, O_RDONLY);
|
||||
if (ns_fd == -1)
|
||||
perror_msg_and_skip("open: %s", path);
|
||||
|
||||
int userns_fd = ioctl(ns_fd, NS_GET_USERNS);
|
||||
printf("ioctl(%d, NS_GET_USERNS) = %s\n", ns_fd, sprintrc(userns_fd));
|
||||
|
||||
int parent_ns_fd = ioctl(userns_fd, NS_GET_PARENT);
|
||||
printf("ioctl(%d, NS_GET_PARENT) = %s\n",
|
||||
userns_fd, sprintrc(parent_ns_fd));
|
||||
|
||||
int nstype = ioctl(userns_fd, NS_GET_NSTYPE);
|
||||
if (nstype == -1) {
|
||||
printf("ioctl(%d, NS_GET_NSTYPE) = %s\n",
|
||||
userns_fd, sprintrc(nstype));
|
||||
} else {
|
||||
printf("ioctl(%d, NS_GET_NSTYPE) = %d (CLONE_NEWUSER)\n",
|
||||
userns_fd, nstype);
|
||||
}
|
||||
|
||||
TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, uid);
|
||||
int rc = ioctl(userns_fd, NS_GET_OWNER_UID, uid);
|
||||
if (rc == -1) {
|
||||
printf("ioctl(%d, NS_GET_OWNER_UID, %p) = %s\n",
|
||||
userns_fd, uid, sprintrc(rc));
|
||||
} else {
|
||||
printf("ioctl(%d, NS_GET_OWNER_UID, [%u]) = %d\n",
|
||||
userns_fd, *uid, rc);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
child(void *arg)
|
||||
{
|
||||
int *pipefd = (int *) arg;
|
||||
close(pipefd[1]);
|
||||
/* Wait for EOF from pipe. */
|
||||
if (read(pipefd[0], &pipefd[1], 1))
|
||||
perror_msg_and_fail("read");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_user_namespace(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int pipefd[2];
|
||||
int status;
|
||||
|
||||
if (pipe(pipefd))
|
||||
perror_msg_and_fail("pipe");
|
||||
|
||||
pid = clone(child, tail_alloc(1) + 1,
|
||||
CLONE_NEWUSER | CLONE_UNTRACED | SIGCHLD, pipefd);
|
||||
if (pid == -1) {
|
||||
perror("clone");
|
||||
return;
|
||||
}
|
||||
close(pipefd[0]);
|
||||
test_clone(pid);
|
||||
close(pipefd[1]);
|
||||
if (wait(&status) != pid) {
|
||||
perror_msg_and_fail("wait");
|
||||
} else if (status != 0) {
|
||||
error_msg_and_fail("unexpected child exit status %d", status);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
test_no_namespace();
|
||||
test_user_namespace();
|
||||
puts("+++ exited with 0 +++");
|
||||
return 0;
|
||||
}
|
11
tests/ioctl_nsfs.test
Executable file
11
tests/ioctl_nsfs.test
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check decoding of NS_* ioctls.
|
||||
|
||||
. "${srcdir=.}/init.sh"
|
||||
|
||||
check_prog grep
|
||||
run_prog > /dev/null
|
||||
run_strace -a16 -eioctl -esignal=none $args > "$EXP"
|
||||
grep -v '^ioctl([012],' < "$LOG" > "$OUT"
|
||||
match_diff "$OUT" "$EXP"
|
Loading…
x
Reference in New Issue
Block a user