Page MenuHomeFreeBSD

D53772.id166512.diff
No OneTemporary

D53772.id166512.diff

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

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)

Event Timeline