Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfsd4: stricter cred comparison for setclientid/exchange_id

The typical setclientid or exchange_id will probably be performed with a
credential that maps to either root or nobody, so comparing just uid's
is unlikely to be useful. So, use everything else we can get our hands
on.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>

+21 -1
+21 -1
fs/nfsd/nfs4state.c
··· 1201 1201 return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); 1202 1202 } 1203 1203 1204 + static bool groups_equal(struct group_info *g1, struct group_info *g2) 1205 + { 1206 + int i; 1207 + 1208 + if (g1->ngroups != g2->ngroups) 1209 + return false; 1210 + for (i=0; i<g1->ngroups; i++) 1211 + if (GROUP_AT(g1, i) != GROUP_AT(g2, i)) 1212 + return false; 1213 + return true; 1214 + } 1215 + 1204 1216 /* XXX what about NGROUP */ 1205 1217 static int 1206 1218 same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1207 1219 { 1208 - return cr1->cr_uid == cr2->cr_uid; 1220 + if ((cr1->cr_uid != cr2->cr_uid) 1221 + || (cr1->cr_gid != cr2->cr_gid) 1222 + || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) 1223 + return false; 1224 + if (cr1->cr_principal == cr2->cr_principal) 1225 + return true; 1226 + if (!cr1->cr_principal || !cr2->cr_principal) 1227 + return false; 1228 + return 0 == strcmp(cr1->cr_principal, cr1->cr_principal); 1209 1229 } 1210 1230 1211 1231 static void gen_clid(struct nfs4_client *clp)