1*63d1fd59SEnji Cooper /* $NetBSD: t_unpriv.c,v 1.13 2017/01/13 21:30:40 christos Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /*- 457718be8SEnji Cooper * Copyright (c) 2011 The NetBSD Foundation, Inc. 557718be8SEnji Cooper * All rights reserved. 657718be8SEnji Cooper * 757718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 857718be8SEnji Cooper * modification, are permitted provided that the following conditions 957718be8SEnji Cooper * are met: 1057718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 1157718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 1257718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 1457718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 1557718be8SEnji Cooper * 1657718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1757718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1857718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1957718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2057718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2157718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2257718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2357718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2457718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2557718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2657718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 2757718be8SEnji Cooper */ 2857718be8SEnji Cooper 2957718be8SEnji Cooper #include <sys/stat.h> 3057718be8SEnji Cooper #include <sys/time.h> 3157718be8SEnji Cooper 3257718be8SEnji Cooper #include <atf-c.h> 3357718be8SEnji Cooper #include <libgen.h> 3457718be8SEnji Cooper #include <limits.h> 3557718be8SEnji Cooper #include <unistd.h> 3657718be8SEnji Cooper 3757718be8SEnji Cooper #include <rump/rump_syscalls.h> 3857718be8SEnji Cooper #include <rump/rump.h> 3957718be8SEnji Cooper 4057718be8SEnji Cooper #include "../common/h_fsmacros.h" 41*63d1fd59SEnji Cooper #include "h_macros.h" 4257718be8SEnji Cooper 4357718be8SEnji Cooper #define USES_OWNER \ 4457718be8SEnji Cooper if (FSTYPE_MSDOS(tc)) \ 4557718be8SEnji Cooper atf_tc_skip("owner not supported by file system") 4657718be8SEnji Cooper 4757718be8SEnji Cooper static void 4857718be8SEnji Cooper owner(const atf_tc_t *tc, const char *mp) 4957718be8SEnji Cooper { 5057718be8SEnji Cooper 5157718be8SEnji Cooper USES_OWNER; 5257718be8SEnji Cooper 5357718be8SEnji Cooper FSTEST_ENTER(); 5457718be8SEnji Cooper 5557718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 5657718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 5757718be8SEnji Cooper atf_tc_fail_errno("setuid"); 5857718be8SEnji Cooper if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM) 5957718be8SEnji Cooper atf_tc_fail_errno("chown"); 6057718be8SEnji Cooper if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM) 6157718be8SEnji Cooper atf_tc_fail_errno("chmod"); 6257718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 6357718be8SEnji Cooper 6457718be8SEnji Cooper if (rump_sys_chown(".", 1, -1) == -1) 6557718be8SEnji Cooper atf_tc_fail_errno("chown"); 6657718be8SEnji Cooper 6757718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 6857718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 6957718be8SEnji Cooper atf_tc_fail_errno("setuid"); 7057718be8SEnji Cooper if (rump_sys_chown(".", 1, -1) == -1) 7157718be8SEnji Cooper atf_tc_fail_errno("chown"); 7257718be8SEnji Cooper if (rump_sys_chmod(".", 0000) == -1) 7357718be8SEnji Cooper atf_tc_fail_errno("chmod"); 7457718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 7557718be8SEnji Cooper 7657718be8SEnji Cooper FSTEST_EXIT(); 7757718be8SEnji Cooper } 7857718be8SEnji Cooper 7957718be8SEnji Cooper static void 8057718be8SEnji Cooper dirperms(const atf_tc_t *tc, const char *mp) 8157718be8SEnji Cooper { 8257718be8SEnji Cooper char name[] = "dir.test/file.test"; 8357718be8SEnji Cooper char *dir = dirname(name); 8457718be8SEnji Cooper int fd; 8557718be8SEnji Cooper 8657718be8SEnji Cooper if (FSTYPE_SYSVBFS(tc)) 8757718be8SEnji Cooper atf_tc_skip("directories not supported by file system"); 8857718be8SEnji Cooper 8957718be8SEnji Cooper FSTEST_ENTER(); 9057718be8SEnji Cooper 9157718be8SEnji Cooper if (rump_sys_mkdir(dir, 0777) == -1) 9257718be8SEnji Cooper atf_tc_fail_errno("mkdir"); 9357718be8SEnji Cooper 9457718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 9557718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 9657718be8SEnji Cooper atf_tc_fail_errno("setuid"); 9757718be8SEnji Cooper if (FSTYPE_ZFS(tc)) 9857718be8SEnji Cooper atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 9957718be8SEnji Cooper if (rump_sys_open(name, O_RDWR|O_CREAT, 0666) != -1 || errno != EACCES) 10057718be8SEnji Cooper atf_tc_fail_errno("open"); 10157718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 10257718be8SEnji Cooper 10357718be8SEnji Cooper if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 10457718be8SEnji Cooper atf_tc_fail_errno("open"); 10557718be8SEnji Cooper if (rump_sys_close(fd) == -1) 10657718be8SEnji Cooper atf_tc_fail_errno("close"); 10757718be8SEnji Cooper 10857718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 10957718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 11057718be8SEnji Cooper atf_tc_fail_errno("setuid"); 11157718be8SEnji Cooper if (rump_sys_unlink(name) != -1 || errno != EACCES) 11257718be8SEnji Cooper atf_tc_fail_errno("unlink"); 11357718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 11457718be8SEnji Cooper 11557718be8SEnji Cooper if (rump_sys_unlink(name) == -1) 11657718be8SEnji Cooper atf_tc_fail_errno("unlink"); 11757718be8SEnji Cooper 11857718be8SEnji Cooper if (rump_sys_rmdir(dir) == -1) 11957718be8SEnji Cooper atf_tc_fail_errno("rmdir"); 12057718be8SEnji Cooper 12157718be8SEnji Cooper FSTEST_EXIT(); 12257718be8SEnji Cooper } 12357718be8SEnji Cooper 12457718be8SEnji Cooper static void 12557718be8SEnji Cooper times(const atf_tc_t *tc, const char *mp) 12657718be8SEnji Cooper { 12757718be8SEnji Cooper const char *name = "file.test"; 12857718be8SEnji Cooper int fd; 12957718be8SEnji Cooper unsigned int i, j; 13057718be8SEnji Cooper struct timeval tmv[2]; 13157718be8SEnji Cooper static struct timeval tmvs[] = { 13257718be8SEnji Cooper { QUAD_MIN, 0 }, 13357718be8SEnji Cooper { 0, 0 }, 13457718be8SEnji Cooper { QUAD_MAX, 999999 } 13557718be8SEnji Cooper }; 13657718be8SEnji Cooper 13757718be8SEnji Cooper FSTEST_ENTER(); 13857718be8SEnji Cooper 13957718be8SEnji Cooper if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 14057718be8SEnji Cooper atf_tc_fail_errno("open"); 14157718be8SEnji Cooper if (rump_sys_close(fd) == -1) 14257718be8SEnji Cooper atf_tc_fail_errno("close"); 14357718be8SEnji Cooper 14457718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 14557718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 14657718be8SEnji Cooper atf_tc_fail_errno("setuid"); 14757718be8SEnji Cooper if (FSTYPE_ZFS(tc)) 14857718be8SEnji Cooper atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 14957718be8SEnji Cooper if (rump_sys_utimes(name, NULL) != -1 || errno != EACCES) 15057718be8SEnji Cooper atf_tc_fail_errno("utimes"); 15157718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 15257718be8SEnji Cooper 15357718be8SEnji Cooper if (rump_sys_utimes(name, NULL) == -1) 15457718be8SEnji Cooper atf_tc_fail_errno("utimes"); 15557718be8SEnji Cooper 15657718be8SEnji Cooper for (i = 0; i < sizeof(tmvs) / sizeof(tmvs[0]); i++) { 15757718be8SEnji Cooper for (j = 0; j < sizeof(tmvs) / sizeof(tmvs[0]); j++) { 15857718be8SEnji Cooper tmv[0] = tmvs[i]; 15957718be8SEnji Cooper tmv[1] = tmvs[j]; 16057718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 16157718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 16257718be8SEnji Cooper atf_tc_fail_errno("setuid"); 16357718be8SEnji Cooper if (rump_sys_utimes(name, tmv) != -1 || errno != EPERM) 16457718be8SEnji Cooper atf_tc_fail_errno("utimes"); 16557718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 16657718be8SEnji Cooper 16757718be8SEnji Cooper if (rump_sys_utimes(name, tmv) == -1) 16857718be8SEnji Cooper atf_tc_fail_errno("utimes"); 16957718be8SEnji Cooper } 17057718be8SEnji Cooper } 17157718be8SEnji Cooper 17257718be8SEnji Cooper if (rump_sys_unlink(name) == -1) 17357718be8SEnji Cooper atf_tc_fail_errno("unlink"); 17457718be8SEnji Cooper 17557718be8SEnji Cooper FSTEST_EXIT(); 17657718be8SEnji Cooper } 17757718be8SEnji Cooper 17857718be8SEnji Cooper static void 17957718be8SEnji Cooper flags(const atf_tc_t *tc, const char *mp) 18057718be8SEnji Cooper { 18157718be8SEnji Cooper const char *name = "file.test"; 18257718be8SEnji Cooper int fd, fflags; 18357718be8SEnji Cooper struct stat st; 18457718be8SEnji Cooper 18557718be8SEnji Cooper FSTEST_ENTER(); 18657718be8SEnji Cooper 18757718be8SEnji Cooper if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) 18857718be8SEnji Cooper atf_tc_fail_errno("open"); 18957718be8SEnji Cooper if (rump_sys_close(fd) == -1) 19057718be8SEnji Cooper atf_tc_fail_errno("close"); 19157718be8SEnji Cooper 19257718be8SEnji Cooper if (rump_sys_stat(name, &st) == -1) 19357718be8SEnji Cooper atf_tc_fail_errno("stat"); 19457718be8SEnji Cooper if (FSTYPE_ZFS(tc)) 19557718be8SEnji Cooper atf_tc_expect_fail("PR kern/47656: Test known to be broken"); 19657718be8SEnji Cooper if (rump_sys_chflags(name, st.st_flags) == -1) { 19757718be8SEnji Cooper if (errno == EOPNOTSUPP) 19857718be8SEnji Cooper atf_tc_skip("file flags not supported by file system"); 19957718be8SEnji Cooper atf_tc_fail_errno("chflags"); 20057718be8SEnji Cooper } 20157718be8SEnji Cooper 20257718be8SEnji Cooper fflags = st.st_flags | UF_IMMUTABLE; 20357718be8SEnji Cooper 20457718be8SEnji Cooper rump_pub_lwproc_rfork(RUMP_RFCFDG); 20557718be8SEnji Cooper if (rump_sys_setuid(1) == -1) 20657718be8SEnji Cooper atf_tc_fail_errno("setuid"); 20757718be8SEnji Cooper fflags |= UF_IMMUTABLE; 20857718be8SEnji Cooper if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM) 20957718be8SEnji Cooper atf_tc_fail_errno("chflags"); 21057718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 21157718be8SEnji Cooper 21257718be8SEnji Cooper if (rump_sys_chflags(name, fflags) == -1) 21357718be8SEnji Cooper atf_tc_fail_errno("chflags"); 21457718be8SEnji Cooper 21557718be8SEnji Cooper fflags &= ~UF_IMMUTABLE; 21657718be8SEnji Cooper if (rump_sys_chflags(name, fflags) == -1) 21757718be8SEnji Cooper atf_tc_fail_errno("chflags"); 21857718be8SEnji Cooper 21957718be8SEnji Cooper if (rump_sys_unlink(name) == -1) 22057718be8SEnji Cooper atf_tc_fail_errno("unlink"); 22157718be8SEnji Cooper 22257718be8SEnji Cooper FSTEST_EXIT(); 22357718be8SEnji Cooper } 22457718be8SEnji Cooper 22557718be8SEnji Cooper ATF_TC_FSAPPLY(owner, "owner unprivileged checks"); 22657718be8SEnji Cooper ATF_TC_FSAPPLY(dirperms, "directory permission checks"); 22757718be8SEnji Cooper ATF_TC_FSAPPLY(times, "time set checks"); 22857718be8SEnji Cooper ATF_TC_FSAPPLY(flags, "file flags checks"); 22957718be8SEnji Cooper 23057718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 23157718be8SEnji Cooper { 23257718be8SEnji Cooper 23357718be8SEnji Cooper ATF_TP_FSAPPLY(owner); 23457718be8SEnji Cooper ATF_TP_FSAPPLY(dirperms); 23557718be8SEnji Cooper ATF_TP_FSAPPLY(times); 23657718be8SEnji Cooper ATF_TP_FSAPPLY(flags); 23757718be8SEnji Cooper 23857718be8SEnji Cooper return atf_no_error(); 23957718be8SEnji Cooper } 240