From f790292aa6447f662eab178f85178ae848981381 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelhaleem Ahmed Date: Tue, 29 Sep 2026 10:34:56 +0000 Subject: [PATCH] fix(sg,cam): do not dereference a NULL supported-device table get_supported_devs() returns NULL for any vendor that is not IBM, HP, HPE or QUANTUM - the switch has no default case and the initialiser is NULL. Two backends use the result without checking it: struct supported_device **cur = get_supported_devs(priv->vendor); while(*cur) { so opening a drive whose INQUIRY vendor id is not one of those four segfaults instead of returning -EDEV_DEVICE_UNSUPPORTABLE three lines further down. The iokit backend already guards it with `while(cur && *cur)`; this makes the sg and cam backends agree with it. Reproduced on Linux with mhvtl, which lets a virtual drive present any vendor id: a drive reporting vendor 'STK' with product 'ULT3580-TD8' crashed `ltfs -o devname=... ` with SIGSEGV. With this change the same command logs LTFS30213I Unsupported Drive 'STK ' / 'ULT3580-TD8 '. and exits 1. The device list is unaffected: sg_get_device_list() names drives through _generate_product_name(), which matches on product id alone, so such a drive is listed and only refused when it is opened. Signed-off-by: Ahmed Abdelhaleem Ahmed --- src/tape_drivers/freebsd/cam/cam_tc.c | 2 +- src/tape_drivers/linux/sg/sg_tape.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tape_drivers/freebsd/cam/cam_tc.c b/src/tape_drivers/freebsd/cam/cam_tc.c index 7c7f82bd..bfe785a2 100644 --- a/src/tape_drivers/freebsd/cam/cam_tc.c +++ b/src/tape_drivers/freebsd/cam/cam_tc.c @@ -281,7 +281,7 @@ int camtape_open(const char *devname, void **handle) /* Check the drive is supportable */ softc->vendor = get_vendor_id(vendor); struct supported_device **cur = get_supported_devs(softc->vendor); - while(*cur) { + while(cur && *cur) { if ((! strncmp((char*)softc->cd->inq_data.vendor, (*cur)->vendor_id, strlen((*cur)->vendor_id)) ) && (! strncmp((char*)softc->cd->inq_data.product, (*cur)->product_id, diff --git a/src/tape_drivers/linux/sg/sg_tape.c b/src/tape_drivers/linux/sg/sg_tape.c index 8a13493e..cd9b533a 100644 --- a/src/tape_drivers/linux/sg/sg_tape.c +++ b/src/tape_drivers/linux/sg/sg_tape.c @@ -500,7 +500,7 @@ static int _raw_open(struct sg_data *priv) priv->vendor = get_vendor_id(id_data.vendor_id); struct supported_device **cur = get_supported_devs(priv->vendor); - while(*cur) { + while(cur && *cur) { if((! strncmp(id_data.vendor_id, (*cur)->vendor_id, strlen((*cur)->vendor_id)) ) && (! strncmp(id_data.product_id, (*cur)->product_id, strlen((*cur)->product_id)) ) ) { drive_type = (*cur)->drive_type;