>>>>> " " == Hai-Pao Fan <[EMAIL PROTECTED]> 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 [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to