Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:31

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2011.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #include <sys/stat.h>
0034 #include <limits.h>
0035 #include <fcntl.h>
0036 #include <errno.h>
0037 #include <stdio.h>
0038 #include <stdint.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <unistd.h>
0042 
0043 #include "fstest.h"
0044 #include "fs_config.h"
0045 #include <tmacros.h>
0046 
0047 const char rtems_test_name[] = "FSRENAMEPERMEXISTING " FILESYSTEM;
0048 const RTEMS_TEST_STATE rtems_test_state = TEST_STATE;
0049 
0050 static void rename_write_permission_test (void)
0051 {
0052   int fd;
0053   int status;
0054   int rv;
0055 
0056   const char *name01 = "name01";
0057   const char *name02 = "name02";
0058 
0059   const char *dir01 = "dir01";
0060   const char *dir02 = "dir02";
0061 
0062   char path01[20];
0063 
0064   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0065   mode_t no_write_access = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP
0066                          | S_IROTH | S_IXOTH;
0067 
0068   const char *wd = __func__;
0069 
0070   /*
0071    * Create a new directory and change the current directory to this
0072    */
0073 
0074   status = mkdir (wd, mode);
0075   rtems_test_assert (status == 0);
0076   status = chdir (wd);
0077   rtems_test_assert (status == 0);
0078 
0079   /*
0080    * The new argument points to a file and
0081    * the old argument points to another file,
0082    * both inside a directory with no write permission.
0083    */
0084 
0085   puts ("\nRename two files on a directory with no write permission \n");
0086 
0087   status = mkdir (dir01, mode);
0088   rtems_test_assert (status == 0);
0089 
0090   status = chdir (dir01);
0091   rtems_test_assert (status == 0);
0092 
0093   fd = creat (name01, mode);
0094   rtems_test_assert (fd >= 0);
0095   status = close (fd);
0096   rtems_test_assert (status == 0);
0097 
0098   fd = creat (name02, mode);
0099   rtems_test_assert (fd >= 0);
0100   status = close (fd);
0101   rtems_test_assert (status == 0);
0102 
0103   status = chmod (".", no_write_access);
0104   rtems_test_assert (status == 0);
0105 
0106   EXPECT_ERROR (EACCES, rename, name01 , name02);
0107 
0108   status = chdir ("..");
0109   rtems_test_assert (status == 0);
0110 
0111   /*
0112    * The new argument points to a file in a directory with no write access and
0113    * the old argument points to another file on a directory with write access.
0114    */
0115 
0116   puts ("\nRename file between two directories, with and without write access\n");
0117 
0118   status = mkdir (dir02, mode);
0119   rtems_test_assert (status == 0);
0120 
0121   status = chdir (dir02);
0122   rtems_test_assert (status == 0);
0123 
0124   fd = creat (name01, mode);
0125   rtems_test_assert (fd >= 0);
0126   status = close (fd);
0127   rtems_test_assert (status == 0);
0128 
0129   rv = snprintf (path01, sizeof(path01), "../%s/%s", dir01, name02);
0130   rtems_test_assert (rv < sizeof(path01));
0131   EXPECT_ERROR (EACCES, rename, name01, path01);
0132 
0133   /*
0134    * The new argument points to a file in a directory with write access and
0135    * the old argument points to another file on a directory without write access.
0136    */
0137 
0138   EXPECT_ERROR (EACCES, rename, path01, name01);
0139 
0140   /*
0141    * Clear directory
0142    */
0143 
0144   EXPECT_EQUAL (0, unlink, name01);
0145 
0146   rv = snprintf (path01, sizeof(path01), "../%s", dir01);
0147   rtems_test_assert (rv < sizeof(path01));
0148   status = chmod (path01, mode);
0149   rtems_test_assert (status == 0);
0150 
0151   rv = snprintf (path01, sizeof(path01), "../%s/%s", dir01, name01);
0152   rtems_test_assert (rv < sizeof(path01));
0153   EXPECT_EQUAL (0, unlink, path01);
0154 
0155   rv = snprintf (path01, sizeof(path01), "../%s/%s", dir01, name02);
0156   rtems_test_assert (rv < sizeof(path01));
0157   EXPECT_EQUAL (0, unlink, path01);
0158 
0159   status = chdir ("..");
0160   rtems_test_assert (status == 0);
0161 
0162   EXPECT_EQUAL (0, rmdir, dir01);
0163   EXPECT_EQUAL (0, rmdir, dir02);
0164 
0165   /*
0166    * Go back to parent directory
0167    */
0168 
0169   status = chdir ("..");
0170   rtems_test_assert (status == 0);
0171 
0172   /*
0173    * Remove test directory
0174    */
0175 
0176   status = rmdir (wd);
0177   rtems_test_assert (status == 0);
0178 }
0179 
0180 static void rename_search_permission_test (void)
0181 {
0182   int fd;
0183   int status;
0184   int rv;
0185 
0186   const char *name01 = "name01";
0187   const char *name02 = "name02";
0188 
0189   const char *dir01 = "dir01";
0190   const char *dir02 = "dir02";
0191 
0192   char path01[20];
0193   char path02[20];
0194 
0195   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0196   mode_t no_execute_access = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
0197                            | S_IROTH | S_IWOTH;
0198 
0199   const char *wd = __func__;
0200 
0201   /*
0202    * Create a new directory and change the current directory to this
0203    */
0204 
0205   status = mkdir (wd, mode);
0206   rtems_test_assert (status == 0);
0207   status = chdir (wd);
0208   rtems_test_assert (status == 0);
0209 
0210   /*
0211    * The new argument points to a file in a directory with no execute access and
0212    * the old argument points to another file on a directory with execute access.
0213    */
0214 
0215   puts ("\nRename file between two directories, with and without execute access\n");
0216 
0217   status = mkdir (dir01, mode);
0218   rtems_test_assert (status == 0);
0219 
0220   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name01);
0221   rtems_test_assert (rv < sizeof(path01));
0222   fd = creat (path01, mode);
0223   rtems_test_assert (fd >= 0);
0224   status = close (fd);
0225   rtems_test_assert (status == 0);
0226 
0227   rv = snprintf (path02, sizeof(path02), "%s/%s", dir01, name02);
0228   rtems_test_assert (rv < sizeof(path02));
0229   fd = creat (path02, mode);
0230   rtems_test_assert (fd >= 0);
0231   status = close (fd);
0232   rtems_test_assert (status == 0);
0233 
0234   status = chmod (dir01, no_execute_access);
0235   rtems_test_assert (status == 0);
0236 
0237   status = mkdir (dir02, mode);
0238   rtems_test_assert (status == 0);
0239 
0240   status = chdir (dir02);
0241   rtems_test_assert (status == 0);
0242 
0243   fd = creat (name01, mode);
0244   rtems_test_assert (fd >= 0);
0245   status = close (fd);
0246   rtems_test_assert (status == 0);
0247 
0248   status = chdir ("..");
0249   rtems_test_assert (status == 0);
0250 
0251   rv = snprintf (path01, sizeof(path01), "%s/%s", dir02, name01);
0252   rtems_test_assert (rv < sizeof(path01));
0253   EXPECT_ERROR (EACCES, rename, path01, path02);
0254 
0255   /*
0256    * The new argument points to a file in a directory with execute access and
0257    * the old argument points to another file on a directory without execute access.
0258    */
0259 
0260   EXPECT_ERROR (EACCES, rename, path02, path01);
0261 
0262   /*
0263    * Clear directory
0264    */
0265 
0266   EXPECT_EQUAL (0, unlink, path01);
0267 
0268   status = chmod (dir01, mode);
0269   rtems_test_assert (status == 0);
0270 
0271   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name01);
0272   rtems_test_assert (rv < sizeof(path01));
0273   EXPECT_EQUAL (0, unlink, path01);
0274   EXPECT_EQUAL (0, unlink, path02);
0275   EXPECT_EQUAL (0, rmdir, dir01);
0276   EXPECT_EQUAL (0, rmdir, dir02);
0277 
0278   /*
0279    * Go back to parent directory
0280    */
0281 
0282   status = chdir ("..");
0283   rtems_test_assert (status == 0);
0284 
0285   /*
0286    * Remove test directory
0287    */
0288 
0289   status = rmdir (wd);
0290   rtems_test_assert (status == 0);
0291 }
0292 
0293 static void rename_permission03 (void)
0294 {
0295   int fd;
0296   int status;
0297   int rv;
0298 
0299   const char *name01 = "name01";
0300   const char *name02 = "name02";
0301 
0302   const char *dir01 = "dir01";
0303 
0304   char path01[30];
0305 
0306   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0307   const char *wd = __func__;
0308 
0309   /*
0310    * Create a new directory and change the current directory to this
0311    */
0312 
0313   status = mkdir (wd, mode);
0314   rtems_test_assert (status == 0);
0315   status = chdir (wd);
0316   rtems_test_assert (status == 0);
0317 
0318   /*
0319    * The new argument points to a file and
0320    * the old argument points to another file on a directory with S_ISVTX.
0321    */
0322 
0323   puts ("\nRename files within directories protected with S_ISVTX\n");
0324 
0325   status = mkdir (dir01, mode | S_ISVTX);
0326   rtems_test_assert (status == 0);
0327 
0328   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name01);
0329   rtems_test_assert (rv < sizeof(path01));
0330   fd = creat (path01, mode);
0331   rtems_test_assert (fd >= 0);
0332   status = close (fd);
0333   rtems_test_assert (status == 0);
0334 
0335   fd = creat (name02, mode);
0336   rtems_test_assert (fd >= 0);
0337   status = close (fd);
0338   rtems_test_assert (status == 0);
0339 
0340   status = chown (path01, 65534, -1);
0341   rtems_test_assert (status == 0);
0342 
0343   status = chown (dir01, 65534, -1);
0344   rtems_test_assert (status == 0);
0345 
0346   EXPECT_EQUAL (-1, rename, path01, name02);
0347 
0348   puts("Testing errno for EPERM or EACCES");
0349 
0350   if (errno == EPERM || errno == EACCES) {
0351     FS_PASS ();
0352   } else {
0353     FS_FAIL ();
0354   }
0355 
0356   /*
0357    * Clear directory
0358    */
0359 
0360   EXPECT_EQUAL (0, unlink, path01);
0361   EXPECT_EQUAL (0, unlink, name02);
0362   EXPECT_EQUAL (0, rmdir, dir01);
0363 
0364   /*
0365    * The new argument points to a file on a directory with S_ISVTX and
0366    * the old argument points to a file outside that directory.
0367    */
0368 
0369   status = mkdir (dir01, mode | S_ISVTX);
0370   rtems_test_assert (status == 0);
0371 
0372   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name01);
0373   rtems_test_assert (rv < sizeof(path01));
0374   fd = creat (path01, mode);
0375   rtems_test_assert (fd >= 0);
0376   status = close (fd);
0377   rtems_test_assert (status == 0);
0378 
0379   fd = creat (name02, mode);
0380   rtems_test_assert (fd >= 0);
0381   status = close (fd);
0382   rtems_test_assert (status == 0);
0383 
0384   status = chown (path01, 65534, -1);
0385   rtems_test_assert (status == 0);
0386 
0387   status = chown (dir01, 65534, -1);
0388   rtems_test_assert (status == 0);
0389 
0390   EXPECT_EQUAL (-1, rename, name02, path01);
0391 
0392   puts("Testing errno for EPERM or EACCES");
0393 
0394   if (errno == EPERM || errno == EACCES) {
0395     FS_PASS ();
0396   } else {
0397     FS_FAIL ();
0398   }
0399 
0400   /*
0401    * Clear directory
0402    */
0403 
0404   EXPECT_EQUAL (0, unlink, path01);
0405   EXPECT_EQUAL (0, unlink, name02);
0406   EXPECT_EQUAL (0, rmdir, dir01);
0407 
0408   /*
0409    * Go back to parent directory
0410    */
0411 
0412   status = chdir ("..");
0413   rtems_test_assert (status == 0);
0414 
0415   /*
0416    * Remove test directory
0417    */
0418 
0419   status = rmdir (wd);
0420   rtems_test_assert (status == 0);
0421 }
0422 
0423 void test (void)
0424 {
0425   rename_write_permission_test ();
0426   rename_search_permission_test ();
0427   rename_permission03 ();
0428 }