test11.c

Go to the documentation of this file.
00001 /* test 11 */
00002 
00003 #include <sys/types.h>
00004 #include <sys/stat.h>
00005 #include <sys/wait.h>
00006 #include <errno.h>
00007 #include <fcntl.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <unistd.h>
00011 #include <stdio.h>
00012 
00013 #define ITERATIONS 10
00014 #define MAX_ERROR 1
00015 
00016 int errct, subtest;
00017 char *envp[3] = {"spring", "summer", 0};
00018 char *passwd_file = "/etc/passwd";
00019 
00020 _PROTOTYPE(int main, (int argc, char *argv[]));
00021 _PROTOTYPE(void test11a, (void));
00022 _PROTOTYPE(void test11b, (void));
00023 _PROTOTYPE(void test11c, (void));
00024 _PROTOTYPE(void test11d, (void));
00025 _PROTOTYPE(void e, (int n));
00026 
00027 int main(argc, argv)
00028 int argc;
00029 char *argv[];
00030 {
00031   int i, m = 0xFFFF;
00032 
00033   if (argc == 2) m = atoi(argv[1]);
00034 
00035   printf("Test 11 ");
00036   fflush(stdout);               /* have to flush for child's benefit */
00037 
00038   if (geteuid() != 0) {
00039         printf("must be setuid root; test aborted\n");
00040         exit(1);
00041   }
00042   if (getuid() == 0) {
00043        printf("must be setuid root logged in as someone else; test aborted\n");
00044        exit(1);
00045   }
00046 
00047 /*
00048   system("rm -rf DIR_11; mkdir DIR_11");
00049   chdir("DIR_11");
00050 */
00051 
00052   for (i = 0; i < ITERATIONS; i++) {
00053         if (m & 0001) test11a();
00054         if (m & 0002) test11b();
00055         if (m & 0004) test11c();
00056         if (m & 0010) test11d();
00057   }
00058   if (errct == 0)
00059         printf("ok\n");
00060   else
00061         printf(" %d errors\n", errct);
00062 
00063 /*
00064   chdir("..");
00065   system("rm -rf DIR_11");
00066 */
00067   return(0);
00068 }
00069 
00070 void test11a()
00071 {
00072 /* Test exec */
00073   int n, fd;
00074   char aa[4];
00075 
00076   subtest = 1;
00077 
00078   if (fork()) {
00079         wait(&n);
00080         if (n != 25600) e(1);
00081         unlink("t1");
00082         unlink("t2");
00083   } else {
00084         if (chown("t11a", 10, 20) < 0) e(2);
00085         chmod("t11a", 0666);
00086 
00087         /* The following call should fail because the mode has no X
00088          * bits on. If a bug lets it unexpectedly succeed, the child
00089          * will print an error message since the arguments are wrong.
00090          */
00091         execl("t11a", (char *) 0, envp);        /* should fail -- no X bits */
00092 
00093         /* Control should come here after the failed execl(). */
00094         chmod("t11a", 06555);
00095         if ((fd = creat("t1", 0600)) != 3) e(3);
00096         if (close(fd) < 0) e(4);
00097         if (open("t1", O_RDWR) != 3) e(5);
00098         if (chown("t1", 10, 99) < 0) e(6);
00099         if ((fd = creat("t2", 0060)) != 4) e(7);
00100         if (close(fd) < 0) e(8);
00101         if (open("t2", O_RDWR) != 4) e(9);
00102         if (chown("t2", 99, 20) < 0) e(10);
00103         if (setgid(6) < 0) e(11);
00104         if (setuid(5) < 0) e(12);
00105         if (getuid() != 5) e(13);
00106         if (geteuid() != 5) e(14);
00107         if (getgid() != 6) e(15);
00108         if (getegid() != 6) e(16);
00109         aa[0] = 3;
00110         aa[1] = 5;
00111         aa[2] = 7;
00112         aa[3] = 9;
00113         if (write(3, aa, 4) != 4) e(17);
00114         lseek(3, 2L, 0);
00115         execle("t11a", "t11a", "arg0", "arg1", "arg2", (char *) 0, envp);
00116         e(18);
00117         printf("Can't exec t11a\n");
00118         exit(3);
00119   }
00120 }
00121 
00122 void test11b()
00123 {
00124   int n;
00125   char *argv[5];
00126 
00127   subtest = 2;
00128   if (fork()) {
00129         wait(&n);
00130         if (n != (75 << 8)) e(20);
00131   } else {
00132         /* Child tests execv. */
00133         argv[0] = "t11b";
00134         argv[1] = "abc";
00135         argv[2] = "defghi";
00136         argv[3] = "j";
00137         argv[4] = 0;
00138         execv("t11b", argv);
00139         e(19);
00140   }
00141 }
00142 
00143 void test11c()
00144 {
00145 /* Test getlogin() and cuserid().  This test  MUST run setuid root. */
00146 
00147   int n, etc_uid;
00148   uid_t ruid, euid;
00149   char *lnamep, *cnamep, *p;
00150   char array[L_cuserid], save[L_cuserid], save2[L_cuserid];
00151   FILE *stream;
00152 
00153   subtest = 3;
00154   errno = -2000;                /* None of these calls set errno. */
00155   array[0] = '@';
00156   array[1] = '0';
00157   save[0] = '#';
00158   save[1] = '0';
00159   ruid = getuid();
00160   euid = geteuid();
00161   lnamep = getlogin();
00162   strcpy(save, lnamep);
00163   cnamep = cuserid(array);
00164   strcpy(save2, cnamep);
00165 
00166   /* Because we are setuid root, cuser == array == 'root';  login != 'root' */
00167   if (euid != 0) e(1);
00168   if (ruid == 0) e(2);
00169   if (strcmp(cnamep, "root") != 0) e(3);
00170   if (strcmp(array, "root") != 0) e(4);
00171   if ( (n = strlen(save)) == 0) e(5);
00172   if (strcmp(save, cnamep) == 0) e(6);          /* they must be different */
00173   cnamep = cuserid(NULL);
00174   if (strcmp(cnamep, save2) != 0) e(7);
00175 
00176   /* Check login against passwd file. First lookup login in /etc/passwd. */
00177   if (n == 0) return;           /* if login not found, don't look it up */
00178   if ( (stream = fopen(passwd_file, "r")) == NULL) e(8);
00179   while (fgets(array, L_cuserid, stream) != NULL) {
00180         if (strncmp(array, save, n) == 0) {
00181                 p = &array[0];          /* hunt for uid */
00182                 while (*p != ':') p++;
00183                 p++;
00184                 while (*p != ':') p++;
00185                 p++;                    /* p now points to uid */
00186                 etc_uid = atoi(p);
00187                 if (etc_uid != ruid) e(9);
00188                 break;                  /* 1 entry per login please */
00189         }
00190   }
00191   fclose(stream);
00192 }
00193 
00194 void test11d()
00195 {
00196   int fd;
00197   struct stat statbuf;
00198 
00199   subtest = 4;
00200   fd = creat("T11.1", 0750);
00201   if (fd < 0) e(1);
00202   if (chown("T11.1", 8, 1) != 0) e(2);
00203   if (chmod("T11.1", 0666) != 0) e(3);
00204   if (stat("T11.1", &statbuf) != 0) e(4);
00205   if ((statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0666) e(5);
00206   if (close(fd) != 0) e(6);
00207   if (unlink("T11.1") != 0) e(7);
00208 }
00209 
00210 void e(n)
00211 int n;
00212 {
00213   int err_num = errno;          /* save errno in case printf clobbers it */
00214 
00215   printf("Subtest %d,  error %d  errno=%d  ", subtest, n, errno);
00216   errno = err_num;              /* restore errno, just in case */
00217   perror("");
00218   if (errct++ > MAX_ERROR) {
00219         printf("Too many errors; test aborted\n");
00220         chdir("..");
00221         system("rm -rf DIR*");
00222         exit(1);
00223   }
00224 }

Generated on Fri Apr 14 22:57:32 2006 for minix by  doxygen 1.4.6