1 /* $NetBSD: t_ro.c,v 1.6 2017/01/13 21:30:40 christos 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) == -1); 83 FSTEST_EXIT(); 84 } 85 86 static void 87 rmfile(const atf_tc_t *tc, const char *mp) 88 { 89 90 FSTEST_ENTER(); 91 ATF_REQUIRE_ERRNO(EROFS, rump_sys_unlink(AFILE) == -1); 92 FSTEST_EXIT(); 93 } 94 95 static void 96 fileio(const atf_tc_t *tc, const char *mp) 97 { 98 int fd; 99 char buf[FUNSIZE+1]; 100 int expected; 101 102 if (FSTYPE_NFSRO(tc)) 103 expected = EACCES; 104 else 105 expected = EROFS; 106 107 FSTEST_ENTER(); 108 RL(fd = rump_sys_open(AFILE, O_RDONLY)); 109 ATF_REQUIRE_EQ(rump_sys_read(fd, buf, FUNSIZE), FUNSIZE); 110 buf[FUNSIZE] = '\0'; 111 ATF_REQUIRE_STREQ(buf, FUNTEXT); 112 RL(rump_sys_close(fd)); 113 114 ATF_REQUIRE_ERRNO(expected, rump_sys_open(AFILE, O_WRONLY) == -1); 115 ATF_REQUIRE_ERRNO(expected, rump_sys_open(AFILE, O_RDWR) == -1); 116 FSTEST_EXIT(); 117 } 118 119 static void 120 attrs(const atf_tc_t *tc, const char *mp) 121 { 122 struct timeval sometvs[2]; 123 struct stat sb; 124 int fd; 125 126 FSTEST_ENTER(); 127 128 RL(rump_sys_stat(AFILE, &sb)); 129 130 ATF_REQUIRE_ERRNO(EROFS, rump_sys_chmod(AFILE, 0775) == -1); 131 if (!FSTYPE_MSDOS(tc)) 132 ATF_REQUIRE_ERRNO(EROFS, rump_sys_chown(AFILE, 1, 1) == -1); 133 ATF_REQUIRE_ERRNO(EROFS, rump_sys_utimes(AFILE, sometvs) == -1); 134 135 RL(fd = rump_sys_open(AFILE, O_RDONLY)); 136 ATF_REQUIRE_ERRNO(EROFS, rump_sys_fchmod(fd, 0775) == -1); 137 if (!FSTYPE_MSDOS(tc)) 138 ATF_REQUIRE_ERRNO(EROFS, rump_sys_fchown(fd, 1, 1) == -1); 139 ATF_REQUIRE_ERRNO(EROFS, rump_sys_futimes(fd, sometvs) == -1); 140 RL(rump_sys_close(fd)); 141 142 FSTEST_EXIT(); 143 } 144 145 static void 146 createdir(const atf_tc_t *tc, const char *mp) 147 { 148 149 FSTEST_ENTER(); 150 ATF_REQUIRE_ERRNO(EROFS, rump_sys_mkdir(ADIR, 0775) == -1); 151 FSTEST_EXIT(); 152 } 153 154 static void 155 createfifo(const atf_tc_t *tc, const char *mp) 156 { 157 158 FSTEST_ENTER(); 159 ATF_REQUIRE_ERRNO(EROFS, rump_sys_mkfifo(AFIFO, 0775) == -1); 160 FSTEST_EXIT(); 161 } 162 163 static void 164 createsymlink(const atf_tc_t *tc, const char *mp) 165 { 166 167 FSTEST_ENTER(); 168 ATF_REQUIRE_ERRNO(EROFS, rump_sys_symlink("hoge", ASYMLINK) == -1); 169 FSTEST_EXIT(); 170 } 171 172 static void 173 createlink(const atf_tc_t *tc, const char *mp) 174 { 175 176 FSTEST_ENTER(); 177 ATF_REQUIRE_ERRNO(EROFS, rump_sys_link(AFILE, ALINK) == -1); 178 FSTEST_EXIT(); 179 } 180 181 ATF_TC_FSAPPLY_RO(create, "create file on r/o mount", nullgen); 182 ATF_TC_FSAPPLY_RO(rmfile, "remove file from r/o mount", filegen); 183 ATF_TC_FSAPPLY_RO(fileio, "can read a file but not write it", filegen); 184 ATF_TC_FSAPPLY_RO(attrs, "can query but not change attributes", filegen); 185 ATF_TC_FSAPPLY_RO(createdir, "create directory on r/o mount", nullgen); 186 ATF_TC_FSAPPLY_RO(createfifo, "create fifo on r/o mount", nullgen); 187 ATF_TC_FSAPPLY_RO(createsymlink, "create symlink on r/o mount", nullgen); 188 ATF_TC_FSAPPLY_RO(createlink, "create hardlink on r/o mount", filegen); 189 190 ATF_TP_ADD_TCS(tp) 191 { 192 193 ATF_TP_FSAPPLY_RO(create); 194 ATF_TP_FSAPPLY_RO(rmfile); 195 ATF_TP_FSAPPLY_RO(fileio); 196 ATF_TP_FSAPPLY_RO(attrs); 197 ATF_TP_FSAPPLY_RO(createdir); 198 ATF_TP_FSAPPLY_RO(createfifo); 199 ATF_TP_FSAPPLY_RO(createsymlink); 200 ATF_TP_FSAPPLY_RO(createlink); 201 202 return atf_no_error(); 203 } 204