From: Johan Hovold Date: Tue, 14 Jul 2015 13:43:23 +0000 (+0200) Subject: greybus: operation: fix another cancellation use-after-free X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~1383 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=fffc151381473384629d78cb89b7f7bbb9dc53b0;p=karo-tx-linux.git greybus: operation: fix another cancellation use-after-free An incoming operation could already be scheduled even if gb_operation_result_set succeeds as its initial status is -EINPROGRESS. Avoid potential use-after-free by never dropping the reference count for incoming operations as part of cancellation. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index b78c55fac8cc..41aec7647b2b 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -853,12 +853,17 @@ void gb_connection_recv(struct gb_connection *connection, */ void gb_operation_cancel(struct gb_operation *operation, int errno) { - if (gb_operation_result_set(operation, errno)) { - gb_message_cancel(operation->request); - gb_operation_put(operation); - } else if (gb_operation_is_incoming(operation)) { - if (!gb_operation_is_unidirectional(operation)) + if (gb_operation_is_incoming(operation)) { + /* Cancel response if it has been allocated */ + if (!gb_operation_result_set(operation, errno) && + !gb_operation_is_unidirectional(operation)) { gb_message_cancel(operation->response); + } + } else { + if (gb_operation_result_set(operation, errno)) { + gb_message_cancel(operation->request); + gb_operation_put(operation); + } } } EXPORT_SYMBOL_GPL(gb_operation_cancel);