1c2aa98e2SPeter Wemm /* 2c2aa98e2SPeter Wemm ** This program tests your system to see if you have the lovely 3c2aa98e2SPeter Wemm ** security-defeating semantics that an open with O_CREAT|O_EXCL 4c2aa98e2SPeter Wemm ** set will successfully open a file named by a symbolic link that 5c2aa98e2SPeter Wemm ** points to a non-existent file. Sadly, Posix is mute on what 6c2aa98e2SPeter Wemm ** should happen in this situation. 7c2aa98e2SPeter Wemm ** 8c2aa98e2SPeter Wemm ** Results to date: 9c2aa98e2SPeter Wemm ** AIX 3.2 OK 10c2aa98e2SPeter Wemm ** BSD family OK 11c2aa98e2SPeter Wemm ** BSD/OS 2.1 OK 12c2aa98e2SPeter Wemm ** FreeBSD 2.1 OK 13c2aa98e2SPeter Wemm ** DEC OSF/1 3.0 OK 14c2aa98e2SPeter Wemm ** HP-UX 9.04 FAIL 15c2aa98e2SPeter Wemm ** HP-UX 9.05 FAIL 16c2aa98e2SPeter Wemm ** HP-UX 9.07 OK 17c2aa98e2SPeter Wemm ** HP-UX 10.01 OK 18c2aa98e2SPeter Wemm ** HP-UX 10.10 OK 19c2aa98e2SPeter Wemm ** HP-UX 10.20 OK 20c2aa98e2SPeter Wemm ** Irix 5.3 OK 21c2aa98e2SPeter Wemm ** Irix 6.2 OK 22c2aa98e2SPeter Wemm ** Irix 6.3 OK 23c2aa98e2SPeter Wemm ** Irix 6.4 OK 24c2aa98e2SPeter Wemm ** Linux OK 25c2aa98e2SPeter Wemm ** NeXT 2.1 OK 26c2aa98e2SPeter Wemm ** Solaris 2.x OK 27c2aa98e2SPeter Wemm ** SunOS 4.x OK 28c2aa98e2SPeter Wemm ** Ultrix 4.3 OK 29c2aa98e2SPeter Wemm */ 30c2aa98e2SPeter Wemm 31c2aa98e2SPeter Wemm #include <sys/types.h> 32c2aa98e2SPeter Wemm #include <sys/stat.h> 3306f25ae9SGregory Neil Shapiro #include <errno.h> 34c2aa98e2SPeter Wemm #include <fcntl.h> 3506f25ae9SGregory Neil Shapiro #include <stdio.h> 3606f25ae9SGregory Neil Shapiro #include <unistd.h> 37c2aa98e2SPeter Wemm 3806f25ae9SGregory Neil Shapiro #ifndef lint 3906f25ae9SGregory Neil Shapiro static char id[] = "@(#)$Id: t_exclopen.c,v 8.5 1999/08/28 00:25:28 gshapiro Exp $"; 4006f25ae9SGregory Neil Shapiro #endif /* ! lint */ 41c2aa98e2SPeter Wemm 4206f25ae9SGregory Neil Shapiro static char Attacker[128]; 4306f25ae9SGregory Neil Shapiro static char Attackee[128]; 4406f25ae9SGregory Neil Shapiro 4506f25ae9SGregory Neil Shapiro static void 4606f25ae9SGregory Neil Shapiro bail(status) 4706f25ae9SGregory Neil Shapiro int status; 4806f25ae9SGregory Neil Shapiro { 4906f25ae9SGregory Neil Shapiro (void) unlink(Attacker); 5006f25ae9SGregory Neil Shapiro (void) unlink(Attackee); 5106f25ae9SGregory Neil Shapiro exit(status); 5206f25ae9SGregory Neil Shapiro } 5306f25ae9SGregory Neil Shapiro 5406f25ae9SGregory Neil Shapiro int 55c2aa98e2SPeter Wemm main(argc, argv) 56c2aa98e2SPeter Wemm int argc; 57c2aa98e2SPeter Wemm char **argv; 58c2aa98e2SPeter Wemm { 59c2aa98e2SPeter Wemm struct stat st; 60c2aa98e2SPeter Wemm 61c2aa98e2SPeter Wemm sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL)); 62c2aa98e2SPeter Wemm sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL)); 63c2aa98e2SPeter Wemm 64c2aa98e2SPeter Wemm if (symlink(Attackee, Attacker) < 0) 65c2aa98e2SPeter Wemm { 66c2aa98e2SPeter Wemm printf("Could not create %s->%s symlink: %d\n", 67c2aa98e2SPeter Wemm Attacker, Attackee, errno); 68c2aa98e2SPeter Wemm bail(1); 69c2aa98e2SPeter Wemm } 70c2aa98e2SPeter Wemm (void) unlink(Attackee); 71c2aa98e2SPeter Wemm if (stat(Attackee, &st) >= 0) 72c2aa98e2SPeter Wemm { 73c2aa98e2SPeter Wemm printf("%s already exists -- remove and try again.\n", 74c2aa98e2SPeter Wemm Attackee); 75c2aa98e2SPeter Wemm bail(1); 76c2aa98e2SPeter Wemm } 77c2aa98e2SPeter Wemm if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0) 78c2aa98e2SPeter Wemm { 7906f25ae9SGregory Neil Shapiro int save_errno = errno; 80c2aa98e2SPeter Wemm 81c2aa98e2SPeter Wemm if (stat(Attackee, &st) >= 0) 82c2aa98e2SPeter Wemm { 83c2aa98e2SPeter Wemm printf("Weird. Open failed but %s was created anyhow (errno = %d)\n", 8406f25ae9SGregory Neil Shapiro Attackee, save_errno); 85c2aa98e2SPeter Wemm bail(1); 86c2aa98e2SPeter Wemm } 87c2aa98e2SPeter Wemm printf("Good show! Exclusive open works properly with symbolic links (errno = %d).\n", 8806f25ae9SGregory Neil Shapiro save_errno); 89c2aa98e2SPeter Wemm bail(0); 90c2aa98e2SPeter Wemm } 91c2aa98e2SPeter Wemm if (stat(Attackee, &st) < 0) 92c2aa98e2SPeter Wemm { 93c2aa98e2SPeter Wemm printf("Weird. Open succeeded but %s was not created\n", 94c2aa98e2SPeter Wemm Attackee); 95c2aa98e2SPeter Wemm bail(2); 96c2aa98e2SPeter Wemm } 97c2aa98e2SPeter Wemm printf("Bad news: you can do an exclusive open through a symbolic link\n"); 98c2aa98e2SPeter Wemm printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n"); 99c2aa98e2SPeter Wemm bail(1); 100c2aa98e2SPeter Wemm 10106f25ae9SGregory Neil Shapiro /* NOTREACHED */ 10206f25ae9SGregory Neil Shapiro exit(0); 103c2aa98e2SPeter Wemm } 104