[PATCH]Fix rpcauth in 2.2.18pre (was Re: bug in rpc code)

2000-10-13 Thread Trond Myklebust

> " " == 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)

2000-10-13 Thread Trond Myklebust

> " " == 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)

2000-10-13 Thread Trond Myklebust

 " " == 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)

2000-10-13 Thread Trond Myklebust

 " " == 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

2000-10-12 Thread Hai-Pao Fan


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

2000-10-12 Thread Hai-Pao Fan


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/