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
bail(status)59 bail(status)
60 int status;
61 {
62 (void) unlink(Attacker);
63 (void) unlink(Attackee);
64 exit(status);
65 }
66
67 int
main(argc,argv)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