1 /* $NetBSD: t_ro.c,v 1.8 2019/09/21 14:25:42 kre Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/stat.h> 30 #include <sys/statvfs.h> 31 32 #include <atf-c.h> 33 #include <fcntl.h> 34 #include <libgen.h> 35 #include <stdlib.h> 36 #include <unistd.h> 37 38 #include <rump/rump_syscalls.h> 39 #include <rump/rump.h> 40 41 #include "../common/h_fsmacros.h" 42 #include "h_macros.h" 43 44 #define AFILE "testfile" 45 #define ADIR "testdir" 46 #define AFIFO "testfifo" 47 #define ASYMLINK "testsymlink" 48 #define ALINK "testlink" 49 #define FUNTEXT "this is some non-humppa text" 50 #define FUNSIZE (sizeof(FUNTEXT)-1) 51 52 static void 53 nullgen(const atf_tc_t *tc, const char *mp) 54 { 55 56 return; 57 } 58 59 static void 60 filegen(const atf_tc_t *tc, const char *mp) 61 { 62 int fd; 63 64 FSTEST_ENTER(); 65 RL(fd = rump_sys_open(AFILE, O_CREAT | O_RDWR, 0777)); 66 ATF_REQUIRE_EQ(rump_sys_write(fd, FUNTEXT, FUNSIZE), FUNSIZE); 67 RL(rump_sys_close(fd)); 68 FSTEST_EXIT(); 69 } 70 71 /* 72 * 73 * BEGIN tests 74 * 75 */ 76 77 static void 78 create(const atf_tc_t *tc, const char *mp) 79 { 80 81 FSTEST_ENTER(); 82 ATF_REQUIRE_ERRNO(EROFS, rump_sys_open(AFILE, O_CREAT|O_RDONLY, 83 0600) == -1); 84 FSTEST_EXIT(); 85 } 86 87 static void 88 rmfile(const atf_tc_t *tc, const char *mp) 89 { 90 91 FSTEST_ENTER(); 92 ATF_REQUIRE_ERRNO(EROFS, rump_sys_unlink(AFILE) == -1); 93 FSTEST_EXIT(); 94 } 95 96 static void 97 fileio(const atf_tc_t *tc, const char *mp) 98 { 99 int fd; 100 char buf[FUNSIZE+1]; 101 int expected; 102 103 if (FSTYPE_NFSRO(tc)) 104 expected = EACCES; 105 else 106 expected = EROFS; 107 108 FSTEST_ENTER(); 109 RL(fd = rump_sys_open(AFILE, O_RDONLY)); 110 ATF_REQUIRE_EQ(rump_sys_read(fd, buf, FUNSIZE), FUNSIZE); 111 buf[FUNSIZE] = '\0'; 112 ATF_REQUIRE_STREQ(buf, FUNTEXT); 113 RL(rump_sys_close(fd)); 114 115 ATF_REQUIRE_ERRNO(expected, rump_sys_open(AFILE, O_WRONLY) == -1); 116 ATF_REQUIRE_ERRNO(expected, rump_sys_open(AFILE, O_RDWR) == -1); 117 FSTEST_EXIT(); 118 } 119 120 static void 121 attrs(const atf_tc_t *tc, const char *mp) 122 { 123 struct timeval sometvs[2] = { {0,0}, {0,0} }; 124 struct stat sb; 125 int fd; 126 127 FSTEST_ENTER(); 128 129 RL(rump_sys_stat(AFILE, &sb)); 130 131 ATF_REQUIRE_ERRNO(EROFS, rump_sys_chmod(AFILE, 0775) == -1); 132 if (!FSTYPE_MSDOS(tc)) 133 ATF_REQUIRE_ERRNO(EROFS, rump_sys_chown(AFILE, 1, 1) == -1); 134 ATF_REQUIRE_ERRNO(EROFS, rump_sys_utimes(AFILE, sometvs) == -1); 135 136 RL(fd = rump_sys_open(AFILE, O_RDONLY)); 137 ATF_REQUIRE_ERRNO(EROFS, rump_sys_fchmod(fd, 0775) == -1); 138 if (!FSTYPE_MSDOS(tc)) 139 ATF_REQUIRE_ERRNO(EROFS, rump_sys_fchown(fd, 1, 1) == -1); 140 ATF_REQUIRE_ERRNO(EROFS, rump_sys_futimes(fd, sometvs) == -1); 141 RL(rump_sys_close(fd)); 142 143 FSTEST_EXIT(); 144 } 145 146 static void 147 createdir(const atf_tc_t *tc, const char *mp) 148 { 149 150 FSTEST_ENTER(); 151 ATF_REQUIRE_ERRNO(EROFS, rump_sys_mkdir(ADIR, 0775) == -1); 152 FSTEST_EXIT(); 153 } 154 155 static void 156 createfifo(const atf_tc_t *tc, const char *mp) 157 { 158 159 FSTEST_ENTER(); 160 ATF_REQUIRE_ERRNO(EROFS, rump_sys_mkfifo(AFIFO, 0775) == -1); 161 FSTEST_EXIT(); 162 } 163 164 static void 165 createsymlink(const atf_tc_t *tc, const char *mp) 166 { 167 168 FSTEST_ENTER(); 169 ATF_REQUIRE_ERRNO(EROFS, rump_sys_symlink("hoge", ASYMLINK) == -1); 170 FSTEST_EXIT(); 171 } 172 173 static void 174 createlink(const atf_tc_t *tc, const char *mp) 175 { 176 177 FSTEST_ENTER(); 178 ATF_REQUIRE_ERRNO(EROFS, rump_sys_link(AFILE, ALINK) == -1); 179 FSTEST_EXIT(); 180 } 181 182 ATF_TC_FSAPPLY_RO(create, "create file on r/o mount", nullgen); 183 ATF_TC_FSAPPLY_RO(rmfile, "remove file from r/o mount", filegen); 184 ATF_TC_FSAPPLY_RO(fileio, "can read a file but not write it", filegen); 185 ATF_TC_FSAPPLY_RO(attrs, "can query but not change attributes", filegen); 186 ATF_TC_FSAPPLY_RO(createdir, "create directory on r/o mount", nullgen); 187 ATF_TC_FSAPPLY_RO(createfifo, "create fifo on r/o mount", nullgen); 188 ATF_TC_FSAPPLY_RO(createsymlink, "create symlink on r/o mount", nullgen); 189 ATF_TC_FSAPPLY_RO(createlink, "create hardlink on r/o mount", filegen); 190 191 ATF_TP_ADD_TCS(tp) 192 { 193 194 ATF_TP_FSAPPLY_RO(create); 195 ATF_TP_FSAPPLY_RO(rmfile); 196 ATF_TP_FSAPPLY_RO(fileio); 197 ATF_TP_FSAPPLY_RO(attrs); 198 ATF_TP_FSAPPLY_RO(createdir); 199 ATF_TP_FSAPPLY_RO(createfifo); 200 ATF_TP_FSAPPLY_RO(createsymlink); 201 ATF_TP_FSAPPLY_RO(createlink); 202 203 return atf_no_error(); 204 } 205