t_exclopen.c revision 38032
138032Speter/*
238032Speter**  This program tests your system to see if you have the lovely
338032Speter**  security-defeating semantics that an open with O_CREAT|O_EXCL
438032Speter**  set will successfully open a file named by a symbolic link that
538032Speter**  points to a non-existent file.  Sadly, Posix is mute on what
638032Speter**  should happen in this situation.
738032Speter**
838032Speter**  Results to date:
938032Speter**	AIX 3.2		OK
1038032Speter**	BSD family	OK
1138032Speter**	  BSD/OS 2.1	OK
1238032Speter**	  FreeBSD 2.1	OK
1338032Speter**	DEC OSF/1 3.0	OK
1438032Speter**	HP-UX 9.04	FAIL
1538032Speter**	HP-UX 9.05	FAIL
1638032Speter**	HP-UX 9.07	OK
1738032Speter**	HP-UX 10.01	OK
1838032Speter**	HP-UX 10.10	OK
1938032Speter**	HP-UX 10.20	OK
2038032Speter**	Irix 5.3	OK
2138032Speter**	Irix 6.2	OK
2238032Speter**	Irix 6.3	OK
2338032Speter**	Irix 6.4	OK
2438032Speter**	Linux		OK
2538032Speter**	NeXT 2.1	OK
2638032Speter**	Solaris 2.x	OK
2738032Speter**	SunOS 4.x	OK
2838032Speter**	Ultrix 4.3	OK
2938032Speter*/
3038032Speter
3138032Speter#include <stdio.h>
3238032Speter#include <errno.h>
3338032Speter#include <sys/types.h>
3438032Speter#include <sys/stat.h>
3538032Speter#include <fcntl.h>
3638032Speter
3738032Speterchar Attacker[128];
3838032Speterchar Attackee[128];
3938032Speter
4038032Spetermain(argc, argv)
4138032Speter	int argc;
4238032Speter	char **argv;
4338032Speter{
4438032Speter	struct stat st;
4538032Speter
4638032Speter	sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL));
4738032Speter	sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL));
4838032Speter
4938032Speter	if (symlink(Attackee, Attacker) < 0)
5038032Speter	{
5138032Speter		printf("Could not create %s->%s symlink: %d\n",
5238032Speter			Attacker, Attackee, errno);
5338032Speter		bail(1);
5438032Speter	}
5538032Speter	(void) unlink(Attackee);
5638032Speter	if (stat(Attackee, &st) >= 0)
5738032Speter	{
5838032Speter		printf("%s already exists -- remove and try again.\n",
5938032Speter			Attackee);
6038032Speter		bail(1);
6138032Speter	}
6238032Speter	if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0)
6338032Speter	{
6438032Speter		int saveerr = errno;
6538032Speter
6638032Speter		if (stat(Attackee, &st) >= 0)
6738032Speter		{
6838032Speter			printf("Weird.  Open failed but %s was created anyhow (errno = %d)\n",
6938032Speter				Attackee, saveerr);
7038032Speter			bail(1);
7138032Speter		}
7238032Speter		printf("Good show!  Exclusive open works properly with symbolic links (errno = %d).\n",
7338032Speter			saveerr);
7438032Speter		bail(0);
7538032Speter	}
7638032Speter	if (stat(Attackee, &st) < 0)
7738032Speter	{
7838032Speter		printf("Weird.  Open succeeded but %s was not created\n",
7938032Speter			Attackee);
8038032Speter		bail(2);
8138032Speter	}
8238032Speter	printf("Bad news: you can do an exclusive open through a symbolic link\n");
8338032Speter	printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n");
8438032Speter	bail(1);
8538032Speter}
8638032Speter
8738032Speterbail(stat)
8838032Speter	int stat;
8938032Speter{
9038032Speter	(void) unlink(Attacker);
9138032Speter	(void) unlink(Attackee);
9238032Speter	exit(stat);
9338032Speter}
94