138032Speter/* 2261363Sgshapiro * Copyright (c) 1999 Proofpoint, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro * 990792Sgshapiro */ 1090792Sgshapiro 1190792Sgshapiro/* 1238032Speter** This program tests your system to see if you have the lovely 1338032Speter** security-defeating semantics that an open with O_CREAT|O_EXCL 1438032Speter** set will successfully open a file named by a symbolic link that 1538032Speter** points to a non-existent file. Sadly, Posix is mute on what 1638032Speter** should happen in this situation. 1738032Speter** 1838032Speter** Results to date: 1938032Speter** AIX 3.2 OK 2038032Speter** BSD family OK 2138032Speter** BSD/OS 2.1 OK 2238032Speter** FreeBSD 2.1 OK 2338032Speter** DEC OSF/1 3.0 OK 2438032Speter** HP-UX 9.04 FAIL 2538032Speter** HP-UX 9.05 FAIL 2638032Speter** HP-UX 9.07 OK 2738032Speter** HP-UX 10.01 OK 2838032Speter** HP-UX 10.10 OK 2938032Speter** HP-UX 10.20 OK 3038032Speter** Irix 5.3 OK 3138032Speter** Irix 6.2 OK 3238032Speter** Irix 6.3 OK 3338032Speter** Irix 6.4 OK 3438032Speter** Linux OK 3538032Speter** NeXT 2.1 OK 3638032Speter** Solaris 2.x OK 3738032Speter** SunOS 4.x OK 3838032Speter** Ultrix 4.3 OK 3938032Speter*/ 4038032Speter 4138032Speter#include <sys/types.h> 4238032Speter#include <sys/stat.h> 4364562Sgshapiro#include <errno.h> 4438032Speter#include <fcntl.h> 4564562Sgshapiro#include <stdio.h> 4664562Sgshapiro#include <unistd.h> 4738032Speter 4864562Sgshapiro#ifndef lint 49266692Sgshapirostatic char id[] = "@(#)$Id: t_exclopen.c,v 8.7 2013-11-22 20:52:01 ca Exp $"; 5064562Sgshapiro#endif /* ! lint */ 5138032Speter 5264562Sgshapirostatic char Attacker[128]; 5364562Sgshapirostatic char Attackee[128]; 5464562Sgshapiro 5564562Sgshapirostatic void 5664562Sgshapirobail(status) 5764562Sgshapiro int status; 5864562Sgshapiro{ 5964562Sgshapiro (void) unlink(Attacker); 6064562Sgshapiro (void) unlink(Attackee); 6164562Sgshapiro exit(status); 6264562Sgshapiro} 6364562Sgshapiro 6464562Sgshapiroint 6538032Spetermain(argc, argv) 6638032Speter int argc; 6738032Speter char **argv; 6838032Speter{ 6938032Speter struct stat st; 7038032Speter 7138032Speter sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL)); 7238032Speter sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL)); 7338032Speter 7438032Speter if (symlink(Attackee, Attacker) < 0) 7538032Speter { 7638032Speter printf("Could not create %s->%s symlink: %d\n", 7738032Speter Attacker, Attackee, errno); 7838032Speter bail(1); 7938032Speter } 8038032Speter (void) unlink(Attackee); 8138032Speter if (stat(Attackee, &st) >= 0) 8238032Speter { 8338032Speter printf("%s already exists -- remove and try again.\n", 8438032Speter Attackee); 8538032Speter bail(1); 8638032Speter } 8738032Speter if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0) 8838032Speter { 8964562Sgshapiro int save_errno = errno; 9038032Speter 9138032Speter if (stat(Attackee, &st) >= 0) 9238032Speter { 9338032Speter printf("Weird. Open failed but %s was created anyhow (errno = %d)\n", 9464562Sgshapiro Attackee, save_errno); 9538032Speter bail(1); 9638032Speter } 9738032Speter printf("Good show! Exclusive open works properly with symbolic links (errno = %d).\n", 9864562Sgshapiro save_errno); 9938032Speter bail(0); 10038032Speter } 10138032Speter if (stat(Attackee, &st) < 0) 10238032Speter { 10338032Speter printf("Weird. Open succeeded but %s was not created\n", 10438032Speter Attackee); 10538032Speter bail(2); 10638032Speter } 10738032Speter printf("Bad news: you can do an exclusive open through a symbolic link\n"); 10838032Speter printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n"); 10938032Speter bail(1); 11038032Speter 11164562Sgshapiro /* NOTREACHED */ 11264562Sgshapiro exit(0); 11338032Speter} 114