NULL pointer in imx-sdma.c with from context arg in reject_firmware_nowait
Xavi Drudis Ferran
xdrudis at tinet.cat
Tue Apr 17 08:41:29 UTC 2018
El Mon, Apr 16, 2018 at 03:46:54AM +0200, Denis 'GNUtoo' Carikli deia:
> On Sat, 14 Apr 2018 19:23:44 +0200
> Xavi Drudis Ferran <xdrudis at tinet.cat> wrote:
> [...]
> > in drivers/dma/imx-sdma.c
> I didn't look into the details of what linux-libre changes inside this
> driver but the unmodified mainline driver is supposed to work without a
> firmware. So just making the request_firmware replacement return that
> it has no firmware should work.
>
It does work when the first parameter of sdma_load_firmware (called
fw) is null and the second (called context and copied to sdma) points
to a sane struct but not when both are null. In linux-libre 4.16
firmware.c we pass a null in the 2nd parameter too, and that
calls dev_info(NULL, ... ) which is not nice. I think in
previous versions, sdma_load_firmware didn't even get called.
drivers/dma/imx-sdma.c
static void sdma_load_firmware(const struct firmware *fw, void *context)
{
struct sdma_engine *sdma = context;
const struct sdma_firmware_header *header;
const struct sdma_script_start_addrs *addr;
unsigned short *ram_code;
if (!fw) {
dev_info(sdma->dev, "external firmware not found, using ROM firmware\n");
/* In this case we just use the ROM firmware. */
return;
}
[...]
original include/linux/firmware.h
reject_firmware_nowait(struct module *module, int uevent,
const char *name, struct device *device,
gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw,
void *context))
{
report_missing_free_firmware(dev_name(device), NULL);
/* We assume NONFREE_FIRMWARE will not be found; how could it? */
return request_firmware_nowait(module, uevent, NONFREE_FIRMWARE,
device, gfp, NULL, cont);
}
request_firmware_nowait (see drivers/base/firmware_class.c) will call
request_firmware_work_func, which will eventually call
sdma_load_firmware(fw, context), with fw null because the file named
by NONFREE_FIRMWARE won't exist, but context also a NULL coming from
the second last parameter in the call above.
I could fix this null pointer dereference with the patch below, I'm just
wondering if the NULL was there on purpose and now I'm making
something worse. I see the point in linux-libre 4.16 was to call the
cont function to help some drivers work. But is it necessary somewhere
to hardcode context to NULL ?
diff -rBbuw orig/linux-4.16/include/linux/firmware.h linux-4.16/include/linux/firmware.h
--- orig/linux-4.16/include/linux/firmware.h 2018-04-02 03:16:13.000000000 +0200
+++ linux-4.16/include/linux/firmware.h 2018-04-14 18:37:32.930013403 +0200
@@ -152,8 +152,9 @@
report_missing_free_firmware(dev_name(device), NULL);
/* We assume NONFREE_FIRMWARE will not be found; how could it? */
return request_firmware_nowait(module, uevent, NONFREE_FIRMWARE,
- device, gfp, NULL, cont);
+ device, gfp, context, cont);
}
+
static inline int
maybe_reject_firmware_nowait(struct module *module, int uevent,
const char *name, struct device *device,
More information about the linux-libre
mailing list