Commit fc29938d authored by Ed Schouten's avatar Ed Schouten Committed by Linus Torvalds

[PATCH] lockd: remove hardcoded maximum NLM cookie length

At the moment, the NLM cookie length is fixed to 8 bytes, while 1024 is the
theoretical maximum.  FreeBSD uses 16 bytes, Mac OS X uses 20 bytes. 
Therefore we need to make the length dynamic (which I set to 32 bytes).

This patch is based on an old patch for Linux 2.4.23-pre9, which I changed
to patch properly (also added some stylish NIPQUAD fixes).

From: Neil Brown <neilb@cse.unsw.edu.au>

Further lockd tidyups.
  - NIPQUAD everywhere that is appropriate
  - use XDR_QUADLEN in more places as appropriate
  - discard QUADLEN which is a lockd-specific version of XDR_QUADLEN
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 47387472
...@@ -104,11 +104,7 @@ nlm_lookup_host(int server, struct sockaddr_in *sin, ...@@ -104,11 +104,7 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
memset(host, 0, sizeof(*host)); memset(host, 0, sizeof(*host));
addr = sin->sin_addr.s_addr; addr = sin->sin_addr.s_addr;
sprintf(host->h_name, "%d.%d.%d.%d", sprintf(host->h_name, "%u.%u.%u.%u", NIPQUAD(addr));
(unsigned char) (ntohl(addr) >> 24),
(unsigned char) (ntohl(addr) >> 16),
(unsigned char) (ntohl(addr) >> 8),
(unsigned char) (ntohl(addr) >> 0));
host->h_addr = *sin; host->h_addr = *sin;
host->h_addr.sin_port = 0; /* ouch! */ host->h_addr.sin_port = 0; /* ouch! */
......
...@@ -140,7 +140,6 @@ static u32 * ...@@ -140,7 +140,6 @@ static u32 *
xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
{ {
char buffer[20]; char buffer[20];
u32 addr = ntohl(argp->addr);
/* /*
* Use the dotted-quad IP address of the remote host as * Use the dotted-quad IP address of the remote host as
...@@ -148,8 +147,7 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) ...@@ -148,8 +147,7 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
* hostname first for whatever remote hostname it receives, * hostname first for whatever remote hostname it receives,
* so this works alright. * so this works alright.
*/ */
sprintf(buffer, "%d.%d.%d.%d", (addr>>24) & 0xff, (addr>>16) & 0xff, sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
(addr>>8) & 0xff, (addr) & 0xff);
if (!(p = xdr_encode_string(p, buffer)) if (!(p = xdr_encode_string(p, buffer))
|| !(p = xdr_encode_string(p, system_utsname.nodename))) || !(p = xdr_encode_string(p, system_utsname.nodename)))
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
......
...@@ -546,7 +546,7 @@ struct nlm_void { int dummy; }; ...@@ -546,7 +546,7 @@ struct nlm_void { int dummy; };
.pc_ressize = sizeof(struct nlm_##rest), \ .pc_ressize = sizeof(struct nlm_##rest), \
.pc_xdrressize = respsize, \ .pc_xdrressize = respsize, \
} }
#define Ck (1+8) /* cookie */ #define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */
#define No (1+1024/4) /* netobj */ #define No (1+1024/4) /* netobj */
#define St 1 /* status */ #define St 1 /* status */
#define Rg 4 /* range (offset + length) */ #define Rg 4 /* range (offset + length) */
......
...@@ -112,11 +112,11 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) ...@@ -112,11 +112,11 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove)
(long long)lock->fl.fl_end, lock->fl.fl_type); (long long)lock->fl.fl_end, lock->fl.fl_type);
for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) { for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) {
fl = &block->b_call.a_args.lock.fl; fl = &block->b_call.a_args.lock.fl;
dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%x\n", dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
block->b_file, fl->fl_pid, block->b_file, fl->fl_pid,
(long long)fl->fl_start, (long long)fl->fl_start,
(long long)fl->fl_end, fl->fl_type, (long long)fl->fl_end, fl->fl_type,
*(unsigned int*)(block->b_call.a_args.cookie.data)); nlmdbg_cookie2a(&block->b_call.a_args.cookie));
if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
if (remove) { if (remove) {
*head = block->b_next; *head = block->b_next;
...@@ -584,13 +584,13 @@ nlmsvc_grant_callback(struct rpc_task *task) ...@@ -584,13 +584,13 @@ nlmsvc_grant_callback(struct rpc_task *task)
struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client);
dprintk("lockd: GRANT_MSG RPC callback\n"); dprintk("lockd: GRANT_MSG RPC callback\n");
dprintk("callback: looking for cookie %x, host (%08x)\n", dprintk("callback: looking for cookie %s, host (%u.%u.%u.%u)\n",
*(unsigned int *)(call->a_args.cookie.data), nlmdbg_cookie2a(&call->a_args.cookie),
ntohl(peer_addr->sin_addr.s_addr)); NIPQUAD(peer_addr->sin_addr.s_addr));
if (!(block = nlmsvc_find_block(&call->a_args.cookie, peer_addr))) { if (!(block = nlmsvc_find_block(&call->a_args.cookie, peer_addr))) {
dprintk("lockd: no block for cookie %x, host (%08x)\n", dprintk("lockd: no block for cookie %s, host (%u.%u.%u.%u)\n",
*(u32 *)(call->a_args.cookie.data), nlmdbg_cookie2a(&call->a_args.cookie),
ntohl(peer_addr->sin_addr.s_addr)); NIPQUAD(peer_addr->sin_addr.s_addr));
return; return;
} }
......
...@@ -571,7 +571,7 @@ struct nlm_void { int dummy; }; ...@@ -571,7 +571,7 @@ struct nlm_void { int dummy; };
.pc_xdrressize = respsize, \ .pc_xdrressize = respsize, \
} }
#define Ck (1+8) /* cookie */ #define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */
#define St 1 /* status */ #define St 1 /* status */
#define No (1+1024/4) /* Net Obj */ #define No (1+1024/4) /* Net Obj */
#define Rg 2 /* range - offset + size */ #define Rg 2 /* range - offset + size */
......
...@@ -55,16 +55,16 @@ static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c) ...@@ -55,16 +55,16 @@ static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
c->len=4; c->len=4;
memset(c->data, 0, 4); /* hockeypux brain damage */ memset(c->data, 0, 4); /* hockeypux brain damage */
} }
else if(len<=8) else if(len<=NLM_MAXCOOKIELEN)
{ {
c->len=len; c->len=len;
memcpy(c->data, p, len); memcpy(c->data, p, len);
p+=(len+3)>>2; p+=XDR_QUADLEN(len);
} }
else else
{ {
printk(KERN_NOTICE printk(KERN_NOTICE
"lockd: bad cookie size %d (only cookies under 8 bytes are supported.)\n", len); "lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len, NLM_MAXCOOKIELEN);
return NULL; return NULL;
} }
return p; return p;
...@@ -75,7 +75,7 @@ nlm_encode_cookie(u32 *p, struct nlm_cookie *c) ...@@ -75,7 +75,7 @@ nlm_encode_cookie(u32 *p, struct nlm_cookie *c)
{ {
*p++ = htonl(c->len); *p++ = htonl(c->len);
memcpy(p, c->data, c->len); memcpy(p, c->data, c->len);
p+=(c->len+3)>>2; p+=XDR_QUADLEN(c->len);
return p; return p;
} }
...@@ -86,7 +86,7 @@ nlm_decode_fh(u32 *p, struct nfs_fh *f) ...@@ -86,7 +86,7 @@ nlm_decode_fh(u32 *p, struct nfs_fh *f)
if ((len = ntohl(*p++)) != NFS2_FHSIZE) { if ((len = ntohl(*p++)) != NFS2_FHSIZE) {
printk(KERN_NOTICE printk(KERN_NOTICE
"lockd: bad fhandle size %x (should be %d)\n", "lockd: bad fhandle size %d (should be %d)\n",
len, NFS2_FHSIZE); len, NFS2_FHSIZE);
return NULL; return NULL;
} }
...@@ -512,11 +512,11 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) ...@@ -512,11 +512,11 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
* Buffer requirements for NLM * Buffer requirements for NLM
*/ */
#define NLM_void_sz 0 #define NLM_void_sz 0
#define NLM_cookie_sz 3 /* 1 len , 2 data */ #define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
#define NLM_caller_sz 1+QUADLEN(sizeof(system_utsname.nodename)) #define NLM_caller_sz 1+XDR_QUADLEN(sizeof(system_utsname.nodename))
#define NLM_netobj_sz 1+QUADLEN(XDR_MAX_NETOBJ) #define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
/* #define NLM_owner_sz 1+QUADLEN(NLM_MAXOWNER) */ /* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */
#define NLM_fhandle_sz 1+QUADLEN(NFS2_FHSIZE) #define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE)
#define NLM_lock_sz 3+NLM_caller_sz+NLM_netobj_sz+NLM_fhandle_sz #define NLM_lock_sz 3+NLM_caller_sz+NLM_netobj_sz+NLM_fhandle_sz
#define NLM_holder_sz 4+NLM_netobj_sz #define NLM_holder_sz 4+NLM_netobj_sz
...@@ -604,3 +604,32 @@ struct rpc_program nlm_program = { ...@@ -604,3 +604,32 @@ struct rpc_program nlm_program = {
.stats = &nlm_stats, .stats = &nlm_stats,
}; };
#ifdef RPC_DEBUG
const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
{
/*
* We can get away with a static buffer because we're only
* called with BKL held.
*/
static char buf[2*NLM_MAXCOOKIELEN+1];
int i;
int len = sizeof(buf);
char *p = buf;
len--; /* allow for trailing \0 */
if (len < 3)
return "???";
for (i = 0 ; i < cookie->len ; i++) {
if (len < 2) {
strcpy(p-3, "...");
break;
}
sprintf(p, "%02x", cookie->data[i]);
p += 2;
len -= 2;
}
*p = '\0';
return buf;
}
#endif
...@@ -56,16 +56,16 @@ nlm4_decode_cookie(u32 *p, struct nlm_cookie *c) ...@@ -56,16 +56,16 @@ nlm4_decode_cookie(u32 *p, struct nlm_cookie *c)
c->len=4; c->len=4;
memset(c->data, 0, 4); /* hockeypux brain damage */ memset(c->data, 0, 4); /* hockeypux brain damage */
} }
else if(len<=8) else if(len<=NLM_MAXCOOKIELEN)
{ {
c->len=len; c->len=len;
memcpy(c->data, p, len); memcpy(c->data, p, len);
p+=(len+3)>>2; p+=XDR_QUADLEN(len);
} }
else else
{ {
printk(KERN_NOTICE printk(KERN_NOTICE
"lockd: bad cookie size %d (only cookies under 8 bytes are supported.)\n", len); "lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len, NLM_MAXCOOKIELEN);
return NULL; return NULL;
} }
return p; return p;
...@@ -76,7 +76,7 @@ nlm4_encode_cookie(u32 *p, struct nlm_cookie *c) ...@@ -76,7 +76,7 @@ nlm4_encode_cookie(u32 *p, struct nlm_cookie *c)
{ {
*p++ = htonl(c->len); *p++ = htonl(c->len);
memcpy(p, c->data, c->len); memcpy(p, c->data, c->len);
p+=(c->len+3)>>2; p+=XDR_QUADLEN(c->len);
return p; return p;
} }
...@@ -515,7 +515,7 @@ nlm4clt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) ...@@ -515,7 +515,7 @@ nlm4clt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
* Buffer requirements for NLM * Buffer requirements for NLM
*/ */
#define NLM4_void_sz 0 #define NLM4_void_sz 0
#define NLM4_cookie_sz 3 /* 1 len , 2 data */ #define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
#define NLM4_caller_sz 1+XDR_QUADLEN(NLM_MAXSTRLEN) #define NLM4_caller_sz 1+XDR_QUADLEN(NLM_MAXSTRLEN)
#define NLM4_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) #define NLM4_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
/* #define NLM4_owner_sz 1+XDR_QUADLEN(NLM4_MAXOWNER) */ /* #define NLM4_owner_sz 1+XDR_QUADLEN(NLM4_MAXOWNER) */
......
...@@ -45,4 +45,13 @@ ...@@ -45,4 +45,13 @@
#define NLMDBG_ALL 0x7fff #define NLMDBG_ALL 0x7fff
/*
* Support for printing NLM cookies in dprintk()
*/
#ifdef RPC_DEBUG
struct nlm_cookie;
/* Call this function with the BKL held (it uses a static buffer) */
extern const char *nlmdbg_cookie2a(const struct nlm_cookie *);
#endif
#endif /* LINUX_LOCKD_DEBUG_H */ #endif /* LINUX_LOCKD_DEBUG_H */
...@@ -13,10 +13,9 @@ ...@@ -13,10 +13,9 @@
#include <linux/nfs.h> #include <linux/nfs.h>
#include <linux/sunrpc/xdr.h> #include <linux/sunrpc/xdr.h>
#define NLM_MAXCOOKIELEN 32
#define NLM_MAXSTRLEN 1024 #define NLM_MAXSTRLEN 1024
#define QUADLEN(len) (((len) + 3) >> 2)
#define nlm_granted __constant_htonl(NLM_LCK_GRANTED) #define nlm_granted __constant_htonl(NLM_LCK_GRANTED)
#define nlm_lck_denied __constant_htonl(NLM_LCK_DENIED) #define nlm_lck_denied __constant_htonl(NLM_LCK_DENIED)
#define nlm_lck_denied_nolocks __constant_htonl(NLM_LCK_DENIED_NOLOCKS) #define nlm_lck_denied_nolocks __constant_htonl(NLM_LCK_DENIED_NOLOCKS)
...@@ -33,13 +32,14 @@ struct nlm_lock { ...@@ -33,13 +32,14 @@ struct nlm_lock {
}; };
/* /*
* NLM cookies. Technically they can be 1K, Nobody uses over 8 bytes * NLM cookies. Technically they can be 1K, but Linux only uses 8 bytes.
* however. * FreeBSD uses 16, Apple Mac OS X 10.3 uses 20. Therefore we set it to
* 32 bytes.
*/ */
struct nlm_cookie struct nlm_cookie
{ {
unsigned char data[8]; unsigned char data[NLM_MAXCOOKIELEN];
unsigned int len; unsigned int len;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment