Messages in this thread Patch in this message | | | From | Yves-Alexis Perez <> | Subject | [PATCH v2] firmware: fix async, manual firmware loading | Date | Fri, 11 Nov 2016 16:32:17 +0100 |
| |
When wait_for_completion_interruptible_timeout() is called from _request_firmware_load() with a large timeout value (here, MAX_JIFFY_OFFSET because it's a an explicit call to the user helper), its return value (a long) will overflow when silently casted to int, be stored as a negative integer and then treated as an error.
This bug was introduced in commit 68ff2a00dbf5 ("firmware_loader: handle timeout via wait_for_completion_interruptible_timeout()") when a delay work was replaced by the call to wait_for_completion_interruptible_timeout().
Fix this by re-using the timeout variable and only set retval in specific cases.
Signed-off-by: Yves-Alexis Perez <corsac@corsac.net> Fixes: 68ff2a00dbf5 "firmware_loader: handle timeout via wait_for_completion_interruptible_timeout()" Cc: Luis R. Rodriguez <mcgrof@kernel.org> Cc: Ming Lei <ming.lei@canonical.com> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: stable@vger.kernel.org Acked-by: Luis R. Rodriguez <mcgrof@kernel.org> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org> --- Changelog:
v2: rewrite the changelog following comments by Luis
drivers/base/firmware_class.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 22d1760..a95e1e5 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -955,13 +955,14 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, timeout = MAX_JIFFY_OFFSET; } - retval = wait_for_completion_interruptible_timeout(&buf->completion, + timeout = wait_for_completion_interruptible_timeout(&buf->completion, timeout); - if (retval == -ERESTARTSYS || !retval) { + if (timeout == -ERESTARTSYS || !timeout) { + retval = timeout; mutex_lock(&fw_lock); fw_load_abort(fw_priv); mutex_unlock(&fw_lock); - } else if (retval > 0) { + } else if (timeout > 0) { retval = 0; } -- 2.10.2
| |