~/.login_conf mechanism is flawed

Janne Snabb snabb at epipe.com
Tue Aug 10 15:25:43 UTC 2010


On Tue, 10 Aug 2010, Janne Snabb wrote:

> Looks like the per-user login capability database (~/.login_conf,
> ~/.login_conf.db) functionality is creating a vulnerability.

Attached is a temporary workaround for anyone who is worried about
this problem. It disables per-user login capability databases
completely. Only the system wide /etc/login.conf is used. Do not
apply the patch if you need per-user login capabilities.

This should work on 8.1-RELEASE, most likely on some other releases
as well. I did not find any references to the evil ~/.login_conf{,.db}
anywhere else in the source except in lib/libutil/login_cap.c.

1. Save the attached login_cap.c.diff in /tmp

2. cd /usr/src/lib/libutil

3. patch < /tmp/login_cap.c.diff

4. make

5. make install

6. re-start any affected daemons:
   /etc/rc.d/sshd restart
   /etc/rc.d/ftpd restart

The relevant files are /lib/libutil.* and /usr/lib/libutil.* if you
build on one machine and distribute binaries to others. Re-start
the relevant daemons at each machine after updating the libutil
libraries.

--
Janne Snabb / EPIPE Communications
snabb at epipe.com - http://epipe.com/
-------------- next part --------------
--- login_cap.c.orig	2010-06-14 02:09:06.000000000 +0000
+++ login_cap.c	2010-08-10 14:55:13.000000000 +0000
@@ -194,11 +194,13 @@
 	int         r, me, i = 0;
 	uid_t euid = 0;
 	gid_t egid = 0;
 	const char  *msg = NULL;
 	const char  *dir;
+#ifdef XXX_USER_LOGIN_CONF_ENABLED
 	char	    userpath[MAXPATHLEN];
+#endif
 
 	static char *login_dbarray[] = { NULL, NULL, NULL };
 
 	me = (name != NULL && strcmp(name, LOGIN_MECLASS) == 0);
 	dir = (!me || pwd == NULL) ? NULL : pwd->pw_dir;
@@ -213,15 +215,17 @@
 	    egid = getegid();
 	    (void)setegid(pwd->pw_gid);
 	    (void)seteuid(pwd->pw_uid);
 	}
 
+#ifdef XXX_USER_LOGIN_CONF_ENABLED
 	if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir,
 			    _FILE_LOGIN_CONF) < MAXPATHLEN) {
 	    if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1)
 		login_dbarray[i++] = userpath;
 	}
+#endif
 	/*
 	 * XXX: Why to add the system database if the class is `me'?
 	 */
 	if (_secure_path(path_login_conf, 0, 0) != -1)
 	    login_dbarray[i++] = path_login_conf;


More information about the freebsd-security mailing list