1 /*- 2 * Copyright (c) 2006 nCircle Network Security, Inc. 3 * All rights reserved. 4 * 5 * This software was developed by Robert N. M. Watson for the TrustedBSD 6 * Project under contract to nCircle Network Security, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, 21 * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 /* 33 * Test privilege check on /dev/io. By default, the permissions also protect 34 * against non-superuser access, so this program will modify permissions on 35 * /dev/io to allow group access for the wheel group, and revert the change 36 * on exit. This is not good for run-time security, but is necessary to test 37 * the checks properly. 38 */ 39 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 43 #include <err.h> 44 #include <errno.h> 45 #include <fcntl.h> 46 #include <unistd.h> 47 48 #include "main.h" 49 50 #define NEW_PERMS 0660 51 #define DEV_IO "/dev/io" 52 #define EXPECTED_PERMS 0600 53 54 static mode_t saved_perms; 55 56 static void 57 save_perms(void) 58 { 59 struct stat sb; 60 61 if (stat(DEV_IO, &sb) < 0) 62 err(-1, "save_perms: stat(%s)", DEV_IO); 63 64 saved_perms = sb.st_mode & ALLPERMS; 65 66 if (saved_perms != EXPECTED_PERMS) 67 err(-1, "save_perms: perms = 0%o; expected 0%o", saved_perms, 68 EXPECTED_PERMS); 69 70 } 71 72 static void 73 set_perms(void) 74 { 75 76 if (chmod(DEV_IO, NEW_PERMS) < 0) 77 err(-1, "set_perms: chmod(%s, 0%o)", DEV_IO, NEW_PERMS); 78 } 79 80 static void 81 restore_perms(void) 82 { 83 84 if (chmod(DEV_IO, saved_perms) < 0) 85 err(-1, "restore_perms: chmod(%s, 0%o)", DEV_IO, saved_perms); 86 } 87 88 static void 89 try_open(const char *test_case, uid_t uid, int expected) 90 { 91 int fd; 92 93 set_euid(uid); 94 fd = open(DEV_IO, O_RDONLY); 95 if (expected == 0) { 96 if (fd == -1) { 97 warn("try_open: %s open(%s) errno %d", DEV_IO, 98 test_case, errno); 99 goto out; 100 } 101 close(fd); 102 goto out; 103 } 104 if (fd >= 0) { 105 warn("try_open: %s open(%s) unexpected success", test_case, 106 DEV_IO); 107 close(fd); 108 goto out; 109 } 110 if (errno == expected) 111 goto out; 112 warn("try_open: %s open(%s) wrong errno %d, expected %d", DEV_IO, 113 test_case, errno, expected); 114 out: 115 set_euid(UID_ROOT); 116 } 117 118 void 119 priv_io(void) 120 { 121 122 assert_root(); 123 124 save_perms(); 125 126 try_open("root:0600", UID_ROOT, 0); 127 try_open("other", UID_OTHER, EACCES); 128 129 set_perms(); 130 131 try_open("root:0660", UID_ROOT, 0); 132 try_open("other", UID_OTHER, EPERM); 133 134 restore_perms(); 135 } 136