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