mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 05:48:40 +00:00
SUNRPC: Fix pointer arithmetic bug recently introduced in rpc_malloc/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>
This commit is contained in:
parent
e70c490810
commit
aa3d1faebe
1 changed files with 15 additions and 7 deletions
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue