Skip to content

Commit

Permalink
firmware_loader: fix pre-allocated buf built-in firmware use
Browse files Browse the repository at this point in the history
[ Upstream commit f7a07f7b96033df7709042ff38e998720a3f7119 ]

The firmware_loader can be used with a pre-allocated buffer
through the use of the API calls:

  o request_firmware_into_buf()
  o request_partial_firmware_into_buf()

If the firmware was built-in and present, our current check
for if the built-in firmware fits into the pre-allocated buffer
does not return any errors, and we proceed to tell the caller
that everything worked fine. It's a lie and no firmware would
end up being copied into the pre-allocated buffer. So if the
caller trust the result it may end up writing a bunch of 0's
to a device!

Fix this by making the function that checks for the pre-allocated
buffer return non-void. Since the typical use case is when no
pre-allocated buffer is provided make this return successfully
for that case. If the built-in firmware does *not* fit into the
pre-allocated buffer size return a failure as we should have
been doing before.

I'm not aware of users of the built-in firmware using the API
calls with a pre-allocated buffer, as such I doubt this fixes
any real life issue. But you never know... perhaps some oddball
private tree might use it.

In so far as upstream is concerned this just fixes our code for
correctness.

Signed-off-by: Luis Chamberlain <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
mcgrof authored and gregkh committed Nov 26, 2021
1 parent f5a0ba4 commit f2d22b1
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/base/firmware_loader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,15 @@ static struct firmware_cache fw_cache;
extern struct builtin_fw __start_builtin_fw[];
extern struct builtin_fw __end_builtin_fw[];

static void fw_copy_to_prealloc_buf(struct firmware *fw,
static bool fw_copy_to_prealloc_buf(struct firmware *fw,
void *buf, size_t size)
{
if (!buf || size < fw->size)
return;
if (!buf)
return true;
if (size < fw->size)
return false;
memcpy(buf, fw->data, fw->size);
return true;
}

static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
Expand All @@ -114,9 +117,7 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
if (strcmp(name, b_fw->name) == 0) {
fw->size = b_fw->size;
fw->data = b_fw->data;
fw_copy_to_prealloc_buf(fw, buf, size);

return true;
return fw_copy_to_prealloc_buf(fw, buf, size);
}
}

Expand Down

0 comments on commit f2d22b1

Please sign in to comment.