提交 dcd22e14 编写于 作者: D Dan Carpenter 提交者: Greg Kroah-Hartman

drm/vmwgfx: Fix double free in vmw_recv_msg()

commit 08b0c891605acf727e43e3e03a25857d3e789b61 upstream.

We recently added a kfree() after the end of the loop:

	if (retries == RETRIES) {
		kfree(reply);
		return -EINVAL;
	}

There are two problems.  First the test is wrong and because retries
equals RETRIES if we succeed on the last iteration through the loop.
Second if we fail on the last iteration through the loop then the kfree
is a double free.

When you're reading this code, please note the break statement at the
end of the while loop.  This patch changes the loop so that if it's not
successful then "reply" is NULL and we can test for that afterward.

Cc: <stable@vger.kernel.org>
Fixes: 6b7c3b86f0b6 ("drm/vmwgfx: fix memory leak when too many retries have occurred")
Signed-off-by: NDan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: NThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: NThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 38d38d1e
...@@ -353,7 +353,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, ...@@ -353,7 +353,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
!!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) {
kfree(reply); kfree(reply);
reply = NULL;
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) { if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry. */ /* A checkpoint occurred. Retry. */
continue; continue;
...@@ -377,7 +377,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, ...@@ -377,7 +377,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
kfree(reply); kfree(reply);
reply = NULL;
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) { if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry. */ /* A checkpoint occurred. Retry. */
continue; continue;
...@@ -389,10 +389,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, ...@@ -389,10 +389,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
break; break;
} }
if (retries == RETRIES) { if (!reply)
kfree(reply);
return -EINVAL; return -EINVAL;
}
*msg_len = reply_len; *msg_len = reply_len;
*msg = reply; *msg = reply;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册