Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139415299
D53772.id166512.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D53772.id166512.diff
View Options
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -526,44 +526,44 @@
}
/*
- * Final storage for supplementary groups will be returned via 'groups'.
- * '*groups' must be NULL on input, and if not equal to 'smallgroups'
- * on output, must be freed (M_TEMP) *even if* an error is returned.
+ * 'smallgroups' must be an (uninitialized) array of length CRED_SMALLGROUPS_NB.
+ * Always sets 'sc_supp_groups', either to a valid kernel-space groups array
+ * (which may or may not be 'smallgroups'), or NULL if SETCREDF_SUPP_GROUPS was
+ * not specified, or a buffer containing garbarge on copyin() failure. In the
+ * last two cases, 'sc_supp_groups_nb' is additionally set to 0.
+ * 'sc_supp_groups' must be freed (M_TEMP) if not equal to 'smallgroups' even on
+ * failure.
*/
static int
kern_setcred_copyin_supp_groups(struct setcred *const wcred,
- const u_int flags, gid_t *const smallgroups, gid_t **const groups)
+ const u_int flags, gid_t *const smallgroups)
{
- MPASS(*groups == NULL);
+ gid_t *groups;
+ int error;
- if (flags & SETCREDF_SUPP_GROUPS) {
- int error;
-
- /*
- * Check for the limit for number of groups right now in order
- * to limit the amount of bytes to copy.
- */
- if (wcred->sc_supp_groups_nb > ngroups_max)
- return (EINVAL);
-
- /*
- * Since we are going to be copying the supplementary groups
- * from userland, make room also for the effective GID right
- * now, to avoid having to allocate and copy again the
- * supplementary groups.
- */
- *groups = wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB ?
- smallgroups : malloc(wcred->sc_supp_groups_nb *
- sizeof(*groups), M_TEMP, M_WAITOK);
-
- error = copyin(wcred->sc_supp_groups, *groups,
- wcred->sc_supp_groups_nb * sizeof(*groups));
- if (error != 0)
- return (error);
- wcred->sc_supp_groups = *groups;
- } else {
+ if ((flags & SETCREDF_SUPP_GROUPS) == 0) {
wcred->sc_supp_groups_nb = 0;
wcred->sc_supp_groups = NULL;
+ return (0);
+ }
+
+ /*
+ * Check the number of groups' limit right now in order to limit the
+ * amount of bytes to copy.
+ */
+ if (wcred->sc_supp_groups_nb > ngroups_max)
+ return (EINVAL);
+
+ groups = wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB ?
+ smallgroups : malloc(wcred->sc_supp_groups_nb * sizeof(gid_t),
+ M_TEMP, M_WAITOK);
+
+ error = copyin(wcred->sc_supp_groups, groups,
+ wcred->sc_supp_groups_nb * sizeof(gid_t));
+ wcred->sc_supp_groups = groups;
+ if (error != 0) {
+ wcred->sc_supp_groups_nb = 0;
+ return (error);
}
return (0);
@@ -580,7 +580,6 @@
void *umac;
#endif
gid_t smallgroups[CRED_SMALLGROUPS_NB];
- gid_t *groups = NULL;
int error;
/*
@@ -628,8 +627,7 @@
* alternative for 32-bit compatibility as 'gid_t' has the same size
* everywhere.
*/
- error = kern_setcred_copyin_supp_groups(&wcred, flags, smallgroups,
- &groups);
+ error = kern_setcred_copyin_supp_groups(&wcred, flags, smallgroups);
if (error != 0)
goto free_groups;
@@ -647,7 +645,7 @@
}
#endif
- error = kern_setcred(td, flags, &wcred, groups);
+ error = kern_setcred(td, flags, &wcred);
#ifdef MAC
if (wcred.sc_label != NULL)
@@ -655,8 +653,8 @@
#endif
free_groups:
- if (groups != smallgroups)
- free(groups, M_TEMP);
+ if (wcred.sc_supp_groups != smallgroups)
+ free(wcred.sc_supp_groups, M_TEMP);
return (error);
}
@@ -677,24 +675,18 @@
/*
* CAUTION: This function normalizes groups in 'wcred'.
- *
- * If 'preallocated_groups' is non-NULL, it must be an already allocated array
- * of size 'wcred->sc_supp_groups_nb' containing the supplementary groups, and
- * 'wcred->sc_supp_groups' then must point to it.
*/
int
kern_setcred(struct thread *const td, const u_int flags,
- struct setcred *const wcred, gid_t *preallocated_groups)
+ struct setcred *const wcred)
{
struct proc *const p = td->td_proc;
- struct ucred *new_cred, *old_cred, *to_free_cred;
+ struct ucred *new_cred, *old_cred, *to_free_cred = NULL;
struct uidinfo *uip = NULL, *ruip = NULL;
#ifdef MAC
void *mac_set_proc_data = NULL;
bool proc_label_set = false;
#endif
- gid_t *groups = NULL;
- gid_t smallgroups[CRED_SMALLGROUPS_NB];
int error;
bool cred_set = false;
@@ -706,32 +698,18 @@
* Part 1: We allocate and perform preparatory operations with no locks.
*/
- if (flags & SETCREDF_SUPP_GROUPS) {
- if (wcred->sc_supp_groups_nb > ngroups_max)
+ if ((flags & SETCREDF_SUPP_GROUPS) != 0 &&
+ wcred->sc_supp_groups_nb > ngroups_max)
return (EINVAL);
- if (preallocated_groups != NULL) {
- groups = preallocated_groups;
- MPASS(preallocated_groups == wcred->sc_supp_groups);
- } else {
- if (wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB)
- groups = smallgroups;
- else
- groups = malloc(wcred->sc_supp_groups_nb *
- sizeof(*groups), M_TEMP, M_WAITOK);
- memcpy(groups, wcred->sc_supp_groups,
- wcred->sc_supp_groups_nb * sizeof(*groups));
- }
- }
if (flags & SETCREDF_MAC_LABEL) {
#ifdef MAC
error = mac_set_proc_prepare(td, wcred->sc_label,
&mac_set_proc_data);
if (error != 0)
- goto free_groups;
+ return (error);
#else
- error = ENOTSUP;
- goto free_groups;
+ return (ENOTSUP);
#endif
}
@@ -757,8 +735,10 @@
* Output the raw supplementary groups array for better
* traceability.
*/
- AUDIT_ARG_GROUPSET(groups, wcred->sc_supp_groups_nb);
- groups_normalize(&wcred->sc_supp_groups_nb, groups);
+ AUDIT_ARG_GROUPSET(wcred->sc_supp_groups,
+ wcred->sc_supp_groups_nb);
+ groups_normalize(&wcred->sc_supp_groups_nb,
+ wcred->sc_supp_groups);
}
/*
@@ -799,7 +779,7 @@
*/
if (flags & SETCREDF_SUPP_GROUPS)
crsetgroups_internal(new_cred, wcred->sc_supp_groups_nb,
- groups);
+ wcred->sc_supp_groups);
if (flags & SETCREDF_GID)
change_egid(new_cred, wcred->sc_gid);
if (flags & SETCREDF_RGID)
@@ -886,9 +866,7 @@
uifree(uip);
if (ruip != NULL)
uifree(ruip);
-free_groups:
- if (groups != preallocated_groups && groups != smallgroups)
- free(groups, M_TEMP); /* Deals with 'groups' being NULL. */
+
return (error);
}
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -326,7 +326,7 @@
int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
struct mbuf *control, enum uio_seg segflg);
int kern_setcred(struct thread *const td, const u_int flags,
- struct setcred *const wcred, gid_t *preallocated_groups);
+ struct setcred *const wcred);
int kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups);
int kern_setitimer(struct thread *, u_int, struct itimerval *,
struct itimerval *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 12, 8:06 PM (8 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26911246
Default Alt Text
D53772.id166512.diff (6 KB)
Attached To
Mode
D53772: setcred(): Remove an optimization for when cr_groups[0] was the egid
Attached
Detach File
Event Timeline
Log In to Comment