[PATCH] Fix hashing in 2.4.0 rpcauth code (was Re: bug in rpc code)

From: Trond Myklebust (trond.myklebust@fys.uio.no)
Date: Fri Oct 13 2000 - 04:25:40 EST


>>>>> " " == Hai-Pao Fan <haipao@mvista.com> writes:

> Problem:

> A returned address from kmalloc() can be overwritten to a wrong
> place in rpcauth_lookup_credcache() routine.

Ouch. This is a bug that's been with us since 2.1.x at least...

Linus, the problem is in fact twofold.

  1) auth_null is not initializing cred->cr_uid as it is required to
     do by the rpc_auth hashing scheme.
     The latter should really have be rewritten: we don't actually
     need hashing for auth_null, since there is nothing uid-specific
     in the credential. (Appended to the TODO list for 2.5)

  2) The hashing scheme itself uses the 'mod' a.k.a. '%' operation on
     signed quantities. This means that offsets into the hash table
     can turn negative...

The following patch should clear it up on 2.4.0. I'll send a separate
patch to Alan for inclusion into 2.2.18.

Cheers,
  Trond

--- net/sunrpc/auth_null.c.orig Mon Mar 20 17:14:04 2000
+++ net/sunrpc/auth_null.c Fri Oct 13 09:44:02 2000
@@ -54,6 +54,7 @@
                 return NULL;
         cred->cr_count = 0;
         cred->cr_flags = RPCAUTH_CRED_UPTODATE;
+ cred->cr_uid = current->uid;
 
         return cred;
 }
--- net/sunrpc/auth.c.orig Sat May 13 18:43:55 2000
+++ net/sunrpc/auth.c Fri Oct 13 10:36:54 2000
@@ -159,7 +159,7 @@
 {
         int nr;
 
- nr = (cred->cr_uid % RPC_CREDCACHE_NR);
+ nr = (cred->cr_uid & RPC_CREDCACHE_MASK);
         spin_lock(&rpc_credcache_lock);
         cred->cr_next = auth->au_credcache[nr];
         auth->au_credcache[nr] = cred;
@@ -178,7 +178,7 @@
         int nr = 0;
 
         if (!(taskflags & RPC_TASK_ROOTCREDS))
- nr = current->uid % RPC_CREDCACHE_NR;
+ nr = current->uid & RPC_CREDCACHE_MASK;
 
         if (time_before(auth->au_nextgc, jiffies))
                 rpcauth_gc_credcache(auth);
@@ -218,7 +218,7 @@
         struct rpc_cred **q, *cr;
         int nr;
 
- nr = (cred->cr_uid % RPC_CREDCACHE_NR);
+ nr = (cred->cr_uid & RPC_CREDCACHE_MASK);
         spin_lock(&rpc_credcache_lock);
         q = &auth->au_credcache[nr];
         while ((cr = *q) != NULL) {
--- include/linux/sunrpc/auth.h.orig Fri Oct 13 10:06:19 2000
+++ include/linux/sunrpc/auth.h Fri Oct 13 10:35:42 2000
@@ -43,6 +43,7 @@
  * Client authentication handle
  */
 #define RPC_CREDCACHE_NR 8
+#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1)
 struct rpc_auth {
         struct rpc_cred * au_credcache[RPC_CREDCACHE_NR];
         unsigned long au_expire; /* cache expiry interval */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Oct 15 2000 - 21:00:24 EST