diff options
51 files changed, 627 insertions, 401 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y index 90cc538e81..cde2ccab4b 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y +++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,8 +34,6 @@ */ %{ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "config.h" #include <sys/param.h> #include <sys/types.h> @@ -60,6 +58,7 @@ #include <stdlib.h> #include <string.h> #include <limits.h> +#include <alloca.h> #include "extensions.h" #include "pathnames.h" #include "proto.h" @@ -2495,10 +2494,15 @@ void cdpath(void) void print_groups(void) { - gid_t groups[NGROUPS_MAX]; - int ngroups = 0; + gid_t *groups; + int ngroups; + int maxgrp; + + maxgrp = getgroups(0, NULL); + + groups = alloca(maxgrp * sizeof (gid_t)); - if ((ngroups = getgroups(NGROUPS_MAX, groups)) < 0) { + if ((ngroups = getgroups(maxgrp, groups)) < 0) { return; } diff --git a/usr/src/cmd/oamuser/lib/Makefile b/usr/src/cmd/oamuser/lib/Makefile index 3f6475621b..b431c2f5c8 100644 --- a/usr/src/cmd/oamuser/lib/Makefile +++ b/usr/src/cmd/oamuser/lib/Makefile @@ -19,11 +19,9 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# LIBRARY= lib.a @@ -38,7 +36,6 @@ OBJECTS= putgrent.o \ vgname.o \ vgroup.o \ vuid.o \ - get_ngm.o \ vlogin.o \ vproj.o \ dates.o \ diff --git a/usr/src/cmd/oamuser/lib/get_ngm.c b/usr/src/cmd/oamuser/lib/get_ngm.c deleted file mode 100644 index 409d7bd74f..0000000000 --- a/usr/src/cmd/oamuser/lib/get_ngm.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright 1996 Sun Microsystems, Inc. All rights reserved. */ -/* Use is subject to license terms. */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/param.h> -#include <unistd.h> - -/* - * read the value of NGROUPS_MAX from the kernel - */ -int -get_ngm(void) -{ - static int ngm = -1; - - if (ngm == -1 && - (ngm = (int)sysconf(_SC_NGROUPS_MAX)) == -1) - ngm = NGROUPS_UMAX; - - return (ngm); -} diff --git a/usr/src/cmd/oamuser/user/val_lgrp.c b/usr/src/cmd/oamuser/user/val_lgrp.c index db7c0c0903..2ad9d38efb 100644 --- a/usr/src/cmd/oamuser/user/val_lgrp.c +++ b/usr/src/cmd/oamuser/user/val_lgrp.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -28,20 +27,19 @@ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <stdio.h> +#include <stdlib.h> #include <sys/param.h> +#include <unistd.h> #include <users.h> #include <userdefs.h> #include "messages.h" -extern int get_ngm(); extern void exit(); extern char *strtok(); -static gid_t grplist[ NGROUPS_UMAX + 1 ]; +static gid_t *grplist; static int ngroups_max = 0; /* Validate a list of groups */ @@ -57,6 +55,11 @@ valid_lgroup(char *list, gid_t gid) if( !list || !*list ) return( (int **) NULL ); + if (ngroups_max == 0) { + ngroups_max = sysconf(_SC_NGROUPS_MAX); + grplist = malloc((ngroups_max + 1) * sizeof (gid_t)); + } + while (ptr = strtok(((i || n_invalid || dup_prim)? NULL: list), ",")) { switch (valid_group(ptr, &g_ptr, &warning)) { @@ -98,10 +101,6 @@ valid_lgroup(char *list, gid_t gid) if (warning) warningmsg(warning, ptr); - if( !ngroups_max ) - ngroups_max = get_ngm(); - - if( i >= ngroups_max ) { errmsg( M_MAXGROUPS, ngroups_max ); break; diff --git a/usr/src/cmd/perl/5.8.4/distrib/doio.c b/usr/src/cmd/perl/5.8.4/distrib/doio.c index e452bc3a4e..e4fdd87266 100644 --- a/usr/src/cmd/perl/5.8.4/distrib/doio.c +++ b/usr/src/cmd/perl/5.8.4/distrib/doio.c @@ -1,3 +1,7 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ /* doio.c * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, @@ -34,6 +38,10 @@ #endif #endif +#if defined(HAS_GETGROUPS) && defined(__sun) +#include <alloca.h> +#endif + #ifdef I_UTIME # if defined(_MSC_VER) || defined(__MINGW32__) # include <sys/utime.h> @@ -1877,13 +1885,21 @@ Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective) return TRUE; #ifdef HAS_GETGROUPS #ifndef NGROUPS -#define NGROUPS 32 +#define NGROUPS 32 #endif { - Groups_t gary[NGROUPS]; I32 anum; +#ifdef __sun + int maxgrp = getgroups(0, NULL); + Groups_t *gary = alloca(maxgrp * sizeof (Groups_t)); + + anum = getgroups(maxgrp,gary); +#else + Groups_t gary[NGROUPS]; anum = getgroups(NGROUPS,gary); +#endif + while (--anum >= 0) if (gary[anum] == testgid) return TRUE; diff --git a/usr/src/cmd/perl/5.8.4/distrib/mg.c b/usr/src/cmd/perl/5.8.4/distrib/mg.c index 76ef523323..8dd7ef239c 100644 --- a/usr/src/cmd/perl/5.8.4/distrib/mg.c +++ b/usr/src/cmd/perl/5.8.4/distrib/mg.c @@ -1,3 +1,7 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ /* mg.c * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, @@ -28,6 +32,10 @@ # ifdef I_GRP # include <grp.h> # endif +#ifdef __sun +#include <alloca.h> +#include <unistd.h> +#endif #endif #ifdef __hpux @@ -891,8 +899,14 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) add_groups: #ifdef HAS_GETGROUPS { +#ifdef __sun + int maxgrp = getgroups(0, NULL); + Groups_t *gary = alloca(maxgrp * sizeof (Groups_t)); + i = getgroups(maxgrp,gary); +#else Groups_t gary[NGROUPS]; i = getgroups(NGROUPS,gary); +#endif while (--i >= 0) Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]); } @@ -2368,12 +2382,18 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) #ifdef HAS_SETGROUPS { char *p = SvPV(sv, len); +#ifdef _SC_NGROUPS_MAX + int maxgrp = sysconf(_SC_NGROUPS_MAX); + Groups_t *gary = alloca(maxgrp * sizeof (Groups_t)); +#else + int maxgrp = NGROUPS; Groups_t gary[NGROUPS]; +#endif while (isSPACE(*p)) ++p; PL_egid = Atol(p); - for (i = 0; i < NGROUPS; ++i) { + for (i = 0; i < maxgrp; ++i) { while (*p && !isSPACE(*p)) ++p; while (isSPACE(*p)) diff --git a/usr/src/cmd/praudit/token.c b/usr/src/cmd/praudit/token.c index 4c1c0ba02b..f52291d8d6 100644 --- a/usr/src/cmd/praudit/token.c +++ b/usr/src/cmd/praudit/token.c @@ -1808,6 +1808,8 @@ attribute64_token(pr_context_t *context) * return codes : -1 - error * : 0 - successful * NOTE: At the time of call, the group token id has been retrieved + * NOTE: This token is obsolete; it supports exactly NGROUPS_MAX + * groups. * * Format of group token: * group token id adr_char diff --git a/usr/src/cmd/print/lpset/lpset.c b/usr/src/cmd/print/lpset/lpset.c index d0a765caea..04b0cc7677 100644 --- a/usr/src/cmd/print/lpset/lpset.c +++ b/usr/src/cmd/print/lpset/lpset.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <sys/types.h> @@ -39,6 +37,7 @@ #include <libintl.h> #endif #include <pwd.h> +#include <alloca.h> #include <ns.h> #include <list.h> @@ -54,8 +53,9 @@ authorized() { struct passwd *pw; uid_t uid; - gid_t list[NGROUPS_MAX]; + gid_t *list; int len; + int maxgrp; if ((uid = getuid()) == 0) return (1); /* "root" is authorized */ @@ -69,8 +69,12 @@ authorized() if (chkauthattr("solaris.print.admin", pw->pw_name) == 1) return (1); /* "solaris.print.admin" is authorized */ - if ((len = getgroups(sizeof (list), list)) != -1) - for (; len >= 0; len--) + /* How many supplemental groups do we have? */ + maxgrp = getgroups(0, NULL); + list = alloca(maxgrp * sizeof (gid_t)); + + if ((len = getgroups(maxgrp, list)) != -1) + while (len-- > 0) if (list[len] == 14) return (1); /* group 14 is authorized */ diff --git a/usr/src/cmd/smserverd/myaudit.c b/usr/src/cmd/smserverd/myaudit.c index ecc0227c6d..845f53fe8b 100644 --- a/usr/src/cmd/smserverd/myaudit.c +++ b/usr/src/cmd/smserverd/myaudit.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,6 +36,7 @@ #include <string.h> #include <unistd.h> #include <stdlib.h> +#include <alloca.h> #include <sys/smedia.h> #include <tsol/label.h> #include "smserver.h" @@ -129,7 +130,7 @@ audit_save_me(door_data_t *door_dp) return (ret_val); door_dp->audit_ap.ap_pid = client_cred.dc_pid; ret_val = auditon(A_GETPINFO_ADDR, (caddr_t)&door_dp->audit_ap, - sizeof (door_dp->audit_ap)); + sizeof (door_dp->audit_ap)); if (ret_val == -1) return (ret_val); @@ -144,7 +145,7 @@ audit_save_me(door_data_t *door_dp) door_dp->audit_tid.at_type = door_dp->audit_ap.ap_termid.at_type; for (i = 0; i < (door_dp->audit_ap.ap_termid.at_type/4); i++) door_dp->audit_tid.at_addr[i] = - door_dp->audit_ap.ap_termid.at_addr[i]; + door_dp->audit_ap.ap_termid.at_addr[i]; (void) audit_save_policy(door_dp); return (0); } @@ -205,19 +206,19 @@ audit_audit(door_data_t *door_dp) } (void) au_write(ad, au_to_subject_ex(door_dp->audit_auid, - door_dp->audit_euid, - door_dp->audit_egid, - door_dp->audit_uid, door_dp->audit_gid, door_dp->audit_pid, - door_dp->audit_asid, &door_dp->audit_tid)); + door_dp->audit_euid, + door_dp->audit_egid, + door_dp->audit_uid, door_dp->audit_gid, door_dp->audit_pid, + door_dp->audit_asid, &door_dp->audit_tid)); if (is_system_labeled()) (void) au_write(ad, au_to_mylabel()); if (door_dp->audit_policy & AUDIT_GROUP) { int ng; - gid_t grplst[NGROUPS_MAX]; + int maxgrp = getgroups(0, NULL); + gid_t *grplst = alloca(maxgrp * sizeof (gid_t)); - (void) memset(grplst, 0, sizeof (grplst)); - if ((ng = getgroups(NGROUPS_UMAX, grplst))) { + if ((ng = getgroups(maxgrp, grplst))) { (void) au_write(ad, au_to_newgroups(ng, grplst)); } } @@ -232,10 +233,10 @@ audit_audit(door_data_t *door_dp) } #ifdef _LP64 (void) au_write(ad, au_to_return64((door_dp->audit_sorf == 0) ? 0 : -1, - (int64_t)door_dp->audit_sorf)); + (int64_t)door_dp->audit_sorf)); #else (void) au_write(ad, au_to_return32((door_dp->audit_sorf == 0) ? 0 : -1, - (int32_t)door_dp->audit_sorf)); + (int32_t)door_dp->audit_sorf)); #endif if (au_close(ad, 1, door_dp->audit_event) < 0) { (void) au_close(ad, 0, 0); @@ -253,7 +254,7 @@ audit_na_selected(door_data_t *door_dp) } return (selected(door_dp->audit_event, - &door_dp->audit_namask, door_dp->audit_sorf)); + &door_dp->audit_namask, door_dp->audit_sorf)); } static int @@ -266,7 +267,7 @@ audit_selected(door_data_t *door_dp) } return (selected(door_dp->audit_event, - &door_dp->audit_ap.ap_mask, door_dp->audit_sorf)); + &door_dp->audit_ap.ap_mask, door_dp->audit_sorf)); } static int diff --git a/usr/src/cmd/ssh/libssh/common/uidswap.c b/usr/src/cmd/ssh/libssh/common/uidswap.c index 32256b4718..942b22a749 100644 --- a/usr/src/cmd/ssh/libssh/common/uidswap.c +++ b/usr/src/cmd/ssh/libssh/common/uidswap.c @@ -46,7 +46,8 @@ static gid_t saved_egid = 0; /* Saved effective uid. */ static int privileged = 0; static int temporarily_use_uid_effective = 0; -static gid_t saved_egroups[NGROUPS_UMAX], user_groups[NGROUPS_UMAX]; +static int ngroups_max = -1; +static gid_t *saved_egroups, *user_groups; static int saved_egroupslen = -1, user_groupslen = -1; /* @@ -76,7 +77,16 @@ temporarily_use_uid(struct passwd *pw) privileged = 1; temporarily_use_uid_effective = 1; - saved_egroupslen = getgroups(NGROUPS_UMAX, saved_egroups); + + if (ngroups_max < 0) { + ngroups_max = sysconf(_SC_NGROUPS_MAX); + saved_egroups = malloc(ngroups_max * sizeof (gid_t)); + user_groups = malloc(ngroups_max * sizeof (gid_t)); + if (saved_egroups == NULL || user_groups == NULL) + fatal("malloc(gid array): %.100s", strerror(errno)); + } + + saved_egroupslen = getgroups(ngroups_max, saved_egroups); if (saved_egroupslen < 0) fatal("getgroups: %.100s", strerror(errno)); @@ -85,7 +95,7 @@ temporarily_use_uid(struct passwd *pw) if (initgroups(pw->pw_name, pw->pw_gid) < 0) fatal("initgroups: %s: %.100s", pw->pw_name, strerror(errno)); - user_groupslen = getgroups(NGROUPS_UMAX, user_groups); + user_groupslen = getgroups(ngroups_max, user_groups); if (user_groupslen < 0) fatal("getgroups: %.100s", strerror(errno)); } diff --git a/usr/src/cmd/ssh/sshd/groupaccess.c b/usr/src/cmd/ssh/sshd/groupaccess.c index 2d8aa3ca80..2239832e1b 100644 --- a/usr/src/cmd/ssh/sshd/groupaccess.c +++ b/usr/src/cmd/ssh/sshd/groupaccess.c @@ -1,4 +1,8 @@ /* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* * Copyright (c) 2001 Kevin Steves. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,9 +33,10 @@ RCSID("$OpenBSD: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $"); #include "xmalloc.h" #include "match.h" #include "log.h" +#include <alloca.h> -static int ngroups; -static char *groups_byname[NGROUPS_UMAX + 1]; /* +1 for base/primary group */ +static int ngroups, ngroups_lim; +static char **groups_byname; /* * Initialize group access list for user with primary (base) and @@ -40,14 +45,20 @@ static char *groups_byname[NGROUPS_UMAX + 1]; /* +1 for base/primary group */ int ga_init(const char *user, gid_t base) { - gid_t groups_bygid[NGROUPS_UMAX + 1]; + gid_t *groups_bygid; int i, j; struct group *gr; - if (ngroups > 0) + if (ngroups_lim == 0) { + /* Add one for the base gid */ + ngroups_lim = sysconf(_SC_NGROUPS_MAX) + 1; + groups_byname = malloc(sizeof (char *) * ngroups_lim); + } else if (ngroups > 0) ga_free(); - ngroups = sizeof(groups_bygid) / sizeof(gid_t); + groups_bygid = alloca(ngroups_lim * sizeof (gid_t)); + + ngroups = ngroups_lim; if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) log("getgrouplist: groups list too small"); for (i = 0, j = 0; i < ngroups; i++) @@ -68,8 +79,8 @@ ga_match(char * const *groups, int n) for (i = 0; i < ngroups; i++) for (j = 0; j < n; j++) if (match_pattern(groups_byname[i], groups[j])) - return 1; - return 0; + return (1); + return (0); } /* @@ -86,14 +97,14 @@ ga_match_pattern_list(const char *group_pattern) switch (match_pattern_list(groups_byname[i], group_pattern, len, 0)) { case -1: - return 0; /* Negated match wins */ + return (0); /* Negated match wins */ case 0: continue; case 1: found = 1; } } - return found; + return (found); } /* diff --git a/usr/src/head/rpcsvc/svc_dg_priv.h b/usr/src/head/rpcsvc/svc_dg_priv.h index 9db92bb5a6..80d2294f73 100644 --- a/usr/src/head/rpcsvc/svc_dg_priv.h +++ b/usr/src/head/rpcsvc/svc_dg_priv.h @@ -20,15 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SVC_DG_PRIV_H #define _SVC_DG_PRIV_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * The svc_dg_data private datastructure shared by some services * for nefarious reasons. THIS IS NOT AN INTERFACE. DO NOT USE. @@ -38,7 +36,13 @@ extern "C" { #endif -#define MAX_OPT_WORDS 128 /* needs to fit a ucred */ +/* + * The size of the option header should include sufficient space for + * a ucred; we reserve 32 words as before we had ucreds and we allocate + * sizeof (svc_dg_data) + ucred_size(). Of course, opts must be declared + * last so it can use the additional memory. + */ +#define MAX_OPT_WORDS 32 /* * kept in xprt->xp_p2 @@ -46,13 +50,13 @@ extern "C" { struct svc_dg_data { /* Note: optbuf must be the first field, used by ti_opts.c code */ struct netbuf optbuf; /* netbuf for options */ - int opts[MAX_OPT_WORDS]; /* options */ uint_t su_iosz; /* size of send.recv buffer */ uint32_t su_xid; /* transaction id */ XDR su_xdrs; /* XDR handle */ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ char *su_cache; /* cached data, NULL if none */ struct t_unitdata su_tudata; /* tu_data for recv */ + int opts[MAX_OPT_WORDS]; /* options: MUST BE LAST */ }; #define get_svc_dg_data(xprt) ((struct svc_dg_data *)((xprt)->xp_p2)) diff --git a/usr/src/lib/libbsm/common/adt_token.c b/usr/src/lib/libbsm/common/adt_token.c index fcb537e3f5..f217e6737e 100644 --- a/usr/src/lib/libbsm/common/adt_token.c +++ b/usr/src/lib/libbsm/common/adt_token.c @@ -32,6 +32,7 @@ #include <bsm/audit.h> #include <adt_xlate.h> +#include <alloca.h> #include <assert.h> #include <netdb.h> #include <priv.h> @@ -598,10 +599,10 @@ adt_to_subject(datadef *def, void *p_data, int required, if (sp->as_session_model == ADT_PROCESS_MODEL) { if (sp->as_kernel_audit_policy & AUDIT_GROUP) { int group_count; - gid_t grouplist[NGROUPS_MAX]; + int maxgrp = getgroups(0, NULL); + gid_t *grouplist = alloca(maxgrp * sizeof (gid_t)); - if ((group_count = getgroups(NGROUPS_UMAX, - grouplist)) > 0) { + if ((group_count = getgroups(maxgrp, grouplist)) > 0) { (void) au_write(event->ae_event_handle, au_to_newgroups(group_count, grouplist)); } diff --git a/usr/src/lib/libbsm/common/au_to.c b/usr/src/lib/libbsm/common/au_to.c index c31ed8ba41..9ee2dd7b7a 100644 --- a/usr/src/lib/libbsm/common/au_to.c +++ b/usr/src/lib/libbsm/common/au_to.c @@ -1090,7 +1090,7 @@ au_to_newgroups(int n, gid_t *groups) char data_header = AUT_NEWGROUPS; /* header for this token */ short n_groups; - if (n < NGROUPS_UMIN || n > NGROUPS_UMAX || groups == NULL) + if (n < 0 || n > SHRT_MAX || groups == NULL) return (NULL); token = get_token(sizeof (char) + sizeof (short) + n * sizeof (gid_t)); if (token == NULL) diff --git a/usr/src/lib/libbsm/common/audit_allocate.c b/usr/src/lib/libbsm/common/audit_allocate.c index 3dfbf3ef65..6bae7be18f 100644 --- a/usr/src/lib/libbsm/common/audit_allocate.c +++ b/usr/src/lib/libbsm/common/audit_allocate.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <tsol/label.h> #include <bsm/audit.h> @@ -35,6 +33,7 @@ #include <bsm/audit_uevents.h> #include <generic.h> #include <stdlib.h> +#include <alloca.h> static int s_audit; /* successful audit event */ static int f_audit; /* failure audit event */ @@ -92,7 +91,6 @@ audit_allocate_record(status) au_event_t event; /* audit event number */ int policy; /* audit policy */ int ng; /* number of groups in process */ - gid_t grplst[NGROUPS_UMAX]; #ifdef DEBUG printf(("audit_allocate_record(%d)\n", status)); @@ -130,8 +128,12 @@ audit_allocate_record(status) (void) au_write(ad, au_to_mylabel()); if (policy & AUDIT_GROUP) { /* add optional group token */ - (void) memset(grplst, 0, sizeof (grplst)); - if ((ng = getgroups(NGROUPS_UMAX, grplst)) < 0) { + gid_t *grplst; + int maxgrp = getgroups(0, NULL); + + grplst = alloca(maxgrp * sizeof (gid_t)); + + if ((ng = getgroups(maxgrp, grplst)) < 0) { (void) au_close(ad, 0, 0); if (!status) return (1); diff --git a/usr/src/lib/libbsm/common/generic.c b/usr/src/lib/libbsm/common/generic.c index 5e59bcd1ce..e1d1929070 100644 --- a/usr/src/lib/libbsm/common/generic.c +++ b/usr/src/lib/libbsm/common/generic.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,6 +34,7 @@ #include <sys/types.h> #include <string.h> #include <unistd.h> +#include <alloca.h> #include <stdlib.h> #include <tsol/label.h> #include <bsm/audit.h> @@ -174,14 +175,14 @@ aug_get_machine(const char *hostname, uint32_t *buf, uint32_t *type) case AF_INET: /* LINTED */ p = &((struct sockaddr_in *)ai->ai_addr)->sin_addr, - (void) memcpy(buf, p, + (void) memcpy(buf, p, sizeof (((struct sockaddr_in *)0)->sin_addr)); *type = AU_IPv4; break; case AF_INET6: /* LINTED */ p = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, - (void) memcpy(buf, p, + (void) memcpy(buf, p, sizeof (((struct sockaddr_in6 *)0)->sin6_addr)); *type = AU_IPv6; break; @@ -280,8 +281,8 @@ aug_save_me(void) aug_save_pid(getpid()); aug_save_asid(ai.ai_asid); aug_save_tid_ex(ai.ai_termid.at_port, - ai.ai_termid.at_addr, - ai.ai_termid.at_type); + ai.ai_termid.at_addr, + ai.ai_termid.at_type); return (0); } @@ -414,15 +415,15 @@ aug_audit(void) } (void) au_write(ad, au_to_subject_ex(aug_auid, aug_euid, aug_egid, - aug_uid, aug_gid, aug_pid, aug_asid, &aug_tid)); + aug_uid, aug_gid, aug_pid, aug_asid, &aug_tid)); if (is_system_labeled()) (void) au_write(ad, au_to_mylabel()); if (aug_policy & AUDIT_GROUP) { int ng; - gid_t grplst[NGROUPS_UMAX]; + int maxgrp = getgroups(0, NULL); + gid_t *grplst = alloca(maxgrp * sizeof (gid_t)); - (void) memset(grplst, 0, sizeof (grplst)); - if ((ng = getgroups(NGROUPS_UMAX, grplst))) { + if ((ng = getgroups(maxgrp, grplst)) > 0) { (void) au_write(ad, au_to_newgroups(ng, grplst)); } } diff --git a/usr/src/lib/libc/port/gen/sysconf.c b/usr/src/lib/libc/port/gen/sysconf.c index 26415015c3..8c2e6f4eb2 100644 --- a/usr/src/lib/libc/port/gen/sysconf.c +++ b/usr/src/lib/libc/port/gen/sysconf.c @@ -20,15 +20,13 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* sysconf(3C) - returns system configuration information */ #pragma weak _sysconf = sysconf @@ -57,6 +55,7 @@ sysconf(int name) static int _hz = 0; static pid_t _maxpid = 0; static int _stackprot = 0; + static int _ngroups_max; extern int __xpg4; switch (name) { @@ -82,7 +81,9 @@ sysconf(int name) return (_sysconfig(_CONFIG_CHILD_MAX)); case _SC_NGROUPS_MAX: - return (_sysconfig(_CONFIG_NGROUPS)); + if (_ngroups_max <= 0) + _ngroups_max = _sysconfig(_CONFIG_NGROUPS); + return (_ngroups_max); case _SC_OPEN_MAX: return (_sysconfig(_CONFIG_OPEN_FILES)); diff --git a/usr/src/lib/libnsl/nsl/_utility.c b/usr/src/lib/libnsl/nsl/_utility.c index 4f366a8978..f01cea5c6e 100644 --- a/usr/src/lib/libnsl/nsl/_utility.c +++ b/usr/src/lib/libnsl/nsl/_utility.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -24,12 +23,10 @@ /* All Rights Reserved */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "mt.h" #include <stdlib.h> #include <string.h> @@ -48,6 +45,7 @@ #include <assert.h> #include <syslog.h> #include <limits.h> +#include <ucred.h> #include "tx.h" #define DEFSIZE 2048 @@ -61,7 +59,7 @@ static struct _ti_user *find_tilink(int s); static struct _ti_user *add_tilink(int s); static void _t_free_lookbufs(struct _ti_user *tiptr); -static unsigned int _t_setsize(t_scalar_t infosize); +static unsigned int _t_setsize(t_scalar_t infosize, boolean_t option); static int _t_cbuf_alloc(struct _ti_user *tiptr, char **retbuf); static int _t_rbuf_alloc(struct _ti_user *tiptr, char **retbuf); static int _t_adjust_state(int fd, int instate); @@ -510,8 +508,8 @@ _t_alloc_bufs(int fd, struct _ti_user *tiptr, struct T_info_ack *tsap) char *ctlbuf, *rcvbuf; char *lookdbuf, *lookcbuf; - csize = _t_setsize(tsap->CDATA_size); - dsize = _t_setsize(tsap->DDATA_size); + csize = _t_setsize(tsap->CDATA_size, B_FALSE); + dsize = _t_setsize(tsap->DDATA_size, B_FALSE); size1 = _T_MAX(csize, dsize); @@ -527,13 +525,13 @@ _t_alloc_bufs(int fd, struct _ti_user *tiptr, struct T_info_ack *tsap) lookdbuf = NULL; } - asize = _t_setsize(tsap->ADDR_size); + asize = _t_setsize(tsap->ADDR_size, B_FALSE); if (tsap->OPT_size >= 0) /* compensate for XTI level options */ optsize = tsap->OPT_size + TX_XTI_LEVEL_MAX_OPTBUF; else optsize = tsap->OPT_size; - osize = _t_setsize(optsize); + osize = _t_setsize(optsize, B_TRUE); /* * We compute the largest buffer size needed for this provider by @@ -593,10 +591,22 @@ _t_alloc_bufs(int fd, struct _ti_user *tiptr, struct T_info_ack *tsap) * set sizes of buffers */ static unsigned int -_t_setsize(t_scalar_t infosize) +_t_setsize(t_scalar_t infosize, boolean_t option) { + static size_t optinfsize; + switch (infosize) { case T_INFINITE /* -1 */: + if (option) { + if (optinfsize == 0) { + size_t uc = ucred_size(); + if (uc < DEFSIZE/2) + optinfsize = DEFSIZE; + else + optinfsize = ucred_size() + DEFSIZE/2; + } + return ((unsigned int)optinfsize); + } return (DEFSIZE); case T_INVALID /* -2 */: return (0); diff --git a/usr/src/lib/libnsl/nsl/t_alloc.c b/usr/src/lib/libnsl/nsl/t_alloc.c index a8e05bc2d9..67d1204afc 100644 --- a/usr/src/lib/libnsl/nsl/t_alloc.c +++ b/usr/src/lib/libnsl/nsl/t_alloc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -24,12 +23,10 @@ /* All Rights Reserved */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.4.1.2 */ - #include "mt.h" #include <stdlib.h> #include <unistd.h> @@ -41,6 +38,7 @@ #include <xti.h> #include <stdio.h> #include <errno.h> +#include <ucred.h> #include <signal.h> #include "tx.h" @@ -48,7 +46,7 @@ * Function protoypes */ static int _alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, - int api_semantics); + int api_semantics, boolean_t option); char * _tx_alloc(int fd, int struct_type, int fields, int api_semantics) @@ -115,7 +113,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) if (fields & T_ADDR) { if (_alloc_buf(&p.bind->addr, info.ADDR_size, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } sig_mutex_unlock(&tiptr->ti_lock); @@ -127,7 +125,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) if (fields & T_ADDR) { if (_alloc_buf(&p.call->addr, info.ADDR_size, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } if (fields & T_OPT) { @@ -138,14 +136,14 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) else optsize = info.OPT_size; if (_alloc_buf(&p.call->opt, optsize, - fields, api_semantics) < 0) + fields, api_semantics, B_TRUE) < 0) goto errout; } if (fields & T_UDATA) { dsize = _T_MAX((int)info.CDATA_size, - (int)info.DDATA_size); + (int)info.DDATA_size); if (_alloc_buf(&p.call->udata, (t_scalar_t)dsize, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } sig_mutex_unlock(&tiptr->ti_lock); @@ -162,7 +160,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) else optsize = info.OPT_size; if (_alloc_buf(&p.opt->opt, optsize, - fields, api_semantics) < 0) + fields, api_semantics, B_TRUE) < 0) goto errout; } sig_mutex_unlock(&tiptr->ti_lock); @@ -173,7 +171,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) goto errout; if (fields & T_UDATA) { if (_alloc_buf(&p.dis->udata, info.DDATA_size, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } sig_mutex_unlock(&tiptr->ti_lock); @@ -184,7 +182,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) goto errout; if (fields & T_ADDR) { if (_alloc_buf(&p.udata->addr, info.ADDR_size, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } if (fields & T_OPT) { @@ -195,12 +193,12 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) else optsize = info.OPT_size; if (_alloc_buf(&p.udata->opt, optsize, - fields, api_semantics) < 0) + fields, api_semantics, B_TRUE) < 0) goto errout; } if (fields & T_UDATA) { if (_alloc_buf(&p.udata->udata, info.TSDU_size, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } sig_mutex_unlock(&tiptr->ti_lock); @@ -211,7 +209,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) goto errout; if (fields & T_ADDR) { if (_alloc_buf(&p.uderr->addr, info.ADDR_size, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } if (fields & T_OPT) { @@ -222,7 +220,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics) else optsize = info.OPT_size; if (_alloc_buf(&p.uderr->opt, optsize, - fields, api_semantics) < 0) + fields, api_semantics, B_FALSE) < 0) goto errout; } sig_mutex_unlock(&tiptr->ti_lock); @@ -262,7 +260,8 @@ errout: } static int -_alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, int api_semantics) +_alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, int api_semantics, + boolean_t option) { switch (n) { case T_INFINITE /* -1 */: @@ -277,6 +276,25 @@ _alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, int api_semantics) errno = EINVAL; return (-1); } + } else if (option) { /* TX_TLI_API */ + static size_t infalloc; + + /* + * retain TLI behavior; ucred_t can vary in size, + * we need to make sure that we can receive one. + */ + if (infalloc == 0) { + size_t uc = ucred_size(); + if (uc < 1024/2) + infalloc = 1024; + else + infalloc = uc + 1024/2; + } + if ((buf->buf = calloc(1, infalloc)) == NULL) { + errno = ENOMEM; + return (-1); + } else + buf->maxlen = infalloc; } else { /* TX_TLI_API */ /* * retain TLI behavior diff --git a/usr/src/lib/libnsl/rpc/auth_sys.c b/usr/src/lib/libnsl/rpc/auth_sys.c index 4b6485bbfa..8ec507bc07 100644 --- a/usr/src/lib/libnsl/rpc/auth_sys.c +++ b/usr/src/lib/libnsl/rpc/auth_sys.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -32,8 +31,6 @@ * California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * auth_sys.c, Implements UNIX (system) style authentication parameters. * @@ -45,6 +42,7 @@ */ #include "mt.h" #include "rpc_mt.h" +#include <alloca.h> #include <stdio.h> #include <syslog.h> #include <stdlib.h> @@ -100,13 +98,13 @@ authsys_create(const char *machname, const uid_t uid, const gid_t gid, auth = malloc(sizeof (*auth)); if (auth == NULL) { (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str, - __no_mem_auth); + __no_mem_auth); return (NULL); } au = malloc(sizeof (*au)); if (au == NULL) { (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str, - __no_mem_auth); + __no_mem_auth); free(auth); return (NULL); } @@ -132,21 +130,21 @@ authsys_create(const char *machname, const uid_t uid, const gid_t gid, xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); if (!xdr_authsys_parms(&xdrs, &aup)) { (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str, - ": xdr_authsys_parms failed"); + ": xdr_authsys_parms failed"); return (NULL); } au->au_origcred.oa_length = XDR_GETPOS(&xdrs); au->au_origcred.oa_flavor = AUTH_SYS; if ((au->au_origcred.oa_base = malloc(au->au_origcred.oa_length)) == - NULL) { + NULL) { (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str, - __no_mem_auth); + __no_mem_auth); free(au); free(auth); return (NULL); } (void) memcpy(au->au_origcred.oa_base, mymem, - (size_t)au->au_origcred.oa_length); + (size_t)au->au_origcred.oa_length); /* * set auth handle to reflect new cred. @@ -173,7 +171,8 @@ authsys_create_default(void) char machname[MAX_MACHINE_NAME + 1]; uid_t uid; gid_t gid; - gid_t gids[NGRPS]; + int maxgrp = getgroups(0, NULL); + gid_t *gids = alloca(maxgrp * sizeof (gid_t)); if (gethostname(machname, MAX_MACHINE_NAME) == -1) { (void) syslog(LOG_ERR, authsys_def_str, "hostname"); @@ -182,10 +181,12 @@ authsys_create_default(void) machname[MAX_MACHINE_NAME] = 0; uid = geteuid(); gid = getegid(); - if ((len = getgroups(NGRPS, gids)) < 0) { + if ((len = getgroups(maxgrp, gids)) < 0) { (void) syslog(LOG_ERR, authsys_def_str, "groups"); return (NULL); } + if (len > NGRPS) + len = NGRPS; return (authsys_create(machname, uid, gid, len, gids)); } @@ -205,22 +206,25 @@ authsys_create_ruid(void) char machname[MAX_MACHINE_NAME + 1]; uid_t uid; gid_t gid; - gid_t gids[NGRPS]; + int maxgrp = getgroups(0, NULL); + gid_t *gids = alloca(maxgrp * sizeof (gid_t)); AUTH *res; if (gethostname(machname, MAX_MACHINE_NAME) == -1) { (void) syslog(LOG_ERR, - "authsys_create_ruid:gethostname failed"); + "authsys_create_ruid:gethostname failed"); return (NULL); } machname[MAX_MACHINE_NAME] = 0; uid = getuid(); gid = getgid(); - if ((len = getgroups(NGRPS, gids)) < 0) { + if ((len = getgroups(maxgrp, gids)) < 0) { (void) syslog(LOG_ERR, - "authsys_create_ruid:getgroups failed"); + "authsys_create_ruid:getgroups failed"); return (NULL); } + if (len > NGRPS) + len = NGRPS; res = authsys_create(machname, uid, gid, len, gids); return (res); } @@ -255,7 +259,7 @@ authsys_validate(AUTH *auth, struct opaque_auth *verf) /* LINTED pointer alignment */ au = AUTH_PRIVATE(auth); xdrmem_create(&xdrs, verf->oa_base, - verf->oa_length, XDR_DECODE); + verf->oa_length, XDR_DECODE); if (au->au_shcred.oa_base != NULL) { free(au->au_shcred.oa_base); diff --git a/usr/src/lib/libnsl/rpc/netnamer.c b/usr/src/lib/libnsl/rpc/netnamer.c index f20434eb48..1748937088 100644 --- a/usr/src/lib/libnsl/rpc/netnamer.c +++ b/usr/src/lib/libnsl/rpc/netnamer.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -37,8 +37,6 @@ * Well, at least the API doesn't involve pointers-to-static. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * netname utility routines convert from netnames to unix names (uid, gid) * @@ -52,6 +50,8 @@ #include "rpc_mt.h" #include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <alloca.h> #include <sys/types.h> #include <ctype.h> #include <grp.h> @@ -72,10 +72,6 @@ static const char PKTABLE[] = "cred.org_dir"; #define PKTABLE_LEN 12 #define OPSYS_LEN 4 -#ifndef NGROUPS -#define NGROUPS 16 -#endif - extern int _getgroupsbymember(const char *, gid_t[], int, int); /* @@ -505,7 +501,8 @@ netname2user_ldap(int *err, char *netname, struct netid_userdata *argp) int ngroups = 0; int count; char pwbuf[NSS_LINELEN_PASSWD]; - gid_t groups[NGROUPS_MAX]; + int maxgrp = sysconf(_SC_NGROUPS_MAX); + gid_t *groups = alloca(maxgrp * sizeof (gid_t)); if (strlcpy(buf, netname, NSS_LINELEN_PASSWD) >= NSS_LINELEN_PASSWD) { *err = __NSW_UNAVAIL; @@ -539,7 +536,7 @@ netname2user_ldap(int *err, char *netname, struct netid_userdata *argp) groups[0] = pw.pw_gid; - ngroups = _getgroupsbymember(pw.pw_name, groups, NGROUPS_MAX, + ngroups = _getgroupsbymember(pw.pw_name, groups, maxgrp, (pw.pw_gid <= MAXUID) ? 1 : 0); if (ngroups < 0) { diff --git a/usr/src/lib/libnsl/rpc/svc_dg.c b/usr/src/lib/libnsl/rpc/svc_dg.c index 2785e12cef..030a1e52b1 100644 --- a/usr/src/lib/libnsl/rpc/svc_dg.c +++ b/usr/src/lib/libnsl/rpc/svc_dg.c @@ -48,6 +48,7 @@ #include <syslog.h> #include <stdlib.h> #include <string.h> +#include <ucred.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> @@ -121,6 +122,7 @@ svc_dg_create_private(int fd, uint_t sendsize, uint_t recvsize) SVCXPRT *xprt; struct svc_dg_data *su = NULL; struct t_info tinfo; + size_t ucred_sz = ucred_size(); if (RPC_FD_NOTIN_FDSET(fd)) { errno = EBADF; @@ -148,7 +150,7 @@ svc_dg_create_private(int fd, uint_t sendsize, uint_t recvsize) /* LINTED pointer alignment */ svc_flags(xprt) |= SVC_DGRAM; - su = malloc(sizeof (*su)); + su = malloc(sizeof (*su) + ucred_sz); if (su == NULL) goto freedata; su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4; @@ -167,7 +169,7 @@ svc_dg_create_private(int fd, uint_t sendsize, uint_t recvsize) su->su_tudata.udata.buf = (char *)rpc_buffer(xprt); su->su_tudata.opt.buf = (char *)su->opts; su->su_tudata.udata.maxlen = su->su_iosz; - su->su_tudata.opt.maxlen = MAX_OPT_WORDS << 2; /* no of bytes */ + su->su_tudata.opt.maxlen = MAX_OPT_WORDS * sizeof (int) + ucred_sz; /* LINTED pointer alignment */ SVC_XP_AUTH(xprt).svc_ah_ops = svc_auth_any_ops; /* LINTED pointer alignment */ @@ -195,6 +197,7 @@ svc_dg_xprtcopy(SVCXPRT *parent) { SVCXPRT *xprt; struct svc_dg_data *su; + size_t ucred_sz = ucred_size(); if ((xprt = svc_xprt_alloc()) == NULL) return (NULL); @@ -237,7 +240,7 @@ svc_dg_xprtcopy(SVCXPRT *parent) xprt->xp_rtaddr.maxlen); xprt->xp_type = parent->xp_type; - if ((su = malloc(sizeof (struct svc_dg_data))) == NULL) { + if ((su = malloc(sizeof (struct svc_dg_data) + ucred_sz)) == NULL) { svc_dg_xprtfree(xprt); return (NULL); } @@ -255,7 +258,7 @@ svc_dg_xprtcopy(SVCXPRT *parent) su->su_tudata.udata.buf = (char *)rpc_buffer(xprt); su->su_tudata.opt.buf = (char *)su->opts; su->su_tudata.udata.maxlen = su->su_iosz; - su->su_tudata.opt.maxlen = MAX_OPT_WORDS << 2; /* no of bytes */ + su->su_tudata.opt.maxlen = MAX_OPT_WORDS * sizeof (int) + ucred_sz; xprt->xp_p2 = (caddr_t)su; /* get_svc_dg_data(xprt) = su */ xprt->xp_verf.oa_base = su->su_verfbody; diff --git a/usr/src/lib/libnsl/rpc/svc_door.c b/usr/src/lib/libnsl/rpc/svc_door.c index d5f3d7c675..480e28b4c3 100644 --- a/usr/src/lib/libnsl/rpc/svc_door.c +++ b/usr/src/lib/libnsl/rpc/svc_door.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,12 +20,10 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * svc_door.c, Server side for doors IPC based RPC. */ @@ -56,8 +53,6 @@ int __rpc_min_door_buf_size = 1000; static struct xp_ops *svc_door_ops(); -#define MAX_OPT_WORDS 32 - mutex_t svc_door_mutex = DEFAULTMUTEX; cond_t svc_door_waitcv = DEFAULTCV; int svc_ndoorfds = 0; diff --git a/usr/src/lib/libnsl/rpc/svcauth_des.c b/usr/src/lib/libnsl/rpc/svcauth_des.c index b437457052..fd0b9abbb5 100644 --- a/usr/src/lib/libnsl/rpc/svcauth_des.c +++ b/usr/src/lib/libnsl/rpc/svcauth_des.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -32,8 +31,6 @@ * California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * svcauth_des.c, server-side des authentication * @@ -54,6 +51,7 @@ #include <rpc/des_crypt.h> #include <rpc/rpc.h> #include <sys/types.h> +#include <sys/param.h> #include <stdlib.h> #include <unistd.h> #include <string.h> @@ -63,10 +61,6 @@ extern int key_decryptsession_pk(const char *, netobj *, des_block *); -#ifndef NGROUPS -#define NGROUPS 16 -#endif - #define USEC_PER_SEC ((ulong_t)1000000L) #define BEFORE(t1, t2) timercmp(t1, t2, < /* EMPTY */) @@ -611,7 +605,7 @@ struct bsdcred { uid_t uid; /* cached uid */ gid_t gid; /* cached gid */ short grouplen; /* length of cached groups */ - short groups[NGROUPS]; /* cached groups */ + gid_t groups[1]; /* cached groups allocate _SC_NGROUPS_MAX */ }; static void @@ -649,7 +643,13 @@ authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid, /* LINTED pointer cast */ cred = (struct bsdcred *)_rpc_authdes_cache[sid].localcred; if (cred == NULL) { - cred = malloc(sizeof (struct bsdcred)); + static size_t bsdcred_sz; + + if (bsdcred_sz == 0) { + bsdcred_sz = sizeof (struct bsdcred) + + (sysconf(_SC_NGROUPS_MAX) - 1) * sizeof (gid_t); + } + cred = malloc(bsdcred_sz); if (cred == NULL) { __msgout2(__getucredstr, "out of memory"); (void) mutex_unlock(&authdes_lock); @@ -675,7 +675,7 @@ authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid, *gid = cred->gid = i_gid; *grouplen = cred->grouplen = i_grouplen; for (i = i_grouplen - 1; i >= 0; i--) { - cred->groups[i] = groups[i]; /* int to short */ + cred->groups[i] = groups[i]; } (void) mutex_unlock(&authdes_lock); return (1); @@ -695,7 +695,7 @@ authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid, *gid = cred->gid; *grouplen = cred->grouplen; for (i = cred->grouplen - 1; i >= 0; i--) { - groups[i] = cred->groups[i]; /* short to int */ + groups[i] = cred->groups[i]; } (void) mutex_unlock(&authdes_lock); return (1); diff --git a/usr/src/lib/libsocket/inet/rcmd.c b/usr/src/lib/libsocket/inet/rcmd.c index 6a0edcac5b..d1fdcd2418 100644 --- a/usr/src/lib/libsocket/inet/rcmd.c +++ b/usr/src/lib/libsocket/inet/rcmd.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,8 +37,6 @@ * contributors. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <limits.h> #include <stdio.h> #include <ctype.h> @@ -62,6 +60,7 @@ #include <string.h> #include <stdlib.h> #include <grp.h> +#include <alloca.h> #include <arpa/inet.h> #include <priv_utils.h> @@ -565,7 +564,8 @@ ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) char pbuf[MAXPATHLEN]; uid_t uid = (uid_t)-1; gid_t gid = (gid_t)-1; - gid_t grouplist[NGROUPS_MAX]; + int maxgrp = getgroups(0, NULL); + gid_t *grouplist = alloca(maxgrp * sizeof (gid_t)); int ngroups; sp = rhost; @@ -605,7 +605,7 @@ ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) */ gid = getegid(); uid = geteuid(); - if ((ngroups = getgroups(NGROUPS_MAX, grouplist)) == -1) + if ((ngroups = getgroups(maxgrp, grouplist)) == -1) return (-1); (void) setegid(pwd->pw_gid); diff --git a/usr/src/ucbcmd/groups/groups.c b/usr/src/ucbcmd/groups/groups.c index 396e69f744..26b0d618a8 100644 --- a/usr/src/ucbcmd/groups/groups.c +++ b/usr/src/ucbcmd/groups/groups.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -13,14 +13,13 @@ * specifies the terms and conditions for redistribution. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * groups */ #include <sys/types.h> #include <sys/param.h> +#include <alloca.h> #include <grp.h> #include <pwd.h> #include <stdio.h> @@ -36,7 +35,10 @@ main(int argc, char *argv[]) int ngroups, i; char *sep = ""; struct group *gr; - gid_t groups[NGROUPS_UMAX]; + gid_t *groups; + int maxgrp = sysconf(_SC_NGROUPS_MAX); + + groups = alloca(maxgrp * sizeof (gid_t)); if (argc > 1) { for (i = 1; i < argc; i++) @@ -44,7 +46,7 @@ main(int argc, char *argv[]) exit(0); } - ngroups = getgroups(NGROUPS_UMAX, groups); + ngroups = getgroups(maxgrp, groups); if (getpwuid(getuid()) == NULL) { (void) fprintf(stderr, "groups: could not find passwd entry\n"); exit(1); @@ -86,9 +88,9 @@ showgroups(char *user) * To avoid duplicate group entries */ if (pwgid_printed == 0) { - (void) printf("%s%s", sep, gr->gr_name); - sep = " "; - pwgid_printed = 1; + (void) printf("%s%s", sep, gr->gr_name); + sep = " "; + pwgid_printed = 1; } continue; } diff --git a/usr/src/uts/common/brand/lx/procfs/lx_proc.h b/usr/src/uts/common/brand/lx/procfs/lx_proc.h index c79e3fa590..a2bd74a817 100644 --- a/usr/src/uts/common/brand/lx/procfs/lx_proc.h +++ b/usr/src/uts/common/brand/lx/procfs/lx_proc.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LXPROC_H #define _LXPROC_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -52,7 +50,8 @@ extern "C" { #include <sys/user.h> #include <sys/t_lock.h> #include <sys/sysmacros.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> +#include <sys/priv.h> #include <sys/vnode.h> #include <sys/vfs.h> #include <sys/statvfs.h> diff --git a/usr/src/uts/common/c2/audit.c b/usr/src/uts/common/c2/audit.c index eb02448ed2..a39d9b86e3 100644 --- a/usr/src/uts/common/c2/audit.c +++ b/usr/src/uts/common/c2/audit.c @@ -60,7 +60,7 @@ #include <sys/disp.h> /* for servicing_interrupt() */ #include <sys/devpolicy.h> #include <sys/crypto/ioctladmin.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> #include <inet/kssl/kssl.h> #include <net/pfpolicy.h> @@ -2405,8 +2405,8 @@ audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun, nszone = zone_find_by_id(netstackid_to_zoneid( ns->netstack_stackid)); if (nszone != NULL) { - if (strncmp(cred->cr_zone->zone_name, nszone->zone_name, - ZONENAME_MAX) != 0) { + if (strncmp(crgetzone(cred)->zone_name, + nszone->zone_name, ZONENAME_MAX) != 0) { token_t *ztoken; ztoken = au_to_zonename(0, nszone); diff --git a/usr/src/uts/common/c2/audit_start.c b/usr/src/uts/common/c2/audit_start.c index 98fe62f823..7f9471c1ff 100644 --- a/usr/src/uts/common/c2/audit_start.c +++ b/usr/src/uts/common/c2/audit_start.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,7 +39,7 @@ #include <sys/systm.h> #include <sys/pathname.h> #include <sys/debug.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> #include <sys/zone.h> #include <c2/audit.h> #include <c2/audit_kernel.h> diff --git a/usr/src/uts/common/c2/audit_syscalls.c b/usr/src/uts/common/c2/audit_syscalls.c index 2e930f12b3..87c0c50d48 100644 --- a/usr/src/uts/common/c2/audit_syscalls.c +++ b/usr/src/uts/common/c2/audit_syscalls.c @@ -36,7 +36,7 @@ #include <sys/vfs.h> #include <sys/session.h> /* for session structure (auditctl(2) */ #include <sys/kmem.h> /* for KM_SLEEP */ -#include <sys/cred_impl.h> +#include <sys/cred.h> #include <sys/types.h> #include <sys/proc.h> #include <sys/uio.h> diff --git a/usr/src/uts/common/conf/param.c b/usr/src/uts/common/conf/param.c index ac5d99a76f..e6d77020a6 100644 --- a/usr/src/uts/common/conf/param.c +++ b/usr/src/uts/common/conf/param.c @@ -713,8 +713,17 @@ param_check(void) physmem = original_physmem; } #endif - if (ngroups_max < NGROUPS_UMIN || ngroups_max > NGROUPS_UMAX) - ngroups_max = NGROUPS_MAX_DEFAULT; + if (ngroups_max < NGROUPS_UMIN) + ngroups_max = NGROUPS_UMIN; + if (ngroups_max > NGROUPS_UMAX) + ngroups_max = NGROUPS_UMAX; + + /* If we have many groups then the ucred proto message also grows. */ + if (ngroups_max > NGROUPS_OLDMAX && + strctlsz < (ngroups_max - NGROUPS_OLDMAX) * sizeof (gid_t) + 1024) { + strctlsz = (ngroups_max - NGROUPS_OLDMAX) * sizeof (gid_t) + + 1024; + } if (autoup <= 0) { autoup = DEFAULT_AUTOUP; diff --git a/usr/src/uts/common/fs/dev/sdev_vnops.c b/usr/src/uts/common/fs/dev/sdev_vnops.c index 51db9fd51f..6519dd32ca 100644 --- a/usr/src/uts/common/fs/dev/sdev_vnops.c +++ b/usr/src/uts/common/fs/dev/sdev_vnops.c @@ -51,7 +51,6 @@ #include <sys/errno.h> #include <sys/stat.h> #include <sys/cred.h> -#include <sys/cred_impl.h> #include <sys/dirent.h> #include <sys/pathname.h> #include <sys/cmn_err.h> diff --git a/usr/src/uts/common/fs/nfs/nfs_subr.c b/usr/src/uts/common/fs/nfs/nfs_subr.c index f38854ab54..bad4e8be77 100644 --- a/usr/src/uts/common/fs/nfs/nfs_subr.c +++ b/usr/src/uts/common/fs/nfs/nfs_subr.c @@ -26,7 +26,7 @@ #include <sys/param.h> #include <sys/types.h> #include <sys/systm.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> #include <sys/proc.h> #include <sys/user.h> #include <sys/time.h> diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c index 102b57fe28..f1dcd57ea3 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c @@ -50,7 +50,6 @@ #include <sys/stropts.h> #include <sys/socketvar.h> #include <sys/cred.h> -#include <sys/cred_impl.h> #include <netinet/in.h> #include <inet/ip.h> #include <inet/ip6.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree.c b/usr/src/uts/common/fs/smbsrv/smb_tree.c index 48e412345e..cc9ede2048 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_tree.c +++ b/usr/src/uts/common/fs/smbsrv/smb_tree.c @@ -169,7 +169,7 @@ #include <sys/vfs.h> #include <sys/stat.h> #include <sys/varargs.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> #include <smbsrv/smb_kproto.h> #include <smbsrv/lmerr.h> #include <smbsrv/smb_fsops.h> @@ -1268,7 +1268,7 @@ smb_tree_set_execsub_info(smb_tree_t *tree, smb_execsub_info_t *subs) subs->e_srv_ipaddr = tree->t_session->local_ipaddr; subs->e_cli_ipaddr = tree->t_session->ipaddr; subs->e_cli_netbiosname = tree->t_session->workstation; - subs->e_uid = tree->t_user->u_cred->cr_uid; + subs->e_uid = crgetuid(tree->t_user->u_cred); } /* diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index d0d571e519..69516d041c 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -73,7 +73,7 @@ #include <sys/zfs_rlock.h> #include <sys/extdirent.h> #include <sys/kidmap.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> #include <sys/attr.h> /* diff --git a/usr/src/uts/common/inet/ip/conn_opt.c b/usr/src/uts/common/inet/ip/conn_opt.c index 2b4cd6a951..b94c7b8dbd 100644 --- a/usr/src/uts/common/inet/ip/conn_opt.c +++ b/usr/src/uts/common/inet/ip/conn_opt.c @@ -221,7 +221,8 @@ conn_recvancillary_size(conn_t *connp, crb_t recv_ancillary, IP_STAT(ipst, conn_in_recvdstopts); } if (recv_ancillary.crb_recvucred && ira->ira_cred != NULL) { - ancil_size += sizeof (struct T_opthdr) + ucredsize; + ancil_size += sizeof (struct T_opthdr) + + ucredminsize(ira->ira_cred); IP_STAT(ipst, conn_in_recvucred); } @@ -527,7 +528,8 @@ conn_recvancillary_add(conn_t *connp, crb_t recv_ancillary, toh = (struct T_opthdr *)ancil_buf; toh->level = SOL_SOCKET; toh->name = SCM_UCRED; - toh->len = sizeof (struct T_opthdr) + ucredsize; + toh->len = sizeof (struct T_opthdr) + + ucredminsize(ira->ira_cred); toh->status = 0; (void) cred2ucred(ira->ira_cred, ira->ira_cpid, &toh[1], rcr); ancil_buf += toh->len; diff --git a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c index 69a064b327..bd3884b53e 100644 --- a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c +++ b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c @@ -22,7 +22,6 @@ static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.62.2.19 2005/07/13 21 #include <sys/systm.h> #include <sys/strsubr.h> #include <sys/cred.h> -#include <sys/cred_impl.h> #include <sys/ddi.h> #include <sys/sunddi.h> #include <sys/ksynch.h> @@ -554,7 +553,7 @@ int *rp; return EBUSY; } - error = fr_ioctlswitch(unit, (caddr_t)data, cmd, mode, cp->cr_uid, + error = fr_ioctlswitch(unit, (caddr_t)data, cmd, mode, crgetuid(cp), curproc, ifs); if (error != -1) { RWLOCK_EXIT(&ifs->ifs_ipf_global); @@ -759,12 +758,12 @@ int *rp; #endif break; case SIOCIPFITER : - error = ipf_frruleiter((caddr_t)data, cp->cr_uid, + error = ipf_frruleiter((caddr_t)data, crgetuid(cp), curproc, ifs); break; case SIOCGENITER : - error = ipf_genericiter((caddr_t)data, cp->cr_uid, + error = ipf_genericiter((caddr_t)data, crgetuid(cp), curproc, ifs); break; @@ -773,7 +772,7 @@ int *rp; if (error != 0) { error = EFAULT; } else { - error = ipf_deltoken(tmp, cp->cr_uid, curproc, ifs); + error = ipf_deltoken(tmp, crgetuid(cp), curproc, ifs); } break; diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c index de54c3a5ab..545eb7771a 100644 --- a/usr/src/uts/common/inet/udp/udp.c +++ b/usr/src/uts/common/inet/udp/udp.c @@ -1779,7 +1779,7 @@ udp_do_opt_set(conn_opt_arg_t *coa, int level, int name, break; ucr = (struct ucred_s *)invalp; - if (inlen != ucredsize || + if (inlen < sizeof (*ucr) + sizeof (bslabel_t) || ucr->uc_labeloff < sizeof (*ucr) || ucr->uc_labeloff + sizeof (bslabel_t) > inlen) return (EINVAL); diff --git a/usr/src/uts/common/inet/udp/udp_opt_data.c b/usr/src/uts/common/inet/udp/udp_opt_data.c index 2e22317413..c279bb4a21 100644 --- a/usr/src/uts/common/inet/udp/udp_opt_data.c +++ b/usr/src/uts/common/inet/udp/udp_opt_data.c @@ -84,7 +84,14 @@ opdes_t udp_opt_arr[] = { 0 }, { SO_MAC_IMPLICIT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, -{ SCM_UCRED, SOL_SOCKET, OA_W, OA_W, OP_NP, OP_VARLEN|OP_NODEFAULT, 512, 0 }, +/* + * The maximum size reported here depends on the maximum value for + * ucredsize; unfortunately, we can't add ucredsize here so we need + * to estimate here. Before it was 512 or 384 + NGROUPS_UMAX * sizeof (gid_t); + * as we're changing NGROUPS_UMAX we now codify this here using NGROUPS_UMAX. + */ +{ SCM_UCRED, SOL_SOCKET, OA_W, OA_W, OP_NP, OP_VARLEN|OP_NODEFAULT, + 384 + NGROUPS_UMAX * sizeof (gid_t), 0 }, { SO_EXCLBIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 }, { SO_DOMAIN, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 }, { SO_PROTOTYPE, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 }, diff --git a/usr/src/uts/common/io/tl.c b/usr/src/uts/common/io/tl.c index 83f8cf6944..353d536daf 100644 --- a/usr/src/uts/common/io/tl.c +++ b/usr/src/uts/common/io/tl.c @@ -3059,6 +3059,8 @@ tl_conn_req_ser(mblk_t *mp, tl_endpt_t *tep) t_scalar_t ooff = creq->OPT_offset; size_t ci_msz; size_t size; + cred_t *cr = NULL; + pid_t cpid; if (tep->te_closing) { TL_UNCONNECT(tep->te_oconp); @@ -3100,16 +3102,20 @@ tl_conn_req_ser(mblk_t *mp, tl_endpt_t *tep) /* * calculate length of T_CONN_IND message */ - if (peer_tep->te_flag & TL_SETCRED) { - ooff = 0; - olen = (t_scalar_t) sizeof (struct opthdr) + - OPTLEN(sizeof (tl_credopt_t)); - /* 1 option only */ - } else if (peer_tep->te_flag & TL_SETUCRED) { - ooff = 0; - olen = (t_scalar_t)sizeof (struct opthdr) + - OPTLEN(ucredsize); - /* 1 option only */ + if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED)) { + cr = msg_getcred(mp, &cpid); + ASSERT(cr != NULL); + if (peer_tep->te_flag & TL_SETCRED) { + ooff = 0; + olen = (t_scalar_t) sizeof (struct opthdr) + + OPTLEN(sizeof (tl_credopt_t)); + /* 1 option only */ + } else { + ooff = 0; + olen = (t_scalar_t)sizeof (struct opthdr) + + OPTLEN(ucredminsize(cr)); + /* 1 option only */ + } } ci_msz = sizeof (struct T_conn_ind) + tep->te_alen; ci_msz = T_ALIGN(ci_msz) + olen; @@ -3247,14 +3253,10 @@ tl_conn_req_ser(mblk_t *mp, tl_endpt_t *tep) addr_startp = cimp->b_rptr + ci->SRC_offset; bcopy(tep->te_abuf, addr_startp, tep->te_alen); if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED)) { - cred_t *cr; - pid_t cpid; ci->OPT_offset = (t_scalar_t)T_ALIGN(ci->SRC_offset + ci->SRC_length); ci->OPT_length = olen; /* because only 1 option */ - cr = msg_getcred(cimp, &cpid); - ASSERT(cr != NULL); tl_fill_option(cimp->b_rptr + ci->OPT_offset, cr, cpid, peer_tep->te_flag, peer_tep->te_credp); @@ -3591,7 +3593,7 @@ tl_conn_res(mblk_t *mp, tl_endpt_t *tep) OPTLEN(sizeof (tl_credopt_t)); } else if (cl_ep->te_flag & TL_SETUCRED) { olen = (t_scalar_t)sizeof (struct opthdr) + - OPTLEN(ucredsize); + OPTLEN(ucredminsize(acc_ep->te_credp)); } size = T_ALIGN(sizeof (struct T_conn_con) + acc_ep->te_alen) + olen; @@ -4989,6 +4991,8 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep) ssize_t msz, ui_sz; t_scalar_t alen, aoff, olen, ooff; t_scalar_t oldolen = 0; + cred_t *cr = NULL; + pid_t cpid; udreq = (struct T_unitdata_req *)mp->b_rptr; msz = MBLKL(mp); @@ -5159,19 +5163,25 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep) /* * calculate length of message */ - if (peer_tep->te_flag & TL_SETCRED) { - ASSERT(olen == 0); - olen = (t_scalar_t)sizeof (struct opthdr) + - OPTLEN(sizeof (tl_credopt_t)); - /* 1 option only */ - } else if (peer_tep->te_flag & TL_SETUCRED) { - ASSERT(olen == 0); - olen = (t_scalar_t)sizeof (struct opthdr) + OPTLEN(ucredsize); - /* 1 option only */ - } else if (peer_tep->te_flag & TL_SOCKUCRED) { - /* Possibly more than one option */ - olen += (t_scalar_t)sizeof (struct T_opthdr) + - OPTLEN(ucredsize); + if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED|TL_SOCKUCRED)) { + cr = msg_getcred(mp, &cpid); + ASSERT(cr != NULL); + + if (peer_tep->te_flag & TL_SETCRED) { + ASSERT(olen == 0); + olen = (t_scalar_t)sizeof (struct opthdr) + + OPTLEN(sizeof (tl_credopt_t)); + /* 1 option only */ + } else if (peer_tep->te_flag & TL_SETUCRED) { + ASSERT(olen == 0); + olen = (t_scalar_t)sizeof (struct opthdr) + + OPTLEN(ucredminsize(cr)); + /* 1 option only */ + } else { + /* Possibly more than one option */ + olen += (t_scalar_t)sizeof (struct T_opthdr) + + OPTLEN(ucredminsize(cr)); + } } ui_sz = T_ALIGN(sizeof (struct T_unitdata_ind) + tep->te_alen) + @@ -5217,8 +5227,6 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep) (t_scalar_t)T_ALIGN(udind->SRC_offset + udind->SRC_length); udind->OPT_length = olen; if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED|TL_SOCKUCRED)) { - cred_t *cr; - pid_t cpid; if (oldolen != 0) { bcopy((void *)((uintptr_t)udreq + ooff), @@ -5226,7 +5234,6 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep) udind->OPT_offset), oldolen); } - cr = msg_getcred(mp, &cpid); ASSERT(cr != NULL); tl_fill_option(ui_mp->b_rptr + udind->OPT_offset + @@ -5981,7 +5988,7 @@ tl_fill_option(uchar_t *buf, cred_t *cr, pid_t cpid, int flag, cred_t *pcr) opt->level = TL_PROT_LEVEL; opt->name = TL_OPT_PEER_UCRED; - opt->len = (t_uscalar_t)OPTLEN(ucredsize); + opt->len = (t_uscalar_t)OPTLEN(ucredminsize(cr)); (void) cred2ucred(cr, cpid, (void *)(opt + 1), pcr); } else { @@ -5990,7 +5997,7 @@ tl_fill_option(uchar_t *buf, cred_t *cr, pid_t cpid, int flag, cred_t *pcr) topt->level = SOL_SOCKET; topt->name = SCM_UCRED; - topt->len = ucredsize + sizeof (*topt); + topt->len = ucredminsize(cr) + sizeof (*topt); topt->status = 0; (void) cred2ucred(cr, cpid, (void *)(topt + 1), pcr); } diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c index 205ae32756..7a208b331e 100644 --- a/usr/src/uts/common/os/cred.c +++ b/usr/src/uts/common/os/cred.c @@ -62,6 +62,7 @@ #include <sys/idmap.h> #include <sys/klpd.h> #include <sys/varargs.h> +#include <util/qsort.h> /* Ephemeral IDs Zones specific data */ @@ -74,6 +75,16 @@ typedef struct ephemeral_zsd { cred_t *eph_nobody; } ephemeral_zsd_t; +/* Supplemental groups list. */ +typedef struct credgrp { + uint_t crg_ref; + uint_t crg_ngroups; + gid_t crg_groups[1]; +} credgrp_t; + +static void crgrphold(credgrp_t *); + +#define CREDGRPSZ(ngrp) (sizeof (credgrp_t) + ((ngrp - 1) * sizeof (gid_t))) static kmutex_t ephemeral_zone_mutex; static zone_key_t ephemeral_zone_key; @@ -94,6 +105,7 @@ static int get_c2audit_load(void); #define REMOTE_PEER_CRED(c) ((c)->cr_gid == -1) +#define BIN_GROUP_SEARCH_CUTOFF 16 static boolean_t hasephids = B_FALSE; @@ -160,11 +172,7 @@ cred_init(void) { priv_init(); - crsize = sizeof (cred_t) + sizeof (gid_t) * (ngroups_max - 1); - /* - * Make sure it's word-aligned. - */ - crsize = (crsize + sizeof (int) - 1) & ~(sizeof (int) - 1); + crsize = sizeof (cred_t); if (get_c2audit_load() > 0) { #ifdef _LP64 @@ -251,6 +259,7 @@ cralloc_flags(int flgs) cr->cr_label = NULL; cr->cr_ksid = NULL; cr->cr_klpd = NULL; + cr->cr_grps = NULL; return (cr); } @@ -287,6 +296,7 @@ crget(void) if (cr->cr_label) label_hold(cr->cr_label); ASSERT(cr->cr_klpd == NULL); + ASSERT(cr->cr_grps == NULL); return (cr); } @@ -357,6 +367,9 @@ crfree(cred_t *cr) zone_cred_rele(cr->cr_zone); if (cr->cr_ksid) kcrsid_rele(cr->cr_ksid); + if (cr->cr_grps) + crgrprele(cr->cr_grps); + kmem_cache_free(cred_cache, cr); } } @@ -381,6 +394,8 @@ crcopy(cred_t *cr) kcrsid_hold(newcr->cr_ksid); if (newcr->cr_klpd) crklpd_hold(newcr->cr_klpd); + if (newcr->cr_grps) + crgrphold(newcr->cr_grps); crfree(cr); newcr->cr_ref = 2; /* caller gets two references */ return (newcr); @@ -405,6 +420,8 @@ crcopy_to(cred_t *oldcr, cred_t *newcr) label_hold(newcr->cr_label); if (newcr->cr_klpd) crklpd_hold(newcr->cr_klpd); + if (newcr->cr_grps) + crgrphold(newcr->cr_grps); if (nkcr) { newcr->cr_ksid = nkcr; kcrsidcopy_to(oldcr->cr_ksid, newcr->cr_ksid); @@ -437,6 +454,8 @@ crdup_flags(const cred_t *cr, int flgs) crklpd_hold(newcr->cr_klpd); if (newcr->cr_ksid) kcrsid_hold(newcr->cr_ksid); + if (newcr->cr_grps) + crgrphold(newcr->cr_grps); newcr->cr_ref = 1; return (newcr); } @@ -465,6 +484,8 @@ crdup_to(cred_t *oldcr, cred_t *newcr) label_hold(newcr->cr_label); if (newcr->cr_klpd) crklpd_hold(newcr->cr_klpd); + if (newcr->cr_grps) + crgrphold(newcr->cr_grps); if (nkcr) { newcr->cr_ksid = nkcr; kcrsidcopy_to(oldcr->cr_ksid, newcr->cr_ksid); @@ -519,12 +540,38 @@ groupmember(gid_t gid, const cred_t *cr) int supgroupmember(gid_t gid, const cred_t *cr) { + int hi, lo; + credgrp_t *grps = cr->cr_grps; const gid_t *gp, *endgp; - endgp = &cr->cr_groups[cr->cr_ngroups]; - for (gp = cr->cr_groups; gp < endgp; gp++) - if (*gp == gid) + if (grps == NULL) + return (0); + + /* For a small number of groups, use sequentials search. */ + if (grps->crg_ngroups <= BIN_GROUP_SEARCH_CUTOFF) { + endgp = &grps->crg_groups[grps->crg_ngroups]; + for (gp = grps->crg_groups; gp < endgp; gp++) + if (*gp == gid) + return (1); + return (0); + } + + /* We use binary search when we have many groups. */ + lo = 0; + hi = grps->crg_ngroups - 1; + gp = grps->crg_groups; + + do { + int m = (lo + hi) / 2; + + if (gid > gp[m]) + lo = m + 1; + else if (gid < gp[m]) + hi = m - 1; + else return (1); + } while (lo <= hi); + return (0); } @@ -603,6 +650,7 @@ prochasprocperm(proc_t *tp, proc_t *sp, const cred_t *scrp) int crcmp(const cred_t *cr1, const cred_t *cr2) { + credgrp_t *grp1, *grp2; if (cr1 == cr2) return (0); @@ -611,10 +659,12 @@ crcmp(const cred_t *cr1, const cred_t *cr2) cr1->cr_gid == cr2->cr_gid && cr1->cr_ruid == cr2->cr_ruid && cr1->cr_rgid == cr2->cr_rgid && - cr1->cr_ngroups == cr2->cr_ngroups && cr1->cr_zone == cr2->cr_zone && - bcmp(cr1->cr_groups, cr2->cr_groups, - cr1->cr_ngroups * sizeof (gid_t)) == 0) { + ((grp1 = cr1->cr_grps) == (grp2 = cr2->cr_grps) || + (grp1 != NULL && grp2 != NULL && + grp1->crg_ngroups == grp2->crg_ngroups && + bcmp(grp1->crg_groups, grp2->crg_groups, + grp1->crg_ngroups * sizeof (gid_t)) == 0))) { return (!priv_isequalset(&CR_OEPRIV(cr1), &CR_OEPRIV(cr2))); } return (1); @@ -764,6 +814,20 @@ crsetugid(cred_t *cr, uid_t uid, gid_t gid) return (0); } +static int +gidcmp(const void *v1, const void *v2) +{ + gid_t g1 = *(gid_t *)v1; + gid_t g2 = *(gid_t *)v2; + + if (g1 < g2) + return (-1); + else if (g1 > g2) + return (1); + else + return (0); +} + int crsetgroups(cred_t *cr, int n, gid_t *grp) { @@ -772,10 +836,18 @@ crsetgroups(cred_t *cr, int n, gid_t *grp) if (n > ngroups_max || n < 0) return (-1); - cr->cr_ngroups = n; + if (cr->cr_grps != NULL) + crgrprele(cr->cr_grps); - if (n > 0) - bcopy(grp, cr->cr_groups, n * sizeof (gid_t)); + if (n > 0) { + cr->cr_grps = kmem_alloc(CREDGRPSZ(n), KM_SLEEP); + bcopy(grp, cr->cr_grps->crg_groups, n * sizeof (gid_t)); + cr->cr_grps->crg_ref = 1; + cr->cr_grps->crg_ngroups = n; + qsort(cr->cr_grps->crg_groups, n, sizeof (gid_t), gidcmp); + } else { + cr->cr_grps = NULL; + } return (0); } @@ -788,19 +860,21 @@ crsetprojid(cred_t *cr, projid_t projid) } /* - * This routine returns the pointer to the first element of the cr_groups + * This routine returns the pointer to the first element of the crg_groups * array. It can move around in an implementation defined way. + * Note that when we have no grouplist, we return one element but the + * caller should never reference it. */ const gid_t * crgetgroups(const cred_t *cr) { - return (cr->cr_groups); + return (cr->cr_grps == NULL ? &cr->cr_gid : cr->cr_grps->crg_groups); } int crgetngroups(const cred_t *cr) { - return (cr->cr_ngroups); + return (cr->cr_grps == NULL ? 0 : cr->cr_grps->crg_ngroups); } void @@ -812,12 +886,12 @@ cred2prcred(const cred_t *cr, prcred_t *pcrp) pcrp->pr_egid = cr->cr_gid; pcrp->pr_rgid = cr->cr_rgid; pcrp->pr_sgid = cr->cr_sgid; - pcrp->pr_ngroups = MIN(cr->cr_ngroups, (uint_t)ngroups_max); - pcrp->pr_groups[0] = 0; /* in case ngroups == 0 */ + pcrp->pr_groups[0] = 0; /* in case ngroups == 0 */ + pcrp->pr_ngroups = cr->cr_grps == NULL ? 0 : cr->cr_grps->crg_ngroups; if (pcrp->pr_ngroups != 0) - bcopy(cr->cr_groups, pcrp->pr_groups, - sizeof (gid_t) * cr->cr_ngroups); + bcopy(cr->cr_grps->crg_groups, pcrp->pr_groups, + sizeof (gid_t) * pcrp->pr_ngroups); } static int @@ -867,49 +941,77 @@ struct ucred_s * cred2ucred(const cred_t *cr, pid_t pid, void *buf, const cred_t *rcr) { struct ucred_s *uc; + uint32_t realsz = ucredminsize(cr); + ts_label_t *tslp = is_system_labeled() ? crgetlabel(cr) : NULL; /* The structure isn't always completely filled in, so zero it */ if (buf == NULL) { - uc = kmem_zalloc(ucredsize, KM_SLEEP); + uc = kmem_zalloc(realsz, KM_SLEEP); } else { - bzero(buf, ucredsize); + bzero(buf, realsz); uc = buf; } - uc->uc_size = ucredsize; - uc->uc_credoff = UCRED_CRED_OFF; - uc->uc_privoff = UCRED_PRIV_OFF; - uc->uc_audoff = UCRED_AUD_OFF; - uc->uc_labeloff = UCRED_LABEL_OFF; + uc->uc_size = realsz; uc->uc_pid = pid; uc->uc_projid = cr->cr_projid; uc->uc_zoneid = crgetzoneid(cr); - /* - * Note that cred2uclabel() call should not be factored out - * to the bottom of the if-else. UCXXX() macros depend on - * uc_xxxoff values to work correctly. - */ if (REMOTE_PEER_CRED(cr)) { /* - * other than label, the rest of cred info about a - * remote peer isn't available. + * Other than label, the rest of cred info about a + * remote peer isn't available. Copy the label directly + * after the header where we generally copy the prcred. + * That's why we use sizeof (struct ucred_s). The other + * offset fields are initialized to 0. */ - cred2uclabel(cr, UCLABEL(uc)); - uc->uc_credoff = 0; - uc->uc_privoff = 0; - uc->uc_audoff = 0; + uc->uc_labeloff = tslp == NULL ? 0 : sizeof (struct ucred_s); } else { + uc->uc_credoff = UCRED_CRED_OFF; + uc->uc_privoff = UCRED_PRIV_OFF; + uc->uc_audoff = UCRED_AUD_OFF; + uc->uc_labeloff = tslp == NULL ? 0 : UCRED_LABEL_OFF; + cred2prcred(cr, UCCRED(uc)); cred2prpriv(cr, UCPRIV(uc)); + if (audoff == 0 || cred2ucaud(cr, UCAUD(uc), rcr) != 0) uc->uc_audoff = 0; - cred2uclabel(cr, UCLABEL(uc)); } + if (tslp != NULL) + bcopy(&tslp->tsl_label, UCLABEL(uc), sizeof (bslabel_t)); return (uc); } /* + * Don't allocate the non-needed group entries. Note: this function + * must match the code in cred2ucred; they must agree about the + * minimal size of the ucred. + */ +uint32_t +ucredminsize(const cred_t *cr) +{ + int ndiff; + + if (cr == NULL) + return (ucredsize); + + if (REMOTE_PEER_CRED(cr)) { + if (is_system_labeled()) + return (sizeof (struct ucred_s) + sizeof (bslabel_t)); + else + return (sizeof (struct ucred_s)); + } + + if (cr->cr_grps == NULL) + ndiff = ngroups_max - 1; /* Needs one for prcred_t */ + else + ndiff = ngroups_max - cr->cr_grps->crg_ngroups; + + return (ucredsize - ndiff * sizeof (gid_t)); +} + +/* * Get the "ucred" of a process. */ struct ucred_s * @@ -1326,3 +1428,52 @@ crsetcrklpd(cred_t *cr, struct credklpd *crklpd) crklpd_rele(cr->cr_klpd); cr->cr_klpd = crklpd; } + +credgrp_t * +crgrpcopyin(int n, gid_t *gidset) +{ + credgrp_t *mem; + size_t sz = CREDGRPSZ(n); + + ASSERT(n > 0); + + mem = kmem_alloc(sz, KM_SLEEP); + + if (copyin(gidset, mem->crg_groups, sizeof (gid_t) * n)) { + kmem_free(mem, sz); + return (NULL); + } + mem->crg_ref = 1; + mem->crg_ngroups = n; + return (mem); +} + +const gid_t * +crgetggroups(const credgrp_t *grps) +{ + return (grps->crg_groups); +} + +void +crsetcredgrp(cred_t *cr, credgrp_t *grps) +{ + ASSERT(cr->cr_ref <= 2); + + if (cr->cr_grps != NULL) + crgrprele(cr->cr_grps); + + cr->cr_grps = grps; +} + +void +crgrprele(credgrp_t *grps) +{ + if (atomic_add_32_nv(&grps->crg_ref, -1) == 0) + kmem_free(grps, CREDGRPSZ(grps->crg_ngroups)); +} + +static void +crgrphold(credgrp_t *grps) +{ + atomic_add_32(&grps->crg_ref, 1); +} diff --git a/usr/src/uts/common/rpc/auth_sys.h b/usr/src/uts/common/rpc/auth_sys.h index e3e8c1534a..214c781bac 100644 --- a/usr/src/uts/common/rpc/auth_sys.h +++ b/usr/src/uts/common/rpc/auth_sys.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -38,8 +37,6 @@ #ifndef _RPC_AUTH_SYS_H #define _RPC_AUTH_SYS_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * The system is very weak. The client uses no encryption for it * credentials and only sends null verifiers. The server sends backs @@ -48,6 +45,7 @@ */ #include <sys/types.h> +#include <sys/param.h> #include <rpc/types.h> #include <rpc/xdr.h> #include <rpc/auth.h> @@ -62,8 +60,8 @@ extern "C" { /* gids compose part of a credential; there may not be more than 16 of them */ #define NGRPS 16 -/* gids compose part of a credential; there may not be more than 64 of them */ -#define NGRPS_LOOPBACK 64 +/* gids compose part of a credential */ +#define NGRPS_LOOPBACK NGROUPS_UMAX /* * "sys" (Old UNIX) style credentials. diff --git a/usr/src/uts/common/rpc/sec/auth_kern.c b/usr/src/uts/common/rpc/sec/auth_kern.c index d7c0571515..e045c1c08f 100644 --- a/usr/src/uts/common/rpc/sec/auth_kern.c +++ b/usr/src/uts/common/rpc/sec/auth_kern.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,8 +31,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * auth_kern.c, implements UNIX style authentication parameters in the kernel. * Interfaces with svc_auth_unix on the server. See auth_unix.c for the user @@ -137,7 +134,7 @@ authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr) gp = crgetgroups(cr); gidlen = crgetngroups(cr); if (gidlen > NGRPS) - return (FALSE); + gidlen = NGRPS; gpend = &gp[gidlen-1]; namelen = (int)strlen(nodename); diff --git a/usr/src/uts/common/rpc/sec/authu_prot.c b/usr/src/uts/common/rpc/sec/authu_prot.c index 2dd53219d4..dbc719e03c 100644 --- a/usr/src/uts/common/rpc/sec/authu_prot.c +++ b/usr/src/uts/common/rpc/sec/authu_prot.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,8 +31,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * authunix_prot.c * XDR for UNIX style authentication parameters for RPC @@ -64,8 +61,8 @@ xdr_authunix_parms(XDR *xdrs, struct authunix_parms *p) xdr_int(xdrs, (int *)&(p->aup_uid)) && xdr_int(xdrs, (int *)&(p->aup_gid)) && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), - &(p->aup_len), NGRPS, sizeof (int), - (xdrproc_t)xdr_int)) { + &(p->aup_len), NGRPS, sizeof (int), + (xdrproc_t)xdr_int)) { return (TRUE); } return (FALSE); @@ -130,6 +127,10 @@ xdr_authkern(XDR *xdrs) uid = crgetuid(cr); gid = crgetgid(cr); len = crgetngroups(cr); + + if (len > NGRPS) + len = NGRPS; + groups = (caddr_t)crgetgroups(cr); now = gethrestime_sec(); if (xdr_uint32(xdrs, (uint32_t *)&now) && diff --git a/usr/src/uts/common/rpc/sec/svcauthdes.c b/usr/src/uts/common/rpc/sec/svcauthdes.c index 67cd471c4b..a2dfa41c29 100644 --- a/usr/src/uts/common/rpc/sec/svcauthdes.c +++ b/usr/src/uts/common/rpc/sec/svcauthdes.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,8 +31,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * svcauth_des.c, server-side des authentication * @@ -416,7 +414,7 @@ struct bsdcred { gid_t gid; /* cached gid */ short valid; /* valid creds */ short grouplen; /* length of cached groups */ - gid_t groups[NGROUPS_UMAX]; /* cached groups */ + gid_t groups[1]; /* cached groups - allocate ngroups_max */ }; /* @@ -508,8 +506,8 @@ authdes_cache_new(char *fullname, des_block *sessionkey, uint32_t window) { return (NULL); } - if (!(ucred = (struct bsdcred *)kmem_alloc(sizeof (struct bsdcred), - KM_NOSLEEP))) { + if (!(ucred = kmem_alloc(sizeof (struct bsdcred) + + (ngroups_max - 1) * sizeof (gid_t), KM_NOSLEEP))) { kmem_free(new->rname, strlen(fullname) + 1); kmem_cache_free(authdes_cache_handle, new); return (NULL); @@ -619,7 +617,8 @@ authdes_cache_reclaim(void *pdata) { lru_last = p->lru_prev; kmem_free(p->rname, strlen(p->rname) + 1); - kmem_free(p->localcred, sizeof (struct bsdcred)); + kmem_free(p->localcred, sizeof (struct bsdcred) + + (ngroups_max - 1) * sizeof (gid_t)); mutex_destroy(&p->lock); kmem_cache_free(authdes_cache_handle, p); @@ -667,7 +666,8 @@ sweep_cache() { lru_last = p->lru_prev; kmem_free(p->rname, strlen(p->rname) + 1); - kmem_free(p->localcred, sizeof (struct bsdcred)); + kmem_free(p->localcred, sizeof (struct bsdcred) + + (ngroups_max - 1) * sizeof (gid_t)); mutex_destroy(&p->lock); kmem_cache_free(authdes_cache_handle, p); diff --git a/usr/src/uts/common/sys/cred.h b/usr/src/uts/common/sys/cred.h index 1b07a5d6f3..5056f9a511 100644 --- a/usr/src/uts/common/sys/cred.h +++ b/usr/src/uts/common/sys/cred.h @@ -56,6 +56,7 @@ struct prcred; struct ksid; struct ksidlist; struct credklpd; +struct credgrp; struct auditinfo_addr; /* cred.h is included in audit.h */ @@ -103,6 +104,7 @@ extern struct auditinfo_addr *crgetauinfo_modifiable(cred_t *); extern uint_t crgetref(const cred_t *); extern const gid_t *crgetgroups(const cred_t *); +extern const gid_t *crgetggroups(const struct credgrp *); extern int crgetngroups(const cred_t *); @@ -119,7 +121,13 @@ extern int crsetresgid(cred_t *, gid_t, gid_t, gid_t); */ extern int crsetugid(cred_t *, uid_t, gid_t); +/* + * Functions to handle the supplemental group list. + */ extern int crsetgroups(cred_t *, int, gid_t *); +extern struct credgrp *crgrpcopyin(int, gid_t *); +extern void crgrprele(struct credgrp *); +extern void crsetcredgrp(cred_t *, struct credgrp *); /* * Private interface for setting zone association of credential. diff --git a/usr/src/uts/common/sys/cred_impl.h b/usr/src/uts/common/sys/cred_impl.h index ad70ffd868..fc2fa34e43 100644 --- a/usr/src/uts/common/sys/cred_impl.h +++ b/usr/src/uts/common/sys/cred_impl.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_CRED_IMPL_H #define _SYS_CRED_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/cred.h> #include <sys/priv_impl.h> @@ -74,15 +72,13 @@ struct cred { gid_t cr_rgid; /* real group id */ uid_t cr_suid; /* "saved" user id (from exec) */ gid_t cr_sgid; /* "saved" group id (from exec) */ - uint_t cr_ngroups; /* number of groups returned by */ - /* crgroups() */ cred_priv_t cr_priv; /* privileges */ projid_t cr_projid; /* project */ struct zone *cr_zone; /* pointer to per-zone structure */ struct ts_label_s *cr_label; /* pointer to the effective label */ struct credklpd *cr_klpd; /* pointer to the cred's klpd */ credsid_t *cr_ksid; /* pointer to SIDs */ - gid_t cr_groups[1]; /* cr_groups size not fixed */ + struct credgrp *cr_grps; /* supplemental groups */ /* audit info is defined dynamically */ /* and valid only when audit enabled */ /* auditinfo_addr_t cr_auinfo; audit info */ diff --git a/usr/src/uts/common/sys/param.h b/usr/src/uts/common/sys/param.h index 0279968fc8..2c3f632811 100644 --- a/usr/src/uts/common/sys/param.h +++ b/usr/src/uts/common/sys/param.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -119,7 +119,8 @@ extern "C" { * configurable parameter NGROUPS_MAX. */ #define NGROUPS_UMIN 0 -#define NGROUPS_UMAX 32 +#define NGROUPS_UMAX 1024 +#define NGROUPS_OLDMAX 32 /* * NGROUPS_MAX_DEFAULT: *MUST* match NGROUPS_MAX value in limits.h. diff --git a/usr/src/uts/common/sys/ucred.h b/usr/src/uts/common/sys/ucred.h index c7247baafa..6f8f77832b 100644 --- a/usr/src/uts/common/sys/ucred.h +++ b/usr/src/uts/common/sys/ucred.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * File with private definitions for the ucred structure for use by the @@ -29,8 +29,6 @@ #ifndef _SYS_UCRED_H #define _SYS_UCRED_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/procfs.h> #include <sys/cred.h> @@ -88,8 +86,6 @@ struct ucred_s { #define UCLABEL(uc) (bslabel_t *)(((uc)->uc_labeloff == 0) ? NULL : \ ((char *)(uc)) + (uc)->uc_labeloff) -#define UCRED_CRED_OFF (sizeof (struct ucred_s)) - #endif /* _KERNEL || _STRUCTURED_PROC != 0 */ /* @@ -100,13 +96,19 @@ struct ucred_s { #ifdef _KERNEL -extern uint32_t ucredsize; +extern uint32_t ucredminsize(const cred_t *); -#define UCRED_PRIV_OFF (UCRED_CRED_OFF + sizeof (prcred_t) + \ - (ngroups_max - 1) * sizeof (gid_t)) +#define UCRED_PRIV_OFF (sizeof (struct ucred_s)) #define UCRED_AUD_OFF (UCRED_PRIV_OFF + priv_prgetprivsize(NULL)) #define UCRED_LABEL_OFF (UCRED_AUD_OFF + get_audit_ucrsize()) -#define UCRED_SIZE (UCRED_LABEL_OFF + sizeof (bslabel_t)) + +/* The prcred_t has a variable size; it should be last. */ +#define UCRED_CRED_OFF (UCRED_LABEL_OFF + \ + (is_system_labeled() ? sizeof (bslabel_t) : 0)) + +#define UCRED_SIZE (UCRED_CRED_OFF + sizeof (prcred_t) + \ + (ngroups_max - 1) * sizeof (gid_t)) + struct proc; diff --git a/usr/src/uts/common/syscall/groups.c b/usr/src/uts/common/syscall/groups.c index 3a46812f8a..17434ff36d 100644 --- a/usr/src/uts/common/syscall/groups.c +++ b/usr/src/uts/common/syscall/groups.c @@ -20,18 +20,17 @@ */ /* * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.78 */ - #include <sys/param.h> #include <sys/types.h> #include <sys/sysmacros.h> #include <sys/systm.h> -#include <sys/cred_impl.h> +#include <sys/cred.h> +#include <sys/sid.h> #include <sys/errno.h> #include <sys/proc.h> #include <sys/debug.h> @@ -45,11 +44,11 @@ setgroups(int gidsetsize, gid_t *gidset) cred_t *cr, *newcr; int i; int n = gidsetsize; - gid_t *groups = NULL; int error; int scnt = 0; ksidlist_t *ksl = NULL; zone_t *zone; + struct credgrp *grps = NULL; /* Perform the cheapest tests before grabbing p_crlock */ if (n > ngroups_max || n < 0) @@ -57,25 +56,27 @@ setgroups(int gidsetsize, gid_t *gidset) zone = crgetzone(CRED()); if (n != 0) { - groups = kmem_alloc(n * sizeof (gid_t), KM_SLEEP); + const gid_t *groups; + + grps = crgrpcopyin(n, gidset); - if (copyin(gidset, groups, n * sizeof (gid_t)) != 0) { - kmem_free(groups, n * sizeof (gid_t)); + if (grps == NULL) return (set_errno(EFAULT)); - } + + groups = crgetggroups(grps); for (i = 0; i < n; i++) { if (!VALID_GID(groups[i], zone)) { - kmem_free(groups, n * sizeof (gid_t)); + crgrprele(grps); return (set_errno(EINVAL)); } if (groups[i] > MAXUID) scnt++; } if (scnt > 0) { - ksl = kcrsid_gidstosids(zone, n, groups); + ksl = kcrsid_gidstosids(zone, n, (gid_t *)groups); if (ksl == NULL) { - kmem_free(groups, n * sizeof (gid_t)); + crgrprele(grps); return (set_errno(EINVAL)); } } @@ -95,8 +96,8 @@ retry: mutex_exit(&p->p_crlock); if ((error = secpolicy_allow_setid(cr, -1, B_FALSE)) != 0) { - if (groups != NULL) - kmem_free(groups, n * sizeof (gid_t)); + if (grps != NULL) + crgrprele(grps); if (ksl != NULL) ksidlist_rele(ksl); crfree(newcr); @@ -110,13 +111,7 @@ retry: crdup_to(cr, newcr); crsetsidlist(newcr, ksl); - - if (n != 0) { - bcopy(groups, newcr->cr_groups, n * sizeof (gid_t)); - kmem_free(groups, n * sizeof (gid_t)); - } - - newcr->cr_ngroups = n; + crsetcredgrp(newcr, grps); p->p_cred = newcr; crhold(newcr); /* hold for the current thread */ @@ -138,12 +133,12 @@ getgroups(int gidsetsize, gid_t *gidset) int n; cr = curthread->t_cred; - n = (int)cr->cr_ngroups; + n = crgetngroups(cr); if (gidsetsize != 0) { if (gidsetsize < n) return (set_errno(EINVAL)); - if (copyout(cr->cr_groups, gidset, n * sizeof (gid_t))) + if (copyout(crgetgroups(cr), gidset, n * sizeof (gid_t))) return (set_errno(EFAULT)); } |