19fa5f6b4SRobert Watson /*- 29fa5f6b4SRobert Watson * Copyright (c) 2006 nCircle Network Security, Inc. 39fa5f6b4SRobert Watson * All rights reserved. 49fa5f6b4SRobert Watson * 59fa5f6b4SRobert Watson * This software was developed by Robert N. M. Watson for the TrustedBSD 69fa5f6b4SRobert Watson * Project under contract to nCircle Network Security, Inc. 79fa5f6b4SRobert Watson * 89fa5f6b4SRobert Watson * Redistribution and use in source and binary forms, with or without 99fa5f6b4SRobert Watson * modification, are permitted provided that the following conditions 109fa5f6b4SRobert Watson * are met: 119fa5f6b4SRobert Watson * 1. Redistributions of source code must retain the above copyright 129fa5f6b4SRobert Watson * notice, this list of conditions and the following disclaimer. 139fa5f6b4SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 149fa5f6b4SRobert Watson * notice, this list of conditions and the following disclaimer in the 159fa5f6b4SRobert Watson * documentation and/or other materials provided with the distribution. 169fa5f6b4SRobert Watson * 179fa5f6b4SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 189fa5f6b4SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 199fa5f6b4SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 209fa5f6b4SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, 219fa5f6b4SRobert Watson * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 229fa5f6b4SRobert Watson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 239fa5f6b4SRobert Watson * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 249fa5f6b4SRobert Watson * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 259fa5f6b4SRobert Watson * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 269fa5f6b4SRobert Watson * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 279fa5f6b4SRobert Watson * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 289fa5f6b4SRobert Watson * 299fa5f6b4SRobert Watson * $FreeBSD$ 309fa5f6b4SRobert Watson */ 319fa5f6b4SRobert Watson 329fa5f6b4SRobert Watson /* 339fa5f6b4SRobert Watson * Test privilege check on /dev/io. By default, the permissions also protect 349fa5f6b4SRobert Watson * against non-superuser access, so this program will modify permissions on 359fa5f6b4SRobert Watson * /dev/io to allow group access for the wheel group, and revert the change 369fa5f6b4SRobert Watson * on exit. This is not good for run-time security, but is necessary to test 379fa5f6b4SRobert Watson * the checks properly. 389fa5f6b4SRobert Watson */ 399fa5f6b4SRobert Watson 409fa5f6b4SRobert Watson #include <sys/types.h> 419fa5f6b4SRobert Watson #include <sys/stat.h> 429fa5f6b4SRobert Watson 439fa5f6b4SRobert Watson #include <err.h> 449fa5f6b4SRobert Watson #include <errno.h> 459fa5f6b4SRobert Watson #include <fcntl.h> 469fa5f6b4SRobert Watson #include <unistd.h> 479fa5f6b4SRobert Watson 489fa5f6b4SRobert Watson #include "main.h" 499fa5f6b4SRobert Watson 509fa5f6b4SRobert Watson #define NEW_PERMS 0660 519fa5f6b4SRobert Watson #define DEV_IO "/dev/io" 529fa5f6b4SRobert Watson #define EXPECTED_PERMS 0600 539fa5f6b4SRobert Watson 549fa5f6b4SRobert Watson static mode_t saved_perms; 559fa5f6b4SRobert Watson 569fa5f6b4SRobert Watson static void 579fa5f6b4SRobert Watson save_perms(void) 589fa5f6b4SRobert Watson { 599fa5f6b4SRobert Watson struct stat sb; 609fa5f6b4SRobert Watson 619fa5f6b4SRobert Watson if (stat(DEV_IO, &sb) < 0) 629fa5f6b4SRobert Watson err(-1, "save_perms: stat(%s)", DEV_IO); 639fa5f6b4SRobert Watson 649fa5f6b4SRobert Watson saved_perms = sb.st_mode & ALLPERMS; 659fa5f6b4SRobert Watson 669fa5f6b4SRobert Watson if (saved_perms != EXPECTED_PERMS) 679fa5f6b4SRobert Watson err(-1, "save_perms: perms = 0%o; expected 0%o", saved_perms, 689fa5f6b4SRobert Watson EXPECTED_PERMS); 699fa5f6b4SRobert Watson 709fa5f6b4SRobert Watson } 719fa5f6b4SRobert Watson 729fa5f6b4SRobert Watson static void 739fa5f6b4SRobert Watson set_perms(void) 749fa5f6b4SRobert Watson { 759fa5f6b4SRobert Watson 769fa5f6b4SRobert Watson if (chmod(DEV_IO, NEW_PERMS) < 0) 779fa5f6b4SRobert Watson err(-1, "set_perms: chmod(%s, 0%o)", DEV_IO, NEW_PERMS); 789fa5f6b4SRobert Watson } 799fa5f6b4SRobert Watson 809fa5f6b4SRobert Watson static void 819fa5f6b4SRobert Watson restore_perms(void) 829fa5f6b4SRobert Watson { 839fa5f6b4SRobert Watson 849fa5f6b4SRobert Watson if (chmod(DEV_IO, saved_perms) < 0) 859fa5f6b4SRobert Watson err(-1, "restore_perms: chmod(%s, 0%o)", DEV_IO, saved_perms); 869fa5f6b4SRobert Watson } 879fa5f6b4SRobert Watson 889fa5f6b4SRobert Watson static void 899fa5f6b4SRobert Watson try_open(const char *test_case, uid_t uid, int expected) 909fa5f6b4SRobert Watson { 919fa5f6b4SRobert Watson int fd; 929fa5f6b4SRobert Watson 939fa5f6b4SRobert Watson set_euid(uid); 949fa5f6b4SRobert Watson fd = open(DEV_IO, O_RDONLY); 959fa5f6b4SRobert Watson if (expected == 0) { 969fa5f6b4SRobert Watson if (fd == -1) { 979fa5f6b4SRobert Watson warn("try_open: %s open(%s) errno %d", DEV_IO, 989fa5f6b4SRobert Watson test_case, errno); 999fa5f6b4SRobert Watson goto out; 1009fa5f6b4SRobert Watson } 1019fa5f6b4SRobert Watson close(fd); 1029fa5f6b4SRobert Watson goto out; 1039fa5f6b4SRobert Watson } 1049fa5f6b4SRobert Watson if (fd >= 0) { 1059fa5f6b4SRobert Watson warn("try_open: %s open(%s) unexpected success", test_case, 1069fa5f6b4SRobert Watson DEV_IO); 1079fa5f6b4SRobert Watson close(fd); 1089fa5f6b4SRobert Watson goto out; 1099fa5f6b4SRobert Watson } 1109fa5f6b4SRobert Watson if (errno == expected) 1119fa5f6b4SRobert Watson goto out; 1129fa5f6b4SRobert Watson warn("try_open: %s open(%s) wrong errno %d, expected %d", DEV_IO, 1139fa5f6b4SRobert Watson test_case, errno, expected); 1149fa5f6b4SRobert Watson out: 1159fa5f6b4SRobert Watson set_euid(UID_ROOT); 1169fa5f6b4SRobert Watson } 1179fa5f6b4SRobert Watson 1189fa5f6b4SRobert Watson void 1199fa5f6b4SRobert Watson priv_io(void) 1209fa5f6b4SRobert Watson { 1219fa5f6b4SRobert Watson 1229fa5f6b4SRobert Watson assert_root(); 1239fa5f6b4SRobert Watson 1249fa5f6b4SRobert Watson save_perms(); 1259fa5f6b4SRobert Watson 1269fa5f6b4SRobert Watson try_open("root:0600", UID_ROOT, 0); 1279fa5f6b4SRobert Watson try_open("other", UID_OTHER, EACCES); 1289fa5f6b4SRobert Watson 1299fa5f6b4SRobert Watson set_perms(); 1309fa5f6b4SRobert Watson 1319fa5f6b4SRobert Watson try_open("root:0660", UID_ROOT, 0); 1329fa5f6b4SRobert Watson try_open("other", UID_OTHER, EPERM); 1339fa5f6b4SRobert Watson 1349fa5f6b4SRobert Watson restore_perms(); 1359fa5f6b4SRobert Watson } 136