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