1e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin/* 2e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * Check decoding of setreuid/setregid/setreuid32/setregid32 syscalls. 3e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * 4e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org> 5e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * All rights reserved. 6e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * 7e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * Redistribution and use in source and binary forms, with or without 8e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * modification, are permitted provided that the following conditions 9e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * are met: 10e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * 1. Redistributions of source code must retain the above copyright 11e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * notice, this list of conditions and the following disclaimer. 12e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * 2. Redistributions in binary form must reproduce the above copyright 13e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * notice, this list of conditions and the following disclaimer in the 14e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * documentation and/or other materials provided with the distribution. 15e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * 3. The name of the author may not be used to endorse or promote products 16e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * derived from this software without specific prior written permission. 17e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * 18e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin */ 29e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 30e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin#include <errno.h> 31e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin#include <stdio.h> 32e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin#include <unistd.h> 33e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 34e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinstatic int 35e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinugid2int(const unsigned UGID_TYPE ugid) 36e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin{ 37e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin if ((unsigned UGID_TYPE) -1U == ugid) 38e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin return -1; 39e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin else 40e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin return ugid; 41e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin} 42e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 43e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinstatic void 44e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinprint_int(const unsigned int num) 45e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin{ 46e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin if (num == -1U) 47e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin printf("-1"); 48e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin else 49e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin printf("%u", num); 50e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin} 51e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 52e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinstatic int 53e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinnum_matches_id(const unsigned int num, const unsigned int ugid) 54e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin{ 55e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin return num == ugid || num == -1U; 56e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin} 57e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 58e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin#define PAIR(val) { val, ugid }, { ugid, val } 59e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 60e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinint 61e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levinmain(void) 62e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin{ 63e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin unsigned int ugid = GETUGID; 64e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin CHECK_OVERFLOWUGID(ugid); 65e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 66e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin const struct { 67e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin const long r, e; 68e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin } tests[] = { 69e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin { ugid, ugid }, 70e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin PAIR((unsigned long) 0xffffffff00000000ULL | ugid), 71e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin PAIR(-1U), 72e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin PAIR(-1L), 73e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin PAIR(0xffff0000U | ugid), 74e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin PAIR(0xffff), 75e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin PAIR(0xc0deffffU) 76e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin }; 77e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 78e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin unsigned int i; 79e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 80e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin for (i = 0; i < ARRAY_SIZE(tests); ++i) { 81e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin const unsigned int rn = ugid2int(tests[i].r); 82e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin const unsigned int en = ugid2int(tests[i].e); 83e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 84e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin if (!num_matches_id(rn, ugid) || !num_matches_id(en, ugid)) 85e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin continue; 86e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 87e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin if (syscall(SYSCALL_NR, tests[i].r, tests[i].e)) { 88e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin if (!i && ENOSYS == errno) { 89e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin printf("%s(%u, %u) = -1 ENOSYS (%m)\n", 90e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin SYSCALL_NAME, ugid, ugid); 91e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin break; 92e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin } 93e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin perror_msg_and_fail("%s(%#lx, %#lx)", SYSCALL_NAME, 94e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin tests[i].r, tests[i].e); 95e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin } 96e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 97e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin printf("%s(", SYSCALL_NAME); 98e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin print_int(rn); 99e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin printf(", "); 100e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin print_int(en); 101e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin printf(") = 0\n"); 102e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin } 103e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin 104e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin puts("+++ exited with 0 +++"); 105e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin return 0; 106e6d847385050f4ff1de9e10f17875f4e0d30a163Dmitry V. Levin} 107