~/.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