usb: typec: ucsi: ccg: reject firmware images without a ':' record header
Subsystems (2)
Greg Kroah-Hartman
maintainerPATCH 1/1 usb: typec: ucsi: ccg: reject firmware images without a ':' record header
do_flash() locates the first .cyacd record with
p = strnchr(fw->data, fw->size, ':');
while (p < eof) {
s = strnchr(p + 1, eof - p - 1, ':');
...
}If the firmware image contains no ':' byte, strnchr() returns NULL. NULL compares less than the valid kernel pointer eof, so the loop body runs and strnchr() is called with p + 1 == (void *)1 and a length of roughly (unsigned long)eof, causing a wonderful crash.
The not_signed_fw fallthrough earlier in do_flash() and the chip-state branches in ccg_fw_update_needed() allow an unsigned blob to reach this loop, so a root user who can place a crafted file under /lib/firmware and write the do_flash sysfs attribute can trigger the oops.
Bail out with -EINVAL when the initial strnchr() returns NULL.
--- drivers/usb/typec/ucsi/ucsi_ccg.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/usb/typec/ucsi/ucsi_ccg.c +5 -0
@@ -1243,6 +1243,11 @@ static int do_flash(struct ucsi_ccg *uc, enum enum_flash_mode mode)*****************************************************************/ p =strnchr (fw->data, fw->size,':' ); +if (!p) { +dev_err (dev,"Bad FW format: no ':' record header found\n" ); + err = -EINVAL ; + goto release_mem; + }while (p < eof) { s =strnchr (p +1 , eof - p -1 ,':' );
Signature · 1 line
2.54.0
Quoted 18 lines · Greg Kroah-Hartman
do_flash()locates the first .cyacd record withp = strnchr(fw->data, fw->size, ':'); while (p < eof) { s = strnchr(p + 1, eof - p - 1, ':'); ... }If the firmware image contains no ':' byte,
strnchr()returns NULL. NULL compares less than the valid kernel pointer eof, so the loop body runs andstrnchr()is called with p + 1 == (void *)1 and a length of roughly (unsigned long)eof, causing a wonderful crash.The
not_signed_fwfallthrough earlier indo_flash()and the chip-state branches inccg_fw_update_needed()allow an unsigned blob to reach this loop, so a root user who can place a crafted file under/lib/firmwareand write thedo_flashsysfs attribute can trigger the oops.
Quoted 6 lines
Bail out with
-EINVALwhen the initialstrnchr()returns NULL.Assisted-by gkh_clanker_t1000Cc stable <[email protected]>Cc Heikki Krogerus <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
Quoted 22 lines
--- drivers/usb/typec/ucsi/ucsi_ccg.c | 5 +++++ 1 file changed, 5 insertions(+)drivers/usb/typec/ucsi/ucsi_ccg.c +5
-0@@ -1243,6 +1243,11 @@ static int do_flash(struct ucsi_ccg *uc, enum enum_flash_mode mode)*****************************************************************/ p =strnchr (fw->data, fw->size,':' ); +if (!p) { +dev_err (dev,"Bad FW format: no ':' record header found\n" ); + err = -EINVAL ; + goto release_mem; + }while (p < eof) { s =strnchr (p +1 , eof - p -1 ,':' );Signature · 1 line
2.54.0
Signature · 1 line
heikki