1 /* 2 * Copyright (c) 1999 Proofpoint, 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 <sys/time.h> 44 #include <time.h> 45 #include <errno.h> 46 #include <fcntl.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <unistd.h> 50 51 #ifndef lint 52 static char id[] = "@(#)$Id: t_exclopen.c,v 8.7 2013-11-22 20:52:01 ca Exp $"; 53 #endif 54 55 static char Attacker[128]; 56 static char Attackee[128]; 57 58 static void 59 bail(status) 60 int status; 61 { 62 (void) unlink(Attacker); 63 (void) unlink(Attackee); 64 exit(status); 65 } 66 67 int 68 main(argc, argv) 69 int argc; 70 char **argv; 71 { 72 struct stat st; 73 74 sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL)); 75 sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL)); 76 77 if (symlink(Attackee, Attacker) < 0) 78 { 79 printf("Could not create %s->%s symlink: %d\n", 80 Attacker, Attackee, errno); 81 bail(1); 82 } 83 (void) unlink(Attackee); 84 if (stat(Attackee, &st) >= 0) 85 { 86 printf("%s already exists -- remove and try again.\n", 87 Attackee); 88 bail(1); 89 } 90 if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0) 91 { 92 int save_errno = errno; 93 94 if (stat(Attackee, &st) >= 0) 95 { 96 printf("Weird. Open failed but %s was created anyhow (errno = %d)\n", 97 Attackee, save_errno); 98 bail(1); 99 } 100 printf("Good show! Exclusive open works properly with symbolic links (errno = %d).\n", 101 save_errno); 102 bail(0); 103 } 104 if (stat(Attackee, &st) < 0) 105 { 106 printf("Weird. Open succeeded but %s was not created\n", 107 Attackee); 108 bail(2); 109 } 110 printf("Bad news: you can do an exclusive open through a symbolic link\n"); 111 printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n"); 112 bail(1); 113 114 /* NOTREACHED */ 115 exit(0); 116 } 117