Re: ~/.login_conf mechanism is flawed



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@xxxxxxxxx - http://epipe.com/--- 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;
_______________________________________________
freebsd-security@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to "freebsd-security-unsubscribe@xxxxxxxxxxx"