[PATCH]Fix rpcauth in 2.2.18pre (was Re: bug in rpc code)
> " " == Hai-Pao Fan <[EMAIL PROTECTED]> writes: > Problem: > A returned address from kmalloc() can be overwritten to a wrong > place in rpcauth_lookup_credcache() routine. Hi Alan, The following patch fixes the bug in 2.2.18pre. As reported in the 2.4.0 patch on l-k, the problem is to fix both an uninitialized hash value in auth_null.c, and the use of '%' on signed values in the rpcauth hashing algorithm. Cheers, Trond diff -u --recursive --new-file linux-2.2.18pre15/include/linux/sunrpc/auth.h linux-2.2.18pre15_fixed/include/linux/sunrpc/auth.h --- linux-2.2.18pre15/include/linux/sunrpc/auth.h Fri Oct 13 11:00:28 2000 +++ linux-2.2.18pre15_fixed/include/linux/sunrpc/auth.h Fri Oct 13 11:02:32 2000 @@ -38,6 +38,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 */ diff -u --recursive --new-file linux-2.2.18pre15/net/sunrpc/auth.c linux-2.2.18pre15_fixed/net/sunrpc/auth.c --- linux-2.2.18pre15/net/sunrpc/auth.c Fri Oct 13 11:00:34 2000 +++ linux-2.2.18pre15_fixed/net/sunrpc/auth.c Fri Oct 13 11:04:42 2000 @@ -147,7 +147,7 @@ { int nr; - nr = (cred->cr_uid % RPC_CREDCACHE_NR); + nr = (cred->cr_uid & RPC_CREDCACHE_MASK); cred->cr_next = auth->au_credcache[nr]; auth->au_credcache[nr] = cred; cred->cr_count++; @@ -164,7 +164,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); @@ -197,7 +197,7 @@ struct rpc_cred **q, *cr; int nr; - nr = (cred->cr_uid % RPC_CREDCACHE_NR); + nr = (cred->cr_uid & RPC_CREDCACHE_MASK); q = >au_credcache[nr]; while ((cr = *q) != NULL) { if (cred == cr) { diff -u --recursive --new-file linux-2.2.18pre15/net/sunrpc/auth_null.c linux-2.2.18pre15_fixed/net/sunrpc/auth_null.c --- linux-2.2.18pre15/net/sunrpc/auth_null.cFri Oct 13 11:00:34 2000 +++ linux-2.2.18pre15_fixed/net/sunrpc/auth_null.c Fri Oct 13 11:02:32 2000 @@ -54,6 +54,7 @@ return NULL; cred->cr_count = 0; cred->cr_flags = RPCAUTH_CRED_UPTODATE; + cred->cr_uid = current->uid; return cred; } - 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/
[PATCH] Fix hashing in 2.4.0 rpcauth code (was Re: bug in rpc code)
> " " == 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(_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(_credcache_lock); q = >au_credcache[nr]; while ((cr = *q) != NULL) { --- include/linux/sunrpc/auth.h.origFri 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/
[PATCH] Fix hashing in 2.4.0 rpcauth code (was Re: bug in rpc code)
" " == 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.origFri 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/
[PATCH]Fix rpcauth in 2.2.18pre (was Re: bug in rpc code)
" " == Hai-Pao Fan [EMAIL PROTECTED] writes: Problem: A returned address from kmalloc() can be overwritten to a wrong place in rpcauth_lookup_credcache() routine. Hi Alan, The following patch fixes the bug in 2.2.18pre. As reported in the 2.4.0 patch on l-k, the problem is to fix both an uninitialized hash value in auth_null.c, and the use of '%' on signed values in the rpcauth hashing algorithm. Cheers, Trond diff -u --recursive --new-file linux-2.2.18pre15/include/linux/sunrpc/auth.h linux-2.2.18pre15_fixed/include/linux/sunrpc/auth.h --- linux-2.2.18pre15/include/linux/sunrpc/auth.h Fri Oct 13 11:00:28 2000 +++ linux-2.2.18pre15_fixed/include/linux/sunrpc/auth.h Fri Oct 13 11:02:32 2000 @@ -38,6 +38,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 */ diff -u --recursive --new-file linux-2.2.18pre15/net/sunrpc/auth.c linux-2.2.18pre15_fixed/net/sunrpc/auth.c --- linux-2.2.18pre15/net/sunrpc/auth.c Fri Oct 13 11:00:34 2000 +++ linux-2.2.18pre15_fixed/net/sunrpc/auth.c Fri Oct 13 11:04:42 2000 @@ -147,7 +147,7 @@ { int nr; - nr = (cred-cr_uid % RPC_CREDCACHE_NR); + nr = (cred-cr_uid RPC_CREDCACHE_MASK); cred-cr_next = auth-au_credcache[nr]; auth-au_credcache[nr] = cred; cred-cr_count++; @@ -164,7 +164,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); @@ -197,7 +197,7 @@ struct rpc_cred **q, *cr; int nr; - nr = (cred-cr_uid % RPC_CREDCACHE_NR); + nr = (cred-cr_uid RPC_CREDCACHE_MASK); q = auth-au_credcache[nr]; while ((cr = *q) != NULL) { if (cred == cr) { diff -u --recursive --new-file linux-2.2.18pre15/net/sunrpc/auth_null.c linux-2.2.18pre15_fixed/net/sunrpc/auth_null.c --- linux-2.2.18pre15/net/sunrpc/auth_null.cFri Oct 13 11:00:34 2000 +++ linux-2.2.18pre15_fixed/net/sunrpc/auth_null.c Fri Oct 13 11:02:32 2000 @@ -54,6 +54,7 @@ return NULL; cred-cr_count = 0; cred-cr_flags = RPCAUTH_CRED_UPTODATE; + cred-cr_uid = current-uid; return cred; } - 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/
bug in rpc code
Problem: A returned address from kmalloc() can be overwritten to a wrong place in rpcauth_lookup_credcache() routine. rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags) { ... if (!cred) { cred = auth->au_ops->crcreate(taskflags); } if (cred) rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) return (struct rpc_cred *) cred; } /* auth->au_ops->crcreate in rpcauth_lookup_credcache() is nul_create_cred */ nul_create_cred(int flags) { .. if (!(cred = (struct rpc_cred *) rpc_allocate(flags, sizeof(*cred /* cred->cr_uid is not initialized, =0xbf3ff3f5 in my case */ cred->cr_count = 0; .. } rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { .. nr = (cred->cr_uid % RPC_CREDCACHE_NR); auth->au_credcache[nr] = cred; /* write to a wrong place, nr=-3 in my case */ .. } Soultion: Added one line in nul_create_cred() routine. nul_create_cred(int flags) { struct rpc_cred *cred; if (!(cred = (struct rpc_cred *) rpc_allocate(flags, sizeof(*cred return NULL; cred->cr_uid = 0; << added cred->cr_count = 0; cred->cr_flags = RPCAUTH_CRED_UPTODATE; return cred; - 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/
bug in rpc code
Problem: A returned address from kmalloc() can be overwritten to a wrong place in rpcauth_lookup_credcache() routine. rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags) { ... if (!cred) { cred = auth-au_ops-crcreate(taskflags); } if (cred) rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) return (struct rpc_cred *) cred; } /* auth-au_ops-crcreate in rpcauth_lookup_credcache() is nul_create_cred */ nul_create_cred(int flags) { .. if (!(cred = (struct rpc_cred *) rpc_allocate(flags, sizeof(*cred /* cred-cr_uid is not initialized, =0xbf3ff3f5 in my case */ cred-cr_count = 0; .. } rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { .. nr = (cred-cr_uid % RPC_CREDCACHE_NR); auth-au_credcache[nr] = cred; /* write to a wrong place, nr=-3 in my case */ .. } Soultion: Added one line in nul_create_cred() routine. nul_create_cred(int flags) { struct rpc_cred *cred; if (!(cred = (struct rpc_cred *) rpc_allocate(flags, sizeof(*cred return NULL; cred-cr_uid = 0;added cred-cr_count = 0; cred-cr_flags = RPCAUTH_CRED_UPTODATE; return cred; - 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/