From ff65be7a58201ca7843813f92192d997a2a4b4ee Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 27 Mar 2015 12:41:15 +0100 Subject: [PATCH] greybus: operation: fix use-after-free and infinite loop on unhandled requests Make sure to return a proper response in case we get a request we do not recognise. This fixes an infinite loop and use-after-free bug, where the freed operations structure would get re-added to the work queue indefinitely. Signed-off-by: Johan Hovold Reviewed-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/operation.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index dcf987fb103d..f194b1eeb539 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -208,14 +208,11 @@ static void gb_message_cancel(struct gb_message *message) static void gb_operation_request_handle(struct gb_operation *operation) { struct gb_protocol *protocol = operation->connection->protocol; + int ret; if (!protocol) return; - /* - * If the protocol has no incoming request handler, report - * an error and mark the request bad. - */ if (protocol->request_recv) { protocol->request_recv(operation->type, operation); return; @@ -223,10 +220,14 @@ static void gb_operation_request_handle(struct gb_operation *operation) dev_err(&operation->connection->dev, "unexpected incoming request type 0x%02hhx\n", operation->type); - if (gb_operation_result_set(operation, -EPROTONOSUPPORT)) - queue_work(gb_operation_workqueue, &operation->work); - else - WARN(true, "failed to mark request bad\n"); + + ret = gb_operation_response_send(operation, -EPROTONOSUPPORT); + if (ret) { + dev_err(&operation->connection->dev, + "failed to send response %d: %d\n", + -EPROTONOSUPPORT, ret); + return; + } } /*