usb-storage: alauda: check the return value of alauda_read_map()

alauda_ensure_map_for_zone() ignores the value alauda_read_map()
returns. On failure lba_to_pba[zone] and pba_to_lba[zone] are left NULL,
and both callers dereference them immediately:

  pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];

alauda_read_map() returns USB_STOR_TRANSPORT_ERROR when either kcalloc()
fails or an alauda_get_redu_data() transfer fails, so one failed bulk
transfer is enough to reach the NULL dereference.

Return that value from alauda_ensure_map_for_zone() and check it in
alauda_read_data() and alauda_write_lba().

Fixes: e80b0fade0 ("[PATCH] USB Storage: add alauda support")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217862
Signed-off-by: Arka Mondal <arka@arkamondal.net>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260901065831.43567-3-arka@arkamondal.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Arka Mondal 2026-09-01 15:58:30 +09:00 committed by Greg Kroah-Hartman
parent ec67dacb75
commit eb88241979

View File

@ -697,11 +697,13 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
* Checks to see whether we have already mapped a certain zone
* If we haven't, the map is generated
*/
static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone)
static int alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone)
{
if (MEDIA_INFO(us).lba_to_pba[zone] == NULL
|| MEDIA_INFO(us).pba_to_lba[zone] == NULL)
alauda_read_map(us, zone);
return alauda_read_map(us, zone);
return 0;
}
/*
@ -849,7 +851,9 @@ static int alauda_write_lba(struct us_data *us, u16 lba,
unsigned int new_pba_offset;
unsigned int zone = lba / uzonesize;
alauda_ensure_map_for_zone(us, zone);
result = alauda_ensure_map_for_zone(us, zone);
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
if (pba == 1) {
@ -980,7 +984,10 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
unsigned int lba_offset = lba - (zone * uzonesize);
unsigned int pages;
u16 pba;
alauda_ensure_map_for_zone(us, zone);
result = alauda_ensure_map_for_zone(us, zone);
if (result != USB_STOR_TRANSPORT_GOOD)
break;
/* Not overflowing capacity? */
if (lba >= max_lba) {