From 0eac88a00a3a96640b5d686788bd9a68edb43cc5 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 18 Apr 2016 15:16:53 +0000 Subject: [PATCH] tests: extend test coverage of setresuid syscall * tests/setresugid.c: New file. * tests/setresuid.c: New file. * tests/setresuid.test: New test. * tests/.gitignore: Add setresuid. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add setresuid.test. (EXTRA_DIST): Add setresugid.c. --- tests/.gitignore | 1 + tests/Makefile.am | 3 ++ tests/setresugid.c | 113 +++++++++++++++++++++++++++++++++++++++++++ tests/setresuid.c | 25 ++++++++++ tests/setresuid.test | 6 +++ 5 files changed, 148 insertions(+) create mode 100644 tests/setresugid.c create mode 100644 tests/setresuid.c create mode 100755 tests/setresuid.test diff --git a/tests/.gitignore b/tests/.gitignore index 02ea5b0d..8368c0f6 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -147,6 +147,7 @@ setgid32 sethostname setregid setregid32 +setresuid setreuid setreuid32 setuid diff --git a/tests/Makefile.am b/tests/Makefile.am index 95d75a8e..ca89c14b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -197,6 +197,7 @@ check_PROGRAMS = \ sethostname \ setregid \ setregid32 \ + setresuid \ setreuid \ setreuid32 \ setuid \ @@ -412,6 +413,7 @@ DECODER_TESTS = \ sethostname.test \ setregid.test \ setregid32.test \ + setresuid.test \ setreuid.test \ setreuid32.test \ setuid.test \ @@ -523,6 +525,7 @@ EXTRA_DIST = init.sh run.sh match.awk \ ppoll.expected \ ppoll-v.expected \ setreugid.c \ + setresugid.c \ setugid.c \ sigaction.awk \ sigaltstack.expected \ diff --git a/tests/setresugid.c b/tests/setresugid.c new file mode 100644 index 00000000..711bd317 --- /dev/null +++ b/tests/setresugid.c @@ -0,0 +1,113 @@ +/* + * Check decoding of setresuid/setresgid/setresuid32/setresgid32 syscalls. + * + * Copyright (c) 2016 Dmitry V. Levin + * 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 +#include +#include + +static int +ugid2int(const unsigned UGID_TYPE ugid) +{ + if ((unsigned UGID_TYPE) -1U == ugid) + return -1; + else + return ugid; +} + +static void +print_int(const unsigned int num) +{ + if (num == -1U) + printf("-1"); + else + printf("%u", num); +} + +static int +num_matches_id(const unsigned int num, const unsigned int ugid) +{ + return num == ugid || num == -1U; +} + +#define TRIPLE(val) \ + { val, ugid, ugid }, { ugid, val, ugid }, { ugid, ugid, val } + +int +main(void) +{ + unsigned int ugid = GETUGID; + CHECK_OVERFLOWUGID(ugid); + + const struct { + const long r, e, s; + } tests[] = { + { ugid, ugid, ugid }, + TRIPLE((unsigned long) 0xffffffff00000000ULL | ugid), + TRIPLE(-1U), + TRIPLE(-1L), + TRIPLE(0xffff0000U | ugid), + TRIPLE(0xffff), + TRIPLE(0xc0deffffU) + }; + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + const unsigned int rn = ugid2int(tests[i].r); + const unsigned int en = ugid2int(tests[i].e); + const unsigned int sn = ugid2int(tests[i].s); + + if (!num_matches_id(rn, ugid) || + !num_matches_id(en, ugid) || + !num_matches_id(sn, ugid)) + continue; + + if (syscall(SYSCALL_NR, tests[i].r, tests[i].e, tests[i].s)) { + if (!i && ENOSYS == errno) { + printf("%s(%u, %u, %u) = -1 ENOSYS (%m)\n", + SYSCALL_NAME, ugid, ugid, ugid); + break; + } + perror_msg_and_fail("%s(%#lx, %#lx, %#lx)", + SYSCALL_NAME, + tests[i].r, tests[i].e, tests[i].s); + } + + printf("%s(", SYSCALL_NAME); + print_int(rn); + printf(", "); + print_int(en); + printf(", "); + print_int(sn); + printf(") = 0\n"); + } + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/setresuid.c b/tests/setresuid.c new file mode 100644 index 00000000..b924f914 --- /dev/null +++ b/tests/setresuid.c @@ -0,0 +1,25 @@ +#include "tests.h" +#include + +#ifdef __NR_setresuid + +# define SYSCALL_NR __NR_setresuid +# define SYSCALL_NAME "setresuid" + +# if defined __NR_setresuid32 && __NR_setresuid != __NR_setresuid32 +# define UGID_TYPE short +# define GETUGID syscall(__NR_geteuid) +# define CHECK_OVERFLOWUGID(arg) check_overflowuid(arg) +# else +# define UGID_TYPE int +# define GETUGID geteuid() +# define CHECK_OVERFLOWUGID(arg) +# endif + +# include "setresugid.c" + +#else + +SKIP_MAIN_UNDEFINED("__NR_setresuid") + +#endif diff --git a/tests/setresuid.test b/tests/setresuid.test new file mode 100755 index 00000000..f1219e06 --- /dev/null +++ b/tests/setresuid.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check setresuid syscall decoding. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a19 -- 2.40.0