Date: Tue, 25 Oct 2011 17:02:43 GMT From: Harry Coin <hcoin@quietfountain.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/162009: getpwnam_r buf too small nfs assigns root:user to krb5 clients Message-ID: <201110251702.p9PH2h3B086734@red.freebsd.org> Resent-Message-ID: <201110251710.p9PHAEn3043450@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110251702.p9PH2h3B086734>