mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 05:27:44 +00:00
Solaris: setpag should verify that ngroups will not overflow
Our ngroups management (since PAGs are still encoded as 2 groups) needs to ensure that we do not overflow what we are prepared to handle, and do not panic due to misheld mutexes if we have to return an error when handling it. FIXES 131878 (CVE-2015-3286) Change-Id: I044d5e7d3161de815b3c2dace9c211fbb4b51ffa
This commit is contained in:
parent
ef671f497e
commit
8ce4a39052
@ -77,19 +77,28 @@ setpag(cred, pagvalue, newpag, change_parent)
|
||||
gid_t *gidset;
|
||||
int ngroups, code;
|
||||
int j;
|
||||
size_t gidset_sz;
|
||||
|
||||
AFS_STATCNT(setpag);
|
||||
|
||||
gidset = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
|
||||
/* Derive gidset size from running kernel's ngroups_max;
|
||||
* default 16, but configurable up to 32 (Sol10) or
|
||||
* 1024 (Sol11).
|
||||
*/
|
||||
gidset_sz = sizeof(gidset[0]) * ngroups_max;
|
||||
|
||||
/* must use osi_Alloc, osi_AllocSmallSpace may not be enough. */
|
||||
gidset = osi_Alloc(gidset_sz);
|
||||
|
||||
mutex_enter(&curproc->p_crlock);
|
||||
ngroups = afs_getgroups(*cred, gidset);
|
||||
|
||||
if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) {
|
||||
/* We will have to shift grouplist to make room for pag */
|
||||
if ((sizeof gidset[0]) * (ngroups + 2) > AFS_SMALLOCSIZ) {
|
||||
osi_FreeSmallSpace((char *)gidset);
|
||||
return (E2BIG);
|
||||
if ((sizeof gidset[0]) * (ngroups + 2) > gidset_sz) {
|
||||
mutex_exit(&curproc->p_crlock);
|
||||
code = E2BIG;
|
||||
goto done;
|
||||
}
|
||||
for (j = ngroups - 1; j >= 0; j--) {
|
||||
gidset[j + 2] = gidset[j];
|
||||
@ -99,11 +108,11 @@ setpag(cred, pagvalue, newpag, change_parent)
|
||||
*newpag = (pagvalue == -1 ? genpag() : pagvalue);
|
||||
afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]);
|
||||
/* afs_setgroups will release curproc->p_crlock */
|
||||
if (code = afs_setgroups(cred, ngroups, gidset, change_parent)) {
|
||||
osi_FreeSmallSpace((char *)gidset);
|
||||
return (code);
|
||||
}
|
||||
osi_FreeSmallSpace((char *)gidset);
|
||||
/* exit action is same regardless of code */
|
||||
code = afs_setgroups(cred, ngroups, gidset, change_parent);
|
||||
|
||||
done:
|
||||
osi_Free((char *)gidset, gidset_sz);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user