[net.unix-wizards] bug in 4.1bsd getpass routine and/or fdopen routine

tas@unc.UUCP (06/11/83)

I ran into a bug in the getpass(3) library routine in 4.1bsd
(the original - don't know about 4.1a or 4.1c). It will
only effect you if the control terminal of your process is
inaccessible (i.e., when a /dev/tty open fails):

Getpass opens your control terminal to turn off echo and read
the password you type, but if the control terminal open fails,
it is supposed to use stdin instead. It doesn't. It misses the
fact that the /dev/tty open failed and merrily wanders on talking
to an invalid file descriptor. This is because it calls:

	if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
		fi = stdin;
	else
		setbuf(fi, (char *)NULL);

therefore sending the file descriptor -1 to fdopen if the open
fails. Buf fdopen doesn't check for bad file descriptors, so
it sets up a file pointer and returns it. Fdopen should probably
check for a negative descriptor, at least... but why the fdopen(open(...)...)
instead of just doing an fopen has me puzzled. Anyway, there are
a number of ways to fix this, of which I chose the following just
in case there was a reason for the fdopen as opposed to an fopen:

	int fd;

	fd = open("/dev/tty", 2);
	if (fd < 0 || (fi = fdopen(fd, "r")) == NULL)
		fi = stdin;
	else
		setbuf(fi, (char *)NULL);