Skip to content

Commit

Permalink
SUNRPC: Fix pointer arithmetic bug recently introduced in rpc_malloc/…
Browse files Browse the repository at this point in the history
…free

Use a cleaner method to find the size of an rpc_buffer.  This actually
works on x86-64!

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Chuck Lever authored and Trond Myklebust committed May 9, 2007
1 parent e70c490 commit aa3d1fa
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions net/sunrpc/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,11 @@ static void rpc_async_schedule(struct work_struct *work)
__rpc_execute(container_of(work, struct rpc_task, u.tk_work));
}

struct rpc_buffer {
size_t len;
char data[];
};

/**
* rpc_malloc - allocate an RPC buffer
* @task: RPC task that will use this buffer
Expand All @@ -754,18 +759,18 @@ static void rpc_async_schedule(struct work_struct *work)
*/
void *rpc_malloc(struct rpc_task *task, size_t size)
{
size_t *buf;
struct rpc_buffer *buf;
gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT;

size += sizeof(size_t);
size += sizeof(struct rpc_buffer);
if (size <= RPC_BUFFER_MAXSIZE)
buf = mempool_alloc(rpc_buffer_mempool, gfp);
else
buf = kmalloc(size, gfp);
*buf = size;
buf->len = size;
dprintk("RPC: %5u allocated buffer of size %zu at %p\n",
task->tk_pid, size, buf);
return ++buf;
return &buf->data;
}

/**
Expand All @@ -775,15 +780,18 @@ void *rpc_malloc(struct rpc_task *task, size_t size)
*/
void rpc_free(void *buffer)
{
size_t size, *buf = buffer;
size_t size;
struct rpc_buffer *buf;

if (!buffer)
return;
size = *buf;
buf--;

buf = container_of(buffer, struct rpc_buffer, data);
size = buf->len;

dprintk("RPC: freeing buffer of size %zu at %p\n",
size, buf);

if (size <= RPC_BUFFER_MAXSIZE)
mempool_free(buf, rpc_buffer_mempool);
else
Expand Down

0 comments on commit aa3d1fa

Please sign in to comment.