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,
memset(host, 0, sizeof(*host));
addr = sin->sin_addr.s_addr;
sprintf(host->h_name, "%d.%d.%d.%d",
(unsigned char) (ntohl(addr) >> 24),
(unsigned char) (ntohl(addr) >> 16),
(unsigned char) (ntohl(addr) >> 8),
(unsigned char) (ntohl(addr) >> 0));
sprintf(host->h_name, "%u.%u.%u.%u", NIPQUAD(addr));
host->h_addr = *sin;
host->h_addr.sin_port = 0; /* ouch! */
......
......@@ -140,7 +140,6 @@ static u32 *
xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
{
char buffer[20];
u32 addr = ntohl(argp->addr);
/*
* 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)
* hostname first for whatever remote hostname it receives,
* so this works alright.
*/
sprintf(buffer, "%d.%d.%d.%d", (addr>>24) & 0xff, (addr>>16) & 0xff,
(addr>>8) & 0xff, (addr) & 0xff);
sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
if (!(p = xdr_encode_string(p, buffer))
|| !(p = xdr_encode_string(p, system_utsname.nodename)))
return ERR_PTR(-EIO);
......
......@@ -546,7 +546,7 @@ struct nlm_void { int dummy; };
.pc_ressize = sizeof(struct nlm_##rest), \
.pc_xdrressize = respsize, \
}
#define Ck (1+8) /* cookie */
#define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */
#define No (1+1024/4) /* netobj */
#define St 1 /* status */
#define Rg 4 /* range (offset + length) */
......
......@@ -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);
for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) {
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,
(long long)fl->fl_start,
(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 (remove) {
*head = block->b_next;
......@@ -584,13 +584,13 @@ nlmsvc_grant_callback(struct rpc_task *task)
struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client);
dprintk("lockd: GRANT_MSG RPC callback\n");
dprintk("callback: looking for cookie %x, host (%08x)\n",
*(unsigned int *)(call->a_args.cookie.data),
ntohl(peer_addr->sin_addr.s_addr));
dprintk("callback: looking for cookie %s, host (%u.%u.%u.%u)\n",
nlmdbg_cookie2a(&call->a_args.cookie),
NIPQUAD(peer_addr->sin_addr.s_addr));
if (!(block = nlmsvc_find_block(&call->a_args.cookie, peer_addr))) {
dprintk("lockd: no block for cookie %x, host (%08x)\n",
*(u32 *)(call->a_args.cookie.data),
ntohl(peer_addr->sin_addr.s_addr));
dprintk("lockd: no block for cookie %s, host (%u.%u.%u.%u)\n",
nlmdbg_cookie2a(&call->a_args.cookie),
NIPQUAD(peer_addr->sin_addr.s_addr));
return;
}
......
......@@ -571,7 +571,7 @@ struct nlm_void { int dummy; };
.pc_xdrressize = respsize, \
}
#define Ck (1+8) /* cookie */
#define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */
#define St 1 /* status */
#define No (1+1024/4) /* Net Obj */
#define Rg 2 /* range - offset + size */
......
......@@ -55,16 +55,16 @@ static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
c->len=4;
memset(c->data, 0, 4); /* hockeypux brain damage */
}
else if(len<=8)
else if(len<=NLM_MAXCOOKIELEN)
{
c->len=len;
memcpy(c->data, p, len);
p+=(len+3)>>2;
p+=XDR_QUADLEN(len);
}
else
{
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 p;
......@@ -75,7 +75,7 @@ nlm_encode_cookie(u32 *p, struct nlm_cookie *c)
{
*p++ = htonl(c->len);
memcpy(p, c->data, c->len);
p+=(c->len+3)>>2;
p+=XDR_QUADLEN(c->len);
return p;
}
......@@ -86,7 +86,7 @@ nlm_decode_fh(u32 *p, struct nfs_fh *f)
if ((len = ntohl(*p++)) != NFS2_FHSIZE) {
printk(KERN_NOTICE
"lockd: bad fhandle size %x (should be %d)\n",
"lockd: bad fhandle size %d (should be %d)\n",
len, NFS2_FHSIZE);
return NULL;
}
......@@ -512,11 +512,11 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
* Buffer requirements for NLM
*/
#define NLM_void_sz 0
#define NLM_cookie_sz 3 /* 1 len , 2 data */
#define NLM_caller_sz 1+QUADLEN(sizeof(system_utsname.nodename))
#define NLM_netobj_sz 1+QUADLEN(XDR_MAX_NETOBJ)
/* #define NLM_owner_sz 1+QUADLEN(NLM_MAXOWNER) */
#define NLM_fhandle_sz 1+QUADLEN(NFS2_FHSIZE)
#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(system_utsname.nodename))
#define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
/* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */
#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_holder_sz 4+NLM_netobj_sz
......@@ -604,3 +604,32 @@ struct rpc_program nlm_program = {
.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)
c->len=4;
memset(c->data, 0, 4); /* hockeypux brain damage */
}
else if(len<=8)
else if(len<=NLM_MAXCOOKIELEN)
{
c->len=len;
memcpy(c->data, p, len);
p+=(len+3)>>2;
p+=XDR_QUADLEN(len);
}
else
{
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 p;
......@@ -76,7 +76,7 @@ nlm4_encode_cookie(u32 *p, struct nlm_cookie *c)
{
*p++ = htonl(c->len);
memcpy(p, c->data, c->len);
p+=(c->len+3)>>2;
p+=XDR_QUADLEN(c->len);
return p;
}
......@@ -515,7 +515,7 @@ nlm4clt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
* Buffer requirements for NLM
*/
#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_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
/* #define NLM4_owner_sz 1+XDR_QUADLEN(NLM4_MAXOWNER) */
......
......@@ -45,4 +45,13 @@
#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 */
......@@ -13,10 +13,9 @@
#include <linux/nfs.h>
#include <linux/sunrpc/xdr.h>
#define NLM_MAXCOOKIELEN 32
#define NLM_MAXSTRLEN 1024
#define QUADLEN(len) (((len) + 3) >> 2)
#define nlm_granted __constant_htonl(NLM_LCK_GRANTED)
#define nlm_lck_denied __constant_htonl(NLM_LCK_DENIED)
#define nlm_lck_denied_nolocks __constant_htonl(NLM_LCK_DENIED_NOLOCKS)
......@@ -33,13 +32,14 @@ struct nlm_lock {
};
/*
* NLM cookies. Technically they can be 1K, Nobody uses over 8 bytes
* however.
* NLM cookies. Technically they can be 1K, but Linux only uses 8 bytes.
* FreeBSD uses 16, Apple Mac OS X 10.3 uses 20. Therefore we set it to
* 32 bytes.
*/
struct nlm_cookie
{
unsigned char data[8];
unsigned char data[NLM_MAXCOOKIELEN];
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