The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: 'Phage List' - Archives (1988 - 1989)
DOCUMENT: phage #179 [Re: fingerd bug] (1 message, 1149 bytes)
SOURCE: http://securitydigest.org/exec/display?f=phage/archive/179.txt&t=text/plain
NOTICE: securitydigest.org recognises the rights of all third-party works.

START OF DOCUMENT

From: Jordan Hayes <jordan@ads.com>
To: phage
Date: Tue 19:56:19 08/11/1988 EST
Subject: Re: fingerd bug
References: [Thread Prev: 162] [Thread Next: 152] [Message Prev: 176] [Message Next: 204]

	From jbs@EDDIE.MIT.EDU Tue Nov  8 16:37:18 1988

	the 680x0 stack grows into increasing addresses, so overflowing
	the buffer can't be used to overwrite the stack frame?

If a user can overflow a buffer in a program, it is a bug.  Some things
that should be thought about when writing daemons:

	*) don't use gets ... use fgets and check your return

[ should you *ever* use gets()? ]

	*) think seriously about logging successful attempts
	*) do log failed attempts and any failures ... in the version
	   of sendmail i run, blowing the SMTP lock-step turns on extra
	   logging ...
	*) enforce the way you think a daemon should run ... in
	   the "fixed" fingerd, there is some code that says

		if (getpeername(0, &sin, &i) < 0)
			fatal(argv[0], "getpeername");

	   This stops you from running fingerd from the shell, but it
	   doesn't stop you from running

		% rsh localhost /etc/fingerd

	   I would suggest more like the following:

-----
	struct sockaddr_in	name;
	struct servent		*sp = getservbyname("finger", "tcp");
	int			len = sizeof(name);
	u_short			port;

	/* make sure we are running from inetd */
	if (getsockname(0, (struct sockaddr *)&name, &len) < 0) {
		syslog(LOG_NOTICE, "getsockname(): %m");
		fatal(argv[0], "getsockname");
	}
	switch (name.sin_family) {
		case AF_INET:
			port = ntohs(name.sin_port);
			if (ntohs((u_short)sp->s_port) != port) {
				syslog(LOG_NOTICE, "illegal port (%d)", port);
				fatal(argv[0], "illegal port");
			}
			break;
		default:
			syslog(LOG_NOTICE, "address family not supported: %d",
			    name.sin_family);
			fatal(argv[0], "address family not supported");
	}

	/* Find out where we are coming from and log it */
	len = sizeof(name);
	if (getpeername(0, (struct sockaddr *)&name, &len) < 0) {
		syslog(LOG_NOTICE, "getpeername(): %m");
		fatal(argv[0], "getpeername");
	}
	hp = gethostbyaddr((char *)&name.sin_addr, sizeof(struct in_addr),
	    AF_INET);
-----

(notes to my pals: really you should use panic() from liberr.a instead of
fatal() ...)

/jordan

END OF DOCUMENT