From: Sam Protsenko Date: Wed, 9 Jul 2025 04:23:42 +0000 (-0500) Subject: dfu: Fix dfu_config_interfaces() for single interface DFU syntax X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=89911825a2d3bbd1bc5d41b977aa24fb5b10f49d;p=thirdparty%2Fu-boot.git dfu: Fix dfu_config_interfaces() for single interface DFU syntax As stated in DFU documentation [1], the device interface part might be missing in dfu_alt_info: dfu_alt_info The DFU setting for the USB download gadget with a semicolon separated string of information on each alternate: dfu_alt_info=";;....;" When several devices are used, the format is: - '='alternate list (';' separated) So in first case dfu_alt_info might look like something like this: dfu_alt_info="mmc 0=rawemmc raw 0 0x747c000 mmcpart 1;" And in second case (when the interface is missing): dfu_alt_info="rawemmc raw 0 0x747c000 mmcpart 1;" When the interface is not specified the 'dfu' command crashes when called using 'dfu 0' or 'dfu list' syntax: => dfu list "Synchronous Abort" handler, esr 0x96000006, far 0x0 That's happening due to incorrect string handling in dfu_config_interfaces(). In case when the interface is not specified in dfu_alt_info it triggers this corner case: d = strsep(&s, "="); // now d contains s, and s is NULL if (!d) break; a = strsep(&s, "&"); // s is already NULL, so a is NULL too if (!a) // corner case a = s; // a is NULL now which causes NULL pointer dereference later in this call, due to 'a' being NULL: part = skip_spaces(part); That's because as per strsep() behavior, when delimiter ("&") is not found, the token (a) becomes the entire string (s), and string (s) becomes NULL. To fix that issue assign "a = d" instead of "a = s", because at that point variable d actually contains previous s, which should be used in this case. [1] doc/usage/dfu.rst Fixes: commit febabe3ed4f4 ("dfu: allow to manage DFU on several devices") Signed-off-by: Sam Protsenko Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20250709042342.13544-1-semen.protsenko@linaro.org Signed-off-by: Mattijs Korpershoek --- diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 756569217bb..eefdf44ec87 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -147,7 +147,7 @@ int dfu_config_interfaces(char *env) break; a = strsep(&s, "&"); if (!a) - a = s; + a = d; do { part = strsep(&a, ";"); part = skip_spaces(part);