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 <fcntl.h>
0035 #include <errno.h>
0036 #include <string.h>
0037 #include <stdio.h>
0038 #include <stdlib.h>
0039 #include <stdint.h>
0040 #include <dirent.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[] = "FSPERMISSION " FILESYSTEM;
0048 const RTEMS_TEST_STATE rtems_test_state = TEST_STATE;
0049 
0050 /*
0051  *  Test the umask
0052  */
0053 static void umask_test01(void )
0054 {
0055 
0056   mode_t previous_cmask;
0057   mode_t tmp_mode;
0058   mode_t file_mode;
0059   struct stat statbuf;
0060   int status = 0;
0061   int fd;
0062 
0063   char* file01="file01";
0064   char* file02="file02";
0065   char* directory01="dir01";
0066 
0067   const char* wd=__func__;
0068 
0069   mode_t mode=S_IRWXU|S_IRWXG|S_IRWXO ;
0070 
0071 
0072 
0073   /*
0074    *Create a new directory and change the current directory to  this
0075    */
0076   status=mkdir(wd,mode);
0077   rtems_test_assert(status==0);
0078   status=chdir(wd);
0079   rtems_test_assert(status==0);
0080 
0081 /*
0082  *
0083  *  Call open creat and mkdir to create new files and directory
0084  */
0085   fd=open(file01,O_CREAT|O_RDWR,mode);
0086   status=close(fd);
0087   rtems_test_assert(status==0);
0088 
0089   fd=creat(file02,mode);
0090   status=close(fd);
0091   rtems_test_assert(status==0);
0092 
0093   status=mkdir(directory01,mode);
0094   rtems_test_assert(status==0);
0095 
0096 
0097   /*
0098    *Get the previous cmask and set it to a new one
0099    */
0100   previous_cmask = umask (0321);
0101   printf("The previous cmask is %03o\n",(unsigned int)previous_cmask);
0102   file_mode= mode & ~previous_cmask;
0103 
0104   status = stat (file01, &statbuf);
0105   rtems_test_assert (status == 0);
0106   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0107   printf("The file mode of %s is %03o\n",file01,(unsigned int)tmp_mode);
0108   rtems_test_assert(tmp_mode==file_mode);
0109 
0110 
0111   status = stat (file02, &statbuf);
0112   rtems_test_assert (status == 0);
0113   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0114   printf("The file mode of %s is %03o\n",file02,(unsigned int)tmp_mode);
0115   rtems_test_assert(tmp_mode==file_mode);
0116 
0117   status = stat (directory01, &statbuf);
0118   rtems_test_assert (status == 0);
0119   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0120   printf("The file mode of %s is %03o\n",directory01,(unsigned int)tmp_mode);
0121   rtems_test_assert(tmp_mode==file_mode);
0122 
0123   /*
0124    *Remove them and recreate them with the same mode
0125    */
0126 
0127   status=unlink(file01);
0128   rtems_test_assert(status==0);
0129   fd=open(file01,O_CREAT|O_RDWR,mode);
0130   status=close(fd);
0131   rtems_test_assert(status==0);
0132 
0133   status=unlink(file02);
0134   rtems_test_assert(status==0);
0135   fd=creat(file02,mode);
0136   status=close(fd);
0137   rtems_test_assert(status==0);
0138 
0139   status=rmdir(directory01);
0140   rtems_test_assert(status==0);
0141   status=mkdir(directory01,mode);
0142   rtems_test_assert(status==0);
0143 
0144   /*
0145    *Check the file mode
0146    */
0147 
0148   previous_cmask = umask (00);
0149   printf("The previous cmask is %03o\n",(unsigned int)previous_cmask);
0150   file_mode= mode & ~previous_cmask;
0151 
0152   status = stat (file01, &statbuf);
0153   rtems_test_assert (status == 0);
0154   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0155   printf("The file mode of %s is %03o\n",file01,(unsigned int)tmp_mode);
0156   rtems_test_assert(tmp_mode==file_mode);
0157 
0158 
0159   status = stat (file02, &statbuf);
0160   rtems_test_assert (status == 0);
0161   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0162   printf("The file mode of %s is %03o\n",file02,(unsigned int)tmp_mode);
0163   rtems_test_assert(tmp_mode==file_mode);
0164 
0165   status = stat (directory01, &statbuf);
0166   rtems_test_assert (status == 0);
0167   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0168   printf("The file mode of %s is %03o\n",directory01,(unsigned int)tmp_mode);
0169   rtems_test_assert(tmp_mode==file_mode);
0170 
0171   /*
0172    * Go back to parent directory
0173    */
0174   status=chdir("..");
0175   rtems_test_assert(status==0);
0176 
0177 }
0178 /*
0179  * Check the file mode in file and directory
0180  */
0181 static void test_permission01(void )
0182 {
0183   mode_t tmp_mode;
0184   struct stat statbuf;
0185   int status = 0;
0186   int fd;
0187 
0188   char* file01="file01";
0189   char* file02="file02";
0190   char* directory01="dir01";
0191 
0192   char path[20];
0193   char* test_data="Test Data";
0194   char* data_buf;
0195   size_t len=strlen(test_data);
0196 
0197   int n;
0198   DIR *dp;
0199 
0200   const char* wd=__func__;
0201 
0202   mode_t mode=S_IRWXU|S_IRWXG|S_IRWXO ;
0203   uid_t user_id =65534;
0204   gid_t group_id =65534;
0205 
0206   uid_t another_user_id =65533;
0207   gid_t another_group_id =65533;
0208 
0209 
0210   /*
0211    *Create a new directory and change the current directory to this
0212    */
0213   umask(00);
0214   status=mkdir(wd,mode);
0215   rtems_test_assert(status==0);
0216   status=chdir(wd);
0217   rtems_test_assert(status==0);
0218 
0219   status=seteuid(user_id);
0220   rtems_test_assert(status==0);
0221   status=setegid(group_id);
0222   rtems_test_assert(status==0);
0223 
0224 
0225   /*
0226    *Create a file with mode 0777
0227    */
0228   fd=creat(file01,mode);
0229   rtems_test_assert(fd >= 0);
0230   status=close(fd);
0231   rtems_test_assert(status==0);
0232   /*
0233    *Create a file with mode 0240
0234    */
0235 
0236   fd=creat(file02,0240);
0237   rtems_test_assert(fd >= 0);
0238   status=close(fd);
0239   rtems_test_assert(status==0);
0240 
0241 
0242   /*
0243    *Check the file mode uid and gid
0244    */
0245   status = stat (file01, &statbuf);
0246   rtems_test_assert (status == 0);
0247   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0248   printf("The file mode of %s is %03o\n",file01,(unsigned int)tmp_mode);
0249   rtems_test_assert(tmp_mode==mode);
0250   rtems_test_assert(statbuf.st_uid==user_id);
0251   rtems_test_assert(statbuf.st_gid==group_id);
0252 
0253   status = stat (file02, &statbuf);
0254   rtems_test_assert (status == 0);
0255   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0256   printf("The file mode of %s is %03o\n",file02,(unsigned int)tmp_mode);
0257   rtems_test_assert(tmp_mode==0240);
0258   rtems_test_assert(statbuf.st_uid==user_id);
0259   rtems_test_assert(statbuf.st_gid==group_id);
0260 
0261   /*
0262    * Create directory and a file in it for tese
0263    */
0264 
0265   status=mkdir(directory01,0777);
0266   rtems_test_assert(status==0);
0267   sprintf(path,"%s/%s",directory01,file01);
0268   fd = creat(path,0777);
0269   rtems_test_assert(fd >= 0);
0270   status = close(fd);
0271   rtems_test_assert(status == 0);
0272 
0273   status=chmod(directory01,0340);
0274   rtems_test_assert (status == 0);
0275   status = stat (directory01, &statbuf);
0276   rtems_test_assert (status == 0);
0277   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0278   printf("The file mode of %s is %03o\n",directory01,(unsigned int)tmp_mode);
0279   rtems_test_assert(tmp_mode==0340);
0280   rtems_test_assert(statbuf.st_uid==user_id);
0281   rtems_test_assert(statbuf.st_gid==group_id);
0282 
0283   /*
0284    * Check the file with open and write
0285    */
0286 
0287   /*
0288    * Test write
0289    */
0290   fd=open(file01,O_WRONLY);
0291   rtems_test_assert(fd >= 0);
0292   n=write(fd,test_data,len);
0293   rtems_test_assert(n==len);
0294   status=close(fd);
0295   rtems_test_assert(status==0);
0296 
0297   fd=open(file02,O_WRONLY);
0298   n=write(fd,test_data,len);
0299   rtems_test_assert(n==len);
0300   status=close(fd);
0301   rtems_test_assert(status==0);
0302 
0303   /*
0304    * Test read
0305    */
0306   data_buf=(char*)malloc(len+1);
0307   fd=open(file01,O_RDWR);
0308   rtems_test_assert(fd >= 0);
0309   n=read(fd,data_buf,len);
0310   rtems_test_assert(n==len);
0311   status=close(fd);
0312   rtems_test_assert(status==0);
0313 
0314   EXPECT_ERROR(EACCES,open,file02,O_RDONLY);
0315   EXPECT_ERROR(EACCES,open,file02,O_RDWR);
0316 
0317   /*
0318    * Test read directory
0319    */
0320   dp= opendir(directory01);
0321   rtems_test_assert(dp==NULL);
0322   rtems_test_assert(errno==EACCES);
0323 
0324   /*
0325    * Test write directory
0326    */
0327   status = lstat (path, &statbuf);
0328   rtems_test_assert (status == 0);
0329 
0330   status=unlink(path);
0331   rtems_test_assert(status==0);
0332 
0333 
0334   /*
0335    * Change euid and check
0336    */
0337   puts("Change euid and check");
0338   status=seteuid(0);
0339   rtems_test_assert(status==0);
0340 
0341   status=seteuid(another_user_id);
0342   rtems_test_assert(status==0);
0343 
0344   fd=open(file01,O_WRONLY);
0345   rtems_test_assert(fd >= 0);
0346   n=write(fd,test_data,len);
0347   rtems_test_assert(n==len);
0348   status=close(fd);
0349   rtems_test_assert(status==0);
0350 
0351   EXPECT_ERROR(EACCES,open,file02,O_WRONLY);
0352   EXPECT_ERROR(EACCES,open,file02,O_RDWR);
0353 
0354   /*
0355    * Test read directory
0356    */
0357   dp= opendir(directory01);
0358   rtems_test_assert(dp!=NULL);
0359   status=closedir(dp);
0360   rtems_test_assert(status==0);
0361 
0362   /*
0363    * Test write directory
0364    */
0365   EXPECT_ERROR(EACCES,creat,path,mode);
0366   EXPECT_ERROR(EACCES,rename,path,"test");
0367   EXPECT_ERROR(EACCES,truncate,path,0);
0368   EXPECT_ERROR(EACCES,link,path,"test");
0369   EXPECT_ERROR(EACCES,unlink,path);
0370   /*
0371    * Change egid and check
0372    */
0373   puts("Change egid and check");
0374   status=seteuid(0);
0375   rtems_test_assert(status==0);
0376 
0377   status=setegid(another_group_id);
0378   rtems_test_assert(status==0);
0379 
0380   status=seteuid(another_user_id);
0381   rtems_test_assert(status==0);
0382 
0383   EXPECT_ERROR(EACCES,open,file02,O_WRONLY);
0384   EXPECT_ERROR(EACCES,open,file02,O_RDONLY);
0385   EXPECT_ERROR(EACCES,open,file02,O_RDWR);
0386 
0387   /*
0388    * Test read directory
0389    */
0390   dp= opendir(directory01);
0391   rtems_test_assert(dp==NULL);
0392   rtems_test_assert(errno==EACCES);
0393 
0394    /*
0395    * Test write directory
0396    */
0397   EXPECT_ERROR(EACCES,creat,path,mode);
0398 
0399   /*
0400    * Go back to parent directory
0401    */
0402   status=seteuid(0);
0403   rtems_test_assert(status==0);
0404   status=setegid(0);
0405   rtems_test_assert(status==0);
0406   free(data_buf);
0407 
0408   status=chdir("..");
0409   rtems_test_assert(status==0);
0410 }
0411 
0412 /*
0413  * Test chown and chmod
0414  */
0415 static void  test_permission02(void )
0416 {
0417   struct stat statbuf;
0418   int status = 0;
0419   int fd;
0420 
0421   char* file01="file01";
0422   char* directory01="dir01";
0423 
0424   mode_t tmp_mode;
0425   mode_t file_mode=0321;
0426 
0427   const char* wd=__func__;
0428 
0429   mode_t mode=S_IRWXU|S_IRWXG|S_IRWXO ;
0430   uid_t user_id =65534;
0431   gid_t group_id =65534;
0432 
0433   /*
0434    *Create a new directory and change the current directory to  this
0435    */
0436   status=mkdir(wd,mode);
0437   rtems_test_assert(status==0);
0438   status=chdir(wd);
0439   rtems_test_assert(status==0);
0440 
0441   umask(00);
0442 
0443   fd=creat(file01,mode);
0444   status=close(fd);
0445   rtems_test_assert(status==0);
0446   status=stat(file01,&statbuf);
0447   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0448   rtems_test_assert(tmp_mode==mode);
0449 
0450   /*
0451    *Change the file mode uid and gid
0452    */
0453 
0454   status=chmod(file01,file_mode);
0455   rtems_test_assert(status==0);
0456   status=chown(file01,user_id,group_id);
0457   rtems_test_assert(status==0);
0458   status=stat(file01,&statbuf);
0459   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0460   rtems_test_assert(tmp_mode==file_mode);
0461   rtems_test_assert(user_id==statbuf.st_uid);
0462   rtems_test_assert(group_id==statbuf.st_gid);
0463 
0464   status = seteuid(user_id - 1);
0465   rtems_test_assert(status == 0);
0466 
0467   errno = 0;
0468   status = chown(file01, user_id, group_id);
0469   rtems_test_assert(status == -1);
0470   rtems_test_assert(errno == EPERM);
0471 
0472   status = seteuid(user_id);
0473   rtems_test_assert(status == 0);
0474 
0475   status = chown(file01, user_id, group_id);
0476   rtems_test_assert(status == 0);
0477 
0478   status = seteuid(0);
0479   rtems_test_assert(status == 0);
0480 
0481   status = chown(file01, user_id, group_id);
0482   rtems_test_assert(status == 0);
0483 
0484   status=mkdir(directory01,mode);
0485   rtems_test_assert(status==0);
0486   status=stat(directory01,&statbuf);
0487   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0488   printf("The directory file mode is %0o\n",(unsigned int)tmp_mode);
0489   rtems_test_assert(tmp_mode==mode);
0490 
0491   /*
0492    *Change the directory file mode
0493    */
0494   status=chmod(directory01,file_mode);
0495   rtems_test_assert(status==0);
0496   status=stat(directory01,&statbuf);
0497   tmp_mode = (statbuf.st_mode) & ALLPERMS;
0498   rtems_test_assert(tmp_mode==file_mode);
0499   printf("The directory file mode is %0o\n",(unsigned int)tmp_mode);
0500 
0501   /*
0502    * Go back to parent directory
0503    */
0504   status=chdir("..");
0505   rtems_test_assert(status==0);
0506 }
0507 static void root_test(void )
0508 {
0509   int fd;
0510   int sc;
0511 
0512   fd =creat("test",0000);
0513   sc=close(fd);
0514   rtems_test_assert(sc==0);
0515 
0516   fd=open("test",O_RDONLY);
0517   rtems_test_assert(fd==-1);
0518 }
0519 
0520 static void rename_search_permission_test (void)
0521 {
0522   int fd;
0523   int status;
0524   int rv;
0525 
0526   const char *name01 = "name01";
0527   const char *name02 = "name02";
0528 
0529   const char *dir01 = "dir01";
0530 
0531   char path01[20];
0532   char path02[20];
0533 
0534   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0535   mode_t no_execute_access = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
0536                            | S_IROTH | S_IWOTH;
0537 
0538   const char *wd = __func__;
0539 
0540   /*
0541    * Create a new directory and change the current directory to this
0542    */
0543 
0544   status = mkdir (wd, mode);
0545   rtems_test_assert (status == 0);
0546   status = chdir (wd);
0547   rtems_test_assert (status == 0);
0548 
0549   /*
0550    * The new argument points to a file and
0551    * the old argument points to another file,
0552    * both inside a directory with no execute permission.
0553    */
0554 
0555   puts ("\nRename two files on a directory with no execute permission \n");
0556 
0557   status = mkdir (dir01, mode);
0558   rtems_test_assert (status == 0);
0559 
0560   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name01);
0561   rtems_test_assert (rv < sizeof(path01));
0562   fd = creat (path01, mode);
0563   rtems_test_assert (fd >= 0);
0564   status = close (fd);
0565   rtems_test_assert (status == 0);
0566 
0567   rv = snprintf (path02, sizeof(path02), "%s/%s", dir01, name02);
0568   rtems_test_assert (rv < sizeof(path02));
0569   fd = creat (path02, mode);
0570   rtems_test_assert (fd >= 0);
0571   status = close (fd);
0572   rtems_test_assert (status == 0);
0573 
0574   status = chmod (dir01, no_execute_access);
0575   rtems_test_assert (status == 0);
0576 
0577   EXPECT_ERROR (EACCES, rename, path01 , path02);
0578 
0579   /*
0580    * Clear directory
0581    */
0582   status = chmod (dir01, mode);
0583   rtems_test_assert (status == 0);
0584 
0585   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name01);
0586   rtems_test_assert (rv < sizeof(path01));
0587   EXPECT_EQUAL (0, unlink, path01);
0588   EXPECT_EQUAL (0, unlink, path02);
0589   EXPECT_EQUAL (0, rmdir, dir01);
0590 
0591   /*
0592    * Go back to parent directory
0593    */
0594 
0595   status = chdir ("..");
0596   rtems_test_assert (status == 0);
0597 
0598   /*
0599    * Remove test directory
0600    */
0601 
0602   status = rmdir (wd);
0603   rtems_test_assert (status == 0);
0604 }
0605 
0606 void test(void )
0607 {
0608   umask_test01();
0609   test_permission01();
0610   test_permission02();
0611   root_test();
0612   rename_search_permission_test();
0613 }