1c2aa98e2SPeter Wemm /* 2*5dd76dd0SGregory Neil Shapiro * Copyright (c) 1999 Proofpoint, Inc. and its suppliers. 340266059SGregory Neil Shapiro * All rights reserved. 440266059SGregory Neil Shapiro * 540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 740266059SGregory Neil Shapiro * the sendmail distribution. 840266059SGregory Neil Shapiro * 940266059SGregory Neil Shapiro */ 1040266059SGregory Neil Shapiro 1140266059SGregory Neil Shapiro /* 12c2aa98e2SPeter Wemm ** This program tests your system to see if you have the lovely 13c2aa98e2SPeter Wemm ** security-defeating semantics that an open with O_CREAT|O_EXCL 14c2aa98e2SPeter Wemm ** set will successfully open a file named by a symbolic link that 15c2aa98e2SPeter Wemm ** points to a non-existent file. Sadly, Posix is mute on what 16c2aa98e2SPeter Wemm ** should happen in this situation. 17c2aa98e2SPeter Wemm ** 18c2aa98e2SPeter Wemm ** Results to date: 19c2aa98e2SPeter Wemm ** AIX 3.2 OK 20c2aa98e2SPeter Wemm ** BSD family OK 21c2aa98e2SPeter Wemm ** BSD/OS 2.1 OK 22c2aa98e2SPeter Wemm ** FreeBSD 2.1 OK 23c2aa98e2SPeter Wemm ** DEC OSF/1 3.0 OK 24c2aa98e2SPeter Wemm ** HP-UX 9.04 FAIL 25c2aa98e2SPeter Wemm ** HP-UX 9.05 FAIL 26c2aa98e2SPeter Wemm ** HP-UX 9.07 OK 27c2aa98e2SPeter Wemm ** HP-UX 10.01 OK 28c2aa98e2SPeter Wemm ** HP-UX 10.10 OK 29c2aa98e2SPeter Wemm ** HP-UX 10.20 OK 30c2aa98e2SPeter Wemm ** Irix 5.3 OK 31c2aa98e2SPeter Wemm ** Irix 6.2 OK 32c2aa98e2SPeter Wemm ** Irix 6.3 OK 33c2aa98e2SPeter Wemm ** Irix 6.4 OK 34c2aa98e2SPeter Wemm ** Linux OK 35c2aa98e2SPeter Wemm ** NeXT 2.1 OK 36c2aa98e2SPeter Wemm ** Solaris 2.x OK 37c2aa98e2SPeter Wemm ** SunOS 4.x OK 38c2aa98e2SPeter Wemm ** Ultrix 4.3 OK 39c2aa98e2SPeter Wemm */ 40c2aa98e2SPeter Wemm 41c2aa98e2SPeter Wemm #include <sys/types.h> 42c2aa98e2SPeter Wemm #include <sys/stat.h> 4306f25ae9SGregory Neil Shapiro #include <errno.h> 44c2aa98e2SPeter Wemm #include <fcntl.h> 4506f25ae9SGregory Neil Shapiro #include <stdio.h> 4606f25ae9SGregory Neil Shapiro #include <unistd.h> 47c2aa98e2SPeter Wemm 4806f25ae9SGregory Neil Shapiro #ifndef lint 49*5dd76dd0SGregory Neil Shapiro static char id[] = "@(#)$Id: t_exclopen.c,v 8.7 2013/11/22 20:52:01 ca Exp $"; 5006f25ae9SGregory Neil Shapiro #endif /* ! lint */ 51c2aa98e2SPeter Wemm 5206f25ae9SGregory Neil Shapiro static char Attacker[128]; 5306f25ae9SGregory Neil Shapiro static char Attackee[128]; 5406f25ae9SGregory Neil Shapiro 5506f25ae9SGregory Neil Shapiro static void 5606f25ae9SGregory Neil Shapiro bail(status) 5706f25ae9SGregory Neil Shapiro int status; 5806f25ae9SGregory Neil Shapiro { 5906f25ae9SGregory Neil Shapiro (void) unlink(Attacker); 6006f25ae9SGregory Neil Shapiro (void) unlink(Attackee); 6106f25ae9SGregory Neil Shapiro exit(status); 6206f25ae9SGregory Neil Shapiro } 6306f25ae9SGregory Neil Shapiro 6406f25ae9SGregory Neil Shapiro int 65c2aa98e2SPeter Wemm main(argc, argv) 66c2aa98e2SPeter Wemm int argc; 67c2aa98e2SPeter Wemm char **argv; 68c2aa98e2SPeter Wemm { 69c2aa98e2SPeter Wemm struct stat st; 70c2aa98e2SPeter Wemm 71c2aa98e2SPeter Wemm sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL)); 72c2aa98e2SPeter Wemm sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL)); 73c2aa98e2SPeter Wemm 74c2aa98e2SPeter Wemm if (symlink(Attackee, Attacker) < 0) 75c2aa98e2SPeter Wemm { 76c2aa98e2SPeter Wemm printf("Could not create %s->%s symlink: %d\n", 77c2aa98e2SPeter Wemm Attacker, Attackee, errno); 78c2aa98e2SPeter Wemm bail(1); 79c2aa98e2SPeter Wemm } 80c2aa98e2SPeter Wemm (void) unlink(Attackee); 81c2aa98e2SPeter Wemm if (stat(Attackee, &st) >= 0) 82c2aa98e2SPeter Wemm { 83c2aa98e2SPeter Wemm printf("%s already exists -- remove and try again.\n", 84c2aa98e2SPeter Wemm Attackee); 85c2aa98e2SPeter Wemm bail(1); 86c2aa98e2SPeter Wemm } 87c2aa98e2SPeter Wemm if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0) 88c2aa98e2SPeter Wemm { 8906f25ae9SGregory Neil Shapiro int save_errno = errno; 90c2aa98e2SPeter Wemm 91c2aa98e2SPeter Wemm if (stat(Attackee, &st) >= 0) 92c2aa98e2SPeter Wemm { 93c2aa98e2SPeter Wemm printf("Weird. Open failed but %s was created anyhow (errno = %d)\n", 9406f25ae9SGregory Neil Shapiro Attackee, save_errno); 95c2aa98e2SPeter Wemm bail(1); 96c2aa98e2SPeter Wemm } 97c2aa98e2SPeter Wemm printf("Good show! Exclusive open works properly with symbolic links (errno = %d).\n", 9806f25ae9SGregory Neil Shapiro save_errno); 99c2aa98e2SPeter Wemm bail(0); 100c2aa98e2SPeter Wemm } 101c2aa98e2SPeter Wemm if (stat(Attackee, &st) < 0) 102c2aa98e2SPeter Wemm { 103c2aa98e2SPeter Wemm printf("Weird. Open succeeded but %s was not created\n", 104c2aa98e2SPeter Wemm Attackee); 105c2aa98e2SPeter Wemm bail(2); 106c2aa98e2SPeter Wemm } 107c2aa98e2SPeter Wemm printf("Bad news: you can do an exclusive open through a symbolic link\n"); 108c2aa98e2SPeter Wemm printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n"); 109c2aa98e2SPeter Wemm bail(1); 110c2aa98e2SPeter Wemm 11106f25ae9SGregory Neil Shapiro /* NOTREACHED */ 11206f25ae9SGregory Neil Shapiro exit(0); 113c2aa98e2SPeter Wemm } 114