bin/177698: [patch] sshd sets the user's MAC label at the same time it attempts to set the login class, which can cause the latter to fail if mac_biba is used.

Kevin P. Barry ta0kira at gmail.com
Sun Apr 7 21:50:01 UTC 2013


>Number:         177698
>Category:       bin
>Synopsis:       [patch] sshd sets the user's MAC label at the same time it attempts to set the login class, which can cause the latter to fail if mac_biba is used.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Apr 07 21:50:01 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Kevin P. Barry
>Release:        9.1-RELEASE amd64
>Organization:
>Environment:
FreeBSD kpbarry 9.1-RELEASE FreeBSD 9.1-RELEASE #0: Tue Mar 19 13:38:14 EDT 2013     root at kpbarry:/usr/obj/usr/src/sys/KPBARRY  amd64
>Description:
When using the mac_biba module, only root processes that are capable of attaining biba/equal status are considered privileged. Among the privileges to be lost for processes that cannot attain biba/equal is the ability to set the login class of the process.

When sshd sets the user's context upon successful authentication (session.c:1494), both the user's login class and the corresponding MAC label are set in the same call to setusercontext. Since this isn't an atomic function, it's possible for the MAC label to be set before the login class (in my case, this certainly happens.) Therefore, if the login class of the user logging in has a MAC label in /etc/login.conf incompatible with biba/equal (e.g. biba/high(high-high)) then the login class might not be set (in my case it *doesn't* get set.) This can cause unexpected behavior for tools that can be configured by login class, e.g. rctl.

My proposed solution is to separate context-setting into two calls to setusercontext, with the first call setting all but LOGIN_SETMAC, and the second call setting only LOGIN_SETMAC. I've included a patch, which works on my system.
>How-To-Repeat:
- Enable mac_biba.
- Set the MAC label of a login class to ":label=biba/high(high-high):" in /etc/login.conf and run cap_mkdb. By default, sshd will probably run under the "default" login class; therefore, use a different login class so that a change in login class is required upon login.
- Log in remotely as a user who is a member of the login class modified in the step above. The login should succeed.
- Look at /var/log/messages for a message regarding setloginclass, and/or use `ps -o class -aux | grep sshd` to verify that the login class hasn't been set properly for the logged-in user.
>Fix:
Patch /usr/src/crypto/openssh/session.c so that the MAC label is explicitly set after the login class is set.

Patch attached with submission follows:

--- /usr/src/crypto/openssh/session.c.orig	2012-12-03 22:41:51.000000000 -0500
+++ /usr/src/crypto/openssh/session.c	2013-04-07 17:01:32.000000000 -0400
@@ -1491,11 +1491,24 @@
 
 	if (platform_privileged_uidswap()) {
 #ifdef HAVE_LOGIN_CAP
+#ifdef LOGIN_SETMAC
+		/* Set the MAC label second so it doesn't interfere with setting the login class. */
+		if (setusercontext(lc, pw, pw->pw_uid,
+		    (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER|LOGIN_SETMAC))) < 0) {
+			perror("unable to set user context");
+			exit(1);
+		}
+		if (setusercontext(lc, pw, pw->pw_uid,LOGIN_SETMAC) < 0) {
+			perror("unable to set user context");
+			exit(1);
+		}
+#else
 		if (setusercontext(lc, pw, pw->pw_uid,
 		    (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
 			perror("unable to set user context");
 			exit(1);
 		}
+#endif
 #else
 		if (setlogin(pw->pw_name) < 0)
 			error("setlogin failed: %s", strerror(errno));


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list