From: Johan Hovold Date: Fri, 27 Mar 2015 11:41:13 +0000 (+0100) Subject: greybus: operation: fix use-after-free when sending responses X-Git-Tag: Ubuntu-5.13.0-19.19~14927^2~378^2~21^2~1642 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=0fb5acc4018c0da61f9084932d0cd816fab77eec;p=mirror_ubuntu-jammy-kernel.git 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 Reviewed-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index c64b2bf47a43..ad45dee19a5a 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -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))