Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa3d1fae authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

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: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent e70c4908
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -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