mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 05:48:40 +00:00
greybus: operation: fix use-after-free when sending responses
Fix use-after-free when sending responses due to reference imbalance. Make sure to take a reference to the operation when sending responses. This reference is dropped in greybus_data_sent when the message has been sent, while the initial reference is dropped in gb_operation_work after processing the corresponding request. Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Reviewed-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
parent
37754030b0
commit
0fb5acc401
1 changed files with 12 additions and 3 deletions
|
@ -719,6 +719,8 @@ EXPORT_SYMBOL_GPL(gb_operation_request_send_sync);
|
|||
*/
|
||||
int gb_operation_response_send(struct gb_operation *operation, int errno)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Record the result */
|
||||
if (!gb_operation_result_set(operation, errno)) {
|
||||
pr_err("request result already set\n");
|
||||
|
@ -733,10 +735,17 @@ int gb_operation_response_send(struct gb_operation *operation, int errno)
|
|||
}
|
||||
}
|
||||
|
||||
/* Reference will be dropped when message has been sent. */
|
||||
gb_operation_get(operation);
|
||||
|
||||
/* Fill in the response header and send it */
|
||||
operation->response->header->result = gb_operation_errno_map(errno);
|
||||
|
||||
return gb_message_send(operation->response);
|
||||
ret = gb_message_send(operation->response);
|
||||
if (ret)
|
||||
gb_operation_put(operation);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gb_operation_response_send);
|
||||
|
||||
|
@ -802,8 +811,8 @@ static void gb_connection_recv_request(struct gb_connection *connection,
|
|||
* request handler to be the operation's callback function.
|
||||
*
|
||||
* The last thing the handler does is send a response
|
||||
* message. The original reference to the operation will be
|
||||
* dropped when the response has been sent.
|
||||
* message. The initial reference to the operation will be
|
||||
* dropped when the handler returns.
|
||||
*/
|
||||
operation->callback = gb_operation_request_handle;
|
||||
if (gb_operation_result_set(operation, -EINPROGRESS))
|
||||
|
|
Loading…
Reference in a new issue