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 <errno.h> 44#include <fcntl.h> 45#include <stdio.h> 46#include <unistd.h> 47 48#ifndef lint 49static char id[] = "@(#)$Id: t_exclopen.c,v 8.7 2013-11-22 20:52:01 ca Exp $"; 50#endif /* ! lint */ 51 52static char Attacker[128]; 53static char Attackee[128]; 54 55static void 56bail(status) 57 int status; 58{ 59 (void) unlink(Attacker); 60 (void) unlink(Attackee); 61 exit(status); 62} 63 64int 65main(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