aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2016-10-07 20:03:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 21:46:30 -0400
commit81243eacfa400f5f7b89f4c2323d0de9982bb0fb (patch)
tree9f0bc53a6569fdf1de3d30a61a80386b8bbd1c1f
parent954f74bf45268bcee0af21b6393c9c8acca7e075 (diff)
cred: simpler, 1D supplementary groups
Current supplementary groups code can massively overallocate memory and is implemented in a way so that access to individual gid is done via 2D array. If number of gids is <= 32, memory allocation is more or less tolerable (140/148 bytes). But if it is not, code allocates full page (!) regardless and, what's even more fun, doesn't reuse small 32-entry array. 2D array means dependent shifts, loads and LEAs without possibility to optimize them (gid is never known at compile time). All of the above is unnecessary. Switch to the usual trailing-zero-len-array scheme. Memory is allocated with kmalloc/vmalloc() and only as much as needed. Accesses become simpler (LEA 8(gi,idx,4) or even without displacement). Maximum number of gids is 65536 which translates to 256KB+8 bytes. I think kernel can handle such allocation. On my usual desktop system with whole 9 (nine) aux groups, struct group_info shrinks from 148 bytes to 44 bytes, yay! Nice side effects: - "gi->gid[i]" is shorter than "GROUP_AT(gi, i)", less typing, - fix little mess in net/ipv4/ping.c should have been using GROUP_AT macro but this point becomes moot, - aux group allocation is persistent and should be accounted as such. Link: http://lkml.kernel.org/r/20160817201927.GA2096@p183.telecom.by Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Vasily Kulikov <segoon@openwall.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/s390/kernel/compat_linux.c4
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec.c2
-rw-r--r--fs/nfsd/auth.c6
-rw-r--r--fs/nfsd/nfs4state.c2
-rw-r--r--fs/proc/array.c2
-rw-r--r--include/linux/cred.h11
-rw-r--r--kernel/groups.c67
-rw-r--r--kernel/uid16.c4
-rw-r--r--net/ipv4/ping.c15
-rw-r--r--net/sunrpc/auth_generic.c4
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_xdr.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/auth_unix.c4
-rw-r--r--net/sunrpc/svcauth_unix.c6
14 files changed, 46 insertions, 85 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 437e61159279..0f9cd90c11af 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -189,7 +189,7 @@ static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info
189 kgid_t kgid; 189 kgid_t kgid;
190 190
191 for (i = 0; i < group_info->ngroups; i++) { 191 for (i = 0; i < group_info->ngroups; i++) {
192 kgid = GROUP_AT(group_info, i); 192 kgid = group_info->gid[i];
193 group = (u16)from_kgid_munged(user_ns, kgid); 193 group = (u16)from_kgid_munged(user_ns, kgid);
194 if (put_user(group, grouplist+i)) 194 if (put_user(group, grouplist+i))
195 return -EFAULT; 195 return -EFAULT;
@@ -213,7 +213,7 @@ static int groups16_from_user(struct group_info *group_info, u16 __user *groupli
213 if (!gid_valid(kgid)) 213 if (!gid_valid(kgid))
214 return -EINVAL; 214 return -EINVAL;
215 215
216 GROUP_AT(group_info, i) = kgid; 216 group_info->gid[i] = kgid;
217 } 217 }
218 218
219 return 0; 219 return 0;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 5d3995d5c69a..a7416cd9ac71 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -2220,7 +2220,7 @@ int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset)
2220 task_lock(current); 2220 task_lock(current);
2221 if (pud->pud_ngroups > current_ngroups) 2221 if (pud->pud_ngroups > current_ngroups)
2222 pud->pud_ngroups = current_ngroups; 2222 pud->pud_ngroups = current_ngroups;
2223 memcpy(pud->pud_groups, current_cred()->group_info->blocks[0], 2223 memcpy(pud->pud_groups, current_cred()->group_info->gid,
2224 pud->pud_ngroups * sizeof(__u32)); 2224 pud->pud_ngroups * sizeof(__u32));
2225 task_unlock(current); 2225 task_unlock(current);
2226 2226
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 9d46a0bdd9f9..62469c60be23 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -55,10 +55,10 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
55 goto oom; 55 goto oom;
56 56
57 for (i = 0; i < rqgi->ngroups; i++) { 57 for (i = 0; i < rqgi->ngroups; i++) {
58 if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i))) 58 if (gid_eq(GLOBAL_ROOT_GID, rqgi->gid[i]))
59 GROUP_AT(gi, i) = exp->ex_anon_gid; 59 gi->gid[i] = exp->ex_anon_gid;
60 else 60 else
61 GROUP_AT(gi, i) = GROUP_AT(rqgi, i); 61 gi->gid[i] = rqgi->gid[i];
62 } 62 }
63 } else { 63 } else {
64 gi = get_group_info(rqgi); 64 gi = get_group_info(rqgi);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a204d7e109d4..39bfaba9c99c 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1903,7 +1903,7 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2)
1903 if (g1->ngroups != g2->ngroups) 1903 if (g1->ngroups != g2->ngroups)
1904 return false; 1904 return false;
1905 for (i=0; i<g1->ngroups; i++) 1905 for (i=0; i<g1->ngroups; i++)
1906 if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i))) 1906 if (!gid_eq(g1->gid[i], g2->gid[i]))
1907 return false; 1907 return false;
1908 return true; 1908 return true;
1909} 1909}
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d25b44601b30..89600fd5963d 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -207,7 +207,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
207 group_info = cred->group_info; 207 group_info = cred->group_info;
208 for (g = 0; g < group_info->ngroups; g++) 208 for (g = 0; g < group_info->ngroups; g++)
209 seq_put_decimal_ull(m, g ? " " : "", 209 seq_put_decimal_ull(m, g ? " " : "",
210 from_kgid_munged(user_ns, GROUP_AT(group_info, g))); 210 from_kgid_munged(user_ns, group_info->gid[g]));
211 put_cred(cred); 211 put_cred(cred);
212 /* Trailing space shouldn't have been added in the first place. */ 212 /* Trailing space shouldn't have been added in the first place. */
213 seq_putc(m, ' '); 213 seq_putc(m, ' ');
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 257db64562e5..f0e70a1bb3ac 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -26,15 +26,10 @@ struct inode;
26/* 26/*
27 * COW Supplementary groups list 27 * COW Supplementary groups list
28 */ 28 */
29#define NGROUPS_SMALL 32
30#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(kgid_t)))
31
32struct group_info { 29struct group_info {
33 atomic_t usage; 30 atomic_t usage;
34 int ngroups; 31 int ngroups;
35 int nblocks; 32 kgid_t gid[0];
36 kgid_t small_block[NGROUPS_SMALL];
37 kgid_t *blocks[0];
38}; 33};
39 34
40/** 35/**
@@ -88,10 +83,6 @@ extern void set_groups(struct cred *, struct group_info *);
88extern int groups_search(const struct group_info *, kgid_t); 83extern int groups_search(const struct group_info *, kgid_t);
89extern bool may_setgroups(void); 84extern bool may_setgroups(void);
90 85
91/* access the groups "array" with this macro */
92#define GROUP_AT(gi, i) \
93 ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
94
95/* 86/*
96 * The security context of a task 87 * The security context of a task
97 * 88 *
diff --git a/kernel/groups.c b/kernel/groups.c
index 74d431d25251..2fcadd66a8fd 100644
--- a/kernel/groups.c
+++ b/kernel/groups.c
@@ -7,55 +7,31 @@
7#include <linux/security.h> 7#include <linux/security.h>
8#include <linux/syscalls.h> 8#include <linux/syscalls.h>
9#include <linux/user_namespace.h> 9#include <linux/user_namespace.h>
10#include <linux/vmalloc.h>
10#include <asm/uaccess.h> 11#include <asm/uaccess.h>
11 12
12struct group_info *groups_alloc(int gidsetsize) 13struct group_info *groups_alloc(int gidsetsize)
13{ 14{
14 struct group_info *group_info; 15 struct group_info *gi;
15 int nblocks; 16 unsigned int len;
16 int i; 17
17 18 len = sizeof(struct group_info) + sizeof(kgid_t) * gidsetsize;
18 nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK; 19 gi = kmalloc(len, GFP_KERNEL_ACCOUNT|__GFP_NOWARN|__GFP_NORETRY);
19 /* Make sure we always allocate at least one indirect block pointer */ 20 if (!gi)
20 nblocks = nblocks ? : 1; 21 gi = __vmalloc(len, GFP_KERNEL_ACCOUNT|__GFP_HIGHMEM, PAGE_KERNEL);
21 group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER); 22 if (!gi)
22 if (!group_info)
23 return NULL; 23 return NULL;
24 group_info->ngroups = gidsetsize;
25 group_info->nblocks = nblocks;
26 atomic_set(&group_info->usage, 1);
27
28 if (gidsetsize <= NGROUPS_SMALL)
29 group_info->blocks[0] = group_info->small_block;
30 else {
31 for (i = 0; i < nblocks; i++) {
32 kgid_t *b;
33 b = (void *)__get_free_page(GFP_USER);
34 if (!b)
35 goto out_undo_partial_alloc;
36 group_info->blocks[i] = b;
37 }
38 }
39 return group_info;
40 24
41out_undo_partial_alloc: 25 atomic_set(&gi->usage, 1);
42 while (--i >= 0) { 26 gi->ngroups = gidsetsize;
43 free_page((unsigned long)group_info->blocks[i]); 27 return gi;
44 }
45 kfree(group_info);
46 return NULL;
47} 28}
48 29
49EXPORT_SYMBOL(groups_alloc); 30EXPORT_SYMBOL(groups_alloc);
50 31
51void groups_free(struct group_info *group_info) 32void groups_free(struct group_info *group_info)
52{ 33{
53 if (group_info->blocks[0] != group_info->small_block) { 34 kvfree(group_info);
54 int i;
55 for (i = 0; i < group_info->nblocks; i++)
56 free_page((unsigned long)group_info->blocks[i]);
57 }
58 kfree(group_info);
59} 35}
60 36
61EXPORT_SYMBOL(groups_free); 37EXPORT_SYMBOL(groups_free);
@@ -70,7 +46,7 @@ static int groups_to_user(gid_t __user *grouplist,
70 46
71 for (i = 0; i < count; i++) { 47 for (i = 0; i < count; i++) {
72 gid_t gid; 48 gid_t gid;
73 gid = from_kgid_munged(user_ns, GROUP_AT(group_info, i)); 49 gid = from_kgid_munged(user_ns, group_info->gid[i]);
74 if (put_user(gid, grouplist+i)) 50 if (put_user(gid, grouplist+i))
75 return -EFAULT; 51 return -EFAULT;
76 } 52 }
@@ -95,7 +71,7 @@ static int groups_from_user(struct group_info *group_info,
95 if (!gid_valid(kgid)) 71 if (!gid_valid(kgid))
96 return -EINVAL; 72 return -EINVAL;
97 73
98 GROUP_AT(group_info, i) = kgid; 74 group_info->gid[i] = kgid;
99 } 75 }
100 return 0; 76 return 0;
101} 77}
@@ -115,15 +91,14 @@ static void groups_sort(struct group_info *group_info)
115 for (base = 0; base < max; base++) { 91 for (base = 0; base < max; base++) {
116 int left = base; 92 int left = base;
117 int right = left + stride; 93 int right = left + stride;
118 kgid_t tmp = GROUP_AT(group_info, right); 94 kgid_t tmp = group_info->gid[right];
119 95
120 while (left >= 0 && gid_gt(GROUP_AT(group_info, left), tmp)) { 96 while (left >= 0 && gid_gt(group_info->gid[left], tmp)) {
121 GROUP_AT(group_info, right) = 97 group_info->gid[right] = group_info->gid[left];
122 GROUP_AT(group_info, left);
123 right = left; 98 right = left;
124 left -= stride; 99 left -= stride;
125 } 100 }
126 GROUP_AT(group_info, right) = tmp; 101 group_info->gid[right] = tmp;
127 } 102 }
128 stride /= 3; 103 stride /= 3;
129 } 104 }
@@ -141,9 +116,9 @@ int groups_search(const struct group_info *group_info, kgid_t grp)
141 right = group_info->ngroups; 116 right = group_info->ngroups;
142 while (left < right) { 117 while (left < right) {
143 unsigned int mid = (left+right)/2; 118 unsigned int mid = (left+right)/2;
144 if (gid_gt(grp, GROUP_AT(group_info, mid))) 119 if (gid_gt(grp, group_info->gid[mid]))
145 left = mid + 1; 120 left = mid + 1;
146 else if (gid_lt(grp, GROUP_AT(group_info, mid))) 121 else if (gid_lt(grp, group_info->gid[mid]))
147 right = mid; 122 right = mid;
148 else 123 else
149 return 1; 124 return 1;
diff --git a/kernel/uid16.c b/kernel/uid16.c
index d58cc4d8f0d1..cc40793464e3 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -117,7 +117,7 @@ static int groups16_to_user(old_gid_t __user *grouplist,
117 kgid_t kgid; 117 kgid_t kgid;
118 118
119 for (i = 0; i < group_info->ngroups; i++) { 119 for (i = 0; i < group_info->ngroups; i++) {
120 kgid = GROUP_AT(group_info, i); 120 kgid = group_info->gid[i];
121 group = high2lowgid(from_kgid_munged(user_ns, kgid)); 121 group = high2lowgid(from_kgid_munged(user_ns, kgid));
122 if (put_user(group, grouplist+i)) 122 if (put_user(group, grouplist+i))
123 return -EFAULT; 123 return -EFAULT;
@@ -142,7 +142,7 @@ static int groups16_from_user(struct group_info *group_info,
142 if (!gid_valid(kgid)) 142 if (!gid_valid(kgid))
143 return -EINVAL; 143 return -EINVAL;
144 144
145 GROUP_AT(group_info, i) = kgid; 145 group_info->gid[i] = kgid;
146 } 146 }
147 147
148 return 0; 148 return 0;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 66ddcb60519a..7cf7d6e380c2 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -258,7 +258,7 @@ int ping_init_sock(struct sock *sk)
258 struct net *net = sock_net(sk); 258 struct net *net = sock_net(sk);
259 kgid_t group = current_egid(); 259 kgid_t group = current_egid();
260 struct group_info *group_info; 260 struct group_info *group_info;
261 int i, j, count; 261 int i;
262 kgid_t low, high; 262 kgid_t low, high;
263 int ret = 0; 263 int ret = 0;
264 264
@@ -270,16 +270,11 @@ int ping_init_sock(struct sock *sk)
270 return 0; 270 return 0;
271 271
272 group_info = get_current_groups(); 272 group_info = get_current_groups();
273 count = group_info->ngroups; 273 for (i = 0; i < group_info->ngroups; i++) {
274 for (i = 0; i < group_info->nblocks; i++) { 274 kgid_t gid = group_info->gid[i];
275 int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
276 for (j = 0; j < cp_count; j++) {
277 kgid_t gid = group_info->blocks[i][j];
278 if (gid_lte(low, gid) && gid_lte(gid, high))
279 goto out_release_group;
280 }
281 275
282 count -= cp_count; 276 if (gid_lte(low, gid) && gid_lte(gid, high))
277 goto out_release_group;
283 } 278 }
284 279
285 ret = -EACCES; 280 ret = -EACCES;
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 168219535a34..83dffeadf20a 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -176,8 +176,8 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
176 if (gcred->acred.group_info->ngroups != acred->group_info->ngroups) 176 if (gcred->acred.group_info->ngroups != acred->group_info->ngroups)
177 goto out_nomatch; 177 goto out_nomatch;
178 for (i = 0; i < gcred->acred.group_info->ngroups; i++) { 178 for (i = 0; i < gcred->acred.group_info->ngroups; i++) {
179 if (!gid_eq(GROUP_AT(gcred->acred.group_info, i), 179 if (!gid_eq(gcred->acred.group_info->gid[i],
180 GROUP_AT(acred->group_info, i))) 180 acred->group_info->gid[i]))
181 goto out_nomatch; 181 goto out_nomatch;
182 } 182 }
183out_match: 183out_match:
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
index eeeba5adee6d..dc6fb79a361f 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
@@ -229,7 +229,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr,
229 kgid = make_kgid(&init_user_ns, tmp); 229 kgid = make_kgid(&init_user_ns, tmp);
230 if (!gid_valid(kgid)) 230 if (!gid_valid(kgid))
231 goto out_free_groups; 231 goto out_free_groups;
232 GROUP_AT(creds->cr_group_info, i) = kgid; 232 creds->cr_group_info->gid[i] = kgid;
233 } 233 }
234 234
235 return 0; 235 return 0;
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index d8582028b346..d67f7e1bc82d 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -479,7 +479,7 @@ static int rsc_parse(struct cache_detail *cd,
479 kgid = make_kgid(&init_user_ns, id); 479 kgid = make_kgid(&init_user_ns, id);
480 if (!gid_valid(kgid)) 480 if (!gid_valid(kgid))
481 goto out; 481 goto out;
482 GROUP_AT(rsci.cred.cr_group_info, i) = kgid; 482 rsci.cred.cr_group_info->gid[i] = kgid;
483 } 483 }
484 484
485 /* mech name */ 485 /* mech name */
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index a99278c984e8..a1d768a973f5 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -79,7 +79,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t
79 79
80 cred->uc_gid = acred->gid; 80 cred->uc_gid = acred->gid;
81 for (i = 0; i < groups; i++) 81 for (i = 0; i < groups; i++)
82 cred->uc_gids[i] = GROUP_AT(acred->group_info, i); 82 cred->uc_gids[i] = acred->group_info->gid[i];
83 if (i < NFS_NGROUPS) 83 if (i < NFS_NGROUPS)
84 cred->uc_gids[i] = INVALID_GID; 84 cred->uc_gids[i] = INVALID_GID;
85 85
@@ -127,7 +127,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
127 if (groups > NFS_NGROUPS) 127 if (groups > NFS_NGROUPS)
128 groups = NFS_NGROUPS; 128 groups = NFS_NGROUPS;
129 for (i = 0; i < groups ; i++) 129 for (i = 0; i < groups ; i++)
130 if (!gid_eq(cred->uc_gids[i], GROUP_AT(acred->group_info, i))) 130 if (!gid_eq(cred->uc_gids[i], acred->group_info->gid[i]))
131 return 0; 131 return 0;
132 if (groups < NFS_NGROUPS && gid_valid(cred->uc_gids[groups])) 132 if (groups < NFS_NGROUPS && gid_valid(cred->uc_gids[groups]))
133 return 0; 133 return 0;
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index dfacdc95b3f5..64af4f034de6 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -517,7 +517,7 @@ static int unix_gid_parse(struct cache_detail *cd,
517 kgid = make_kgid(&init_user_ns, gid); 517 kgid = make_kgid(&init_user_ns, gid);
518 if (!gid_valid(kgid)) 518 if (!gid_valid(kgid))
519 goto out; 519 goto out;
520 GROUP_AT(ug.gi, i) = kgid; 520 ug.gi->gid[i] = kgid;
521 } 521 }
522 522
523 ugp = unix_gid_lookup(cd, uid); 523 ugp = unix_gid_lookup(cd, uid);
@@ -564,7 +564,7 @@ static int unix_gid_show(struct seq_file *m,
564 564
565 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen); 565 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
566 for (i = 0; i < glen; i++) 566 for (i = 0; i < glen; i++)
567 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); 567 seq_printf(m, " %d", from_kgid_munged(user_ns, ug->gi->gid[i]));
568 seq_printf(m, "\n"); 568 seq_printf(m, "\n");
569 return 0; 569 return 0;
570} 570}
@@ -817,7 +817,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
817 return SVC_CLOSE; 817 return SVC_CLOSE;
818 for (i = 0; i < slen; i++) { 818 for (i = 0; i < slen; i++) {
819 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); 819 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv));
820 GROUP_AT(cred->cr_group_info, i) = kgid; 820 cred->cr_group_info->gid[i] = kgid;
821 } 821 }
822 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 822 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
823 *authp = rpc_autherr_badverf; 823 *authp = rpc_autherr_badverf;