kern/162009: getpwnam_r buf too small nfs assigns root:user to krb5 clients

Harry Coin hcoin at quietfountain.com
Tue Oct 25 17:10:15 UTC 2011


>Number:         162009
>Category:       kern
>Synopsis:       getpwnam_r buf too small nfs assigns root:user to krb5 clients
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 25 17:10:09 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Harry Coin
>Release:        8 stable
>Organization:
Quiet Fountain LLC
>Environment:
amd64
>Description:
On nfs shares serving kerberos protected accounts, freebsd will assign to files of normal users the ownership root:user.  About as major a security hole as you can expect.



>How-To-Repeat:
nfs share a directory requiring the use of kerberos.  Make sure the principal name maps to a user with a long name and plenty of gecos and other info in the structures relevant to getpw*_r.  Mount the directory on a client.  Log into the client as a normal user.   Create a file on mount.   Note the ownership of the file is root:user.
>Fix:
grep -r 'getpw*_r' /usr/src.  Start hunting.  I found some previously mentioned in bug reports.  Here's another 2.  Basically the problem is 128 byte buffer too small to hold what getpwnam_r returns, plus inadequate error processing (i.e. no log, no user notification...)

patch -p 

diff -u /usr/src/lib/librpcsec_gss/svc_rpcsec_gss.c new/svc_rpcsec_gss.c
--- /usr/src/lib/librpcsec_gss/svc_rpcsec_gss.c	2010-01-30 06:11:21.000000000 -0600
+++ new/svc_rpcsec_gss.c	2011-10-25 11:31:13.549499272 -0500
@@ -562,7 +562,7 @@
     const gss_name_t name)
 {
 	OM_uint32		maj_stat, min_stat;
-	char			buf[128];
+	char			buf[2048];
 	uid_t			uid;
 	struct passwd		pwd, *pw;
 	rpc_gss_ucred_t		*uc = &client->cl_ucred;

diff -u /usr/src/lib/libarchive/archive_write_disk_set_standard_lookup.c new/archive_write_disk_set_standard_lookup.c
--- /usr/src/lib/libarchive/archive_write_disk_set_standard_lookup.c	2011-08-16 12:29:24.293631530 -0500
+++ new/archive_write_disk_set_standard_lookup.c	2011-10-25 11:49:03.507144601 -0500
@@ -189,8 +189,8 @@
 #if HAVE_PWD_H
 #  if HAVE_GETPWNAM_R
 	{
-		char _buffer[128];
-		size_t bufsize = 128;
+		char _buffer[2048];
+		size_t bufsize = 2048;
 		char *buffer = _buffer;
 		struct passwd	pwent, *result;
 		int r;

diff -u /usr/src/usr.sbin/gssd/gssd.c new/gssd.c
--- /usr/src/usr.sbin/gssd/gssd.c	2009-08-03 03:13:06.000000000 -0500
+++ new/gssd.c	2011-10-25 11:59:38.290239235 -0500
@@ -452,7 +452,7 @@
 {
 	gss_name_t name = gssd_find_resource(argp->pname);
 	uid_t uid;
-	char buf[128];
+	char buf[2048];
 	struct passwd pwd, *pw;
 
 	memset(result, 0, sizeof(*result));


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


More information about the freebsd-bugs mailing list