Blob Blame History Raw
From: NeilBrown <neilb@suse.com>
Subject: [PATCH] sunrpc: use supplimental groups in auth hash.
Patch-mainline: not yet, under development
References: bsc#1012917

Some sites vary some supplimental groups a lot.
To avoid unduely long hash chains, include all of these
in the hash calculcation.

Also use hash_32 as it provides better results on 3.0 kernels.

Signed-off-by: NeilBrown <neilb@suse.com>
Acked-by: NeilBrown <neilb@suse.com>

---
 net/sunrpc/auth_generic.c |   17 ++++++++++++++---
 net/sunrpc/auth_unix.c    |   17 ++++++++++++++---
 2 files changed, 28 insertions(+), 6 deletions(-)

--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -81,9 +81,20 @@ static struct rpc_cred *generic_bind_cre
 static int
 generic_hash_cred(struct auth_cred *acred, unsigned int hashbits)
 {
-	return hash_64(from_kgid(&init_user_ns, acred->gid) |
-		((u64)from_kuid(&init_user_ns, acred->uid) <<
-			(sizeof(gid_t) * 8)), hashbits);
+	u32 uid = from_kuid(&init_user_ns, acred->uid);
+	u32 gid;
+	int ret = hash_32(uid, 32);
+
+	if (acred->group_info) {
+		int g;
+
+		for (g = 0; g < acred->group_info->ngroups; g++) {
+			gid = from_kgid(&init_user_ns, acred->group_info->gid[g]);
+			ret = hash_32(ret ^ gid, 32);
+		}
+	}
+	gid = from_kgid(&init_user_ns, acred->gid);
+	return hash_32(ret ^ gid, hashbits);
 }
 
 /*
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -47,9 +47,20 @@ unx_destroy(struct rpc_auth *auth)
 static int
 unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
 {
-	return hash_64(from_kgid(&init_user_ns, acred->gid) |
-		((u64)from_kuid(&init_user_ns, acred->uid) <<
-			(sizeof(gid_t) * 8)), hashbits);
+	u32 uid = from_kuid(&init_user_ns, acred->uid);
+	u32 gid;
+	int ret = hash_32(uid, 32);
+
+	if (acred->group_info) {
+		int g;
+
+		for (g = 0; g < acred->group_info->ngroups && g < UNX_NGROUPS; g++) {
+			gid = from_kgid(&init_user_ns, acred->group_info->gid[g]);
+			ret = hash_32(ret ^ gid, 32);
+		}
+	}
+	gid = from_kgid(&init_user_ns, acred->gid);
+	return hash_32(ret ^ gid, hashbits);
 }
 
 /*