diff options
| author | mrg <mrg@NetBSD.org> | 2022-08-10 01:16:38 +0000 |
|---|---|---|
| committer | mrg <mrg@NetBSD.org> | 2022-08-10 01:16:38 +0000 |
| commit | 99225d721c88a4f2993ace6adc7a9f2492c16111 (patch) | |
| tree | 2f3851264af40795dcdfc32d0d79ddf1819cb5b9 /sys/dev/raidframe | |
| parent | e22e9bfc8a7f15de1857843618eae3865280424d (diff) | |
raidframe: reject invalid values for numCol and numSpares
numCol and numSpares are "int" so they can be "-1" internally,
which means negative values need to be rejected, as well as
values higher than RF_MAXCOL/RF_MAXSPARES.
explicitly nul-terminate all strings coming from userland.
some minor CSE that avoids signed arith.
this fixes issues in the RAIDFRAME_ADD_HOT_SPARE,
RAIDFRAME_CONFIGURE, RAIDFRAME_DELETE_COMPONENT,
RAIDFRAME_INCORPORATE_HOT_SPARE, and RAIDFRAME_REBUILD_IN_PLACE
ioctl commands.
Reported-by: syzbot+b584943ad1f8ab9d4fe0@syzkaller.appspotmail.com
https://syzkaller.appspot.com/bug?id=61e07e418261f8eec8a37a9226725fe31820edd0
https://syzkaller.appspot.com/bug?id=ca0c997b40de81c0f0b44790217731f142003149
https://syzkaller.appspot.com/bug?id=6fc452d228453494655a85264591dd9054cc0b08
https://syzkaller.appspot.com/bug?id=873f0271682713a27adc9a49dd7109c70b35fda3
XXX: pullup-8, pullup-9.
ok oster@ riastradh@
Diffstat (limited to 'sys/dev/raidframe')
| -rw-r--r-- | sys/dev/raidframe/rf_disks.c | 15 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_driver.c | 9 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_netbsdkintf.c | 51 |
3 files changed, 55 insertions, 20 deletions
diff --git a/sys/dev/raidframe/rf_disks.c b/sys/dev/raidframe/rf_disks.c index 368d137e774..45874f401dd 100644 --- a/sys/dev/raidframe/rf_disks.c +++ b/sys/dev/raidframe/rf_disks.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_disks.c,v 1.92 2019/12/08 12:14:40 mlelstv Exp $ */ +/* $NetBSD: rf_disks.c,v 1.93 2022/08/10 01:16:38 mrg Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. * All rights reserved. @@ -60,7 +60,7 @@ ***************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_disks.c,v 1.92 2019/12/08 12:14:40 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_disks.c,v 1.93 2022/08/10 01:16:38 mrg Exp $"); #include <dev/raidframe/raidframevar.h> @@ -318,11 +318,12 @@ static int rf_AllocDiskStructures(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr) { int ret; + size_t entries = raidPtr->numCol + RF_MAXSPARE; /* We allocate RF_MAXSPARE on the first row so that we have room to do hot-swapping of spares */ - raidPtr->Disks = RF_MallocAndAdd((raidPtr->numCol + RF_MAXSPARE) * - sizeof(*raidPtr->Disks), raidPtr->cleanupList); + raidPtr->Disks = RF_MallocAndAdd( + entries * sizeof(*raidPtr->Disks), raidPtr->cleanupList); if (raidPtr->Disks == NULL) { ret = ENOMEM; goto fail; @@ -330,9 +331,7 @@ rf_AllocDiskStructures(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr) /* get space for device specific stuff.. */ raidPtr->raid_cinfo = RF_MallocAndAdd( - (raidPtr->numCol + RF_MAXSPARE) * sizeof(*raidPtr->raid_cinfo), - raidPtr->cleanupList); - + entries * sizeof(*raidPtr->raid_cinfo), raidPtr->cleanupList); if (raidPtr->raid_cinfo == NULL) { ret = ENOMEM; goto fail; @@ -607,7 +606,7 @@ rf_ConfigureDisk(RF_Raid_t *raidPtr, char *bf, RF_RaidDisk_t *diskPtr, error = vn_bdev_openpath(pb, &vp, curlwp); pathbuf_destroy(pb); if (error) { - printf("open device: %s failed!\n", diskPtr->devname); + printf("open device: '%s' failed: %d\n", diskPtr->devname, error); if (error == ENXIO) { /* the component isn't there... must be dead :-( */ diskPtr->status = rf_ds_failed; diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c index 8abab3d88d6..00571bf49b7 100644 --- a/sys/dev/raidframe/rf_driver.c +++ b/sys/dev/raidframe/rf_driver.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_driver.c,v 1.139 2021/07/23 02:35:14 oster Exp $ */ +/* $NetBSD: rf_driver.c,v 1.140 2022/08/10 01:16:38 mrg Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. * All rights reserved. @@ -66,7 +66,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.139 2021/07/23 02:35:14 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.140 2022/08/10 01:16:38 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_raid_diagnostic.h" @@ -341,6 +341,11 @@ rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac) (void (*) (void *)) rf_FreeAllocList, raidPtr->cleanupList); + KASSERT(cfgPtr->numCol < RF_MAXCOL); + KASSERT(cfgPtr->numCol >= 0); + KASSERT(cfgPtr->numSpare < RF_MAXSPARE); + KASSERT(cfgPtr->numSpare >= 0); + raidPtr->numCol = cfgPtr->numCol; raidPtr->numSpare = cfgPtr->numSpare; diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index 0fb79f5eee4..8dd686e8c11 100644 --- a/sys/dev/raidframe/rf_netbsdkintf.c +++ b/sys/dev/raidframe/rf_netbsdkintf.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_netbsdkintf.c,v 1.407 2022/04/16 16:40:54 andvar Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.408 2022/08/10 01:16:38 mrg Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2008-2011 The NetBSD Foundation, Inc. @@ -101,7 +101,7 @@ ***********************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.407 2022/04/16 16:40:54 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.408 2022/08/10 01:16:38 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_raid_autoconfig.h" @@ -1240,7 +1240,7 @@ rf_getConfiguration(struct raid_softc *rs, void *data, RF_Config_t **k_cfg) int rf_construct(struct raid_softc *rs, RF_Config_t *k_cfg) { - int retcode; + int retcode, i; RF_Raid_t *raidPtr = &rs->sc_r; rs->sc_flags &= ~RAIDF_SHUTDOWN; @@ -1251,6 +1251,29 @@ rf_construct(struct raid_softc *rs, RF_Config_t *k_cfg) /* should do some kind of sanity check on the configuration. * Store the sum of all the bytes in the last byte? */ + /* Force nul-termination on all strings. */ +#define ZERO_FINAL(s) do { s[sizeof(s) - 1] = '\0'; } while (0) + for (i = 0; i < RF_MAXCOL; i++) { + ZERO_FINAL(k_cfg->devnames[0][i]); + } + for (i = 0; i < RF_MAXSPARE; i++) { + ZERO_FINAL(k_cfg->spare_names[i]); + } + for (i = 0; i < RF_MAXDBGV; i++) { + ZERO_FINAL(k_cfg->debugVars[i]); + } +#undef ZERO_FINAL + + /* Check some basic limits. */ + if (k_cfg->numCol >= RF_MAXCOL || k_cfg->numCol < 0) { + retcode = EINVAL; + goto out; + } + if (k_cfg->numSpare >= RF_MAXSPARE || k_cfg->numSpare < 0) { + retcode = EINVAL; + goto out; + } + /* configure the system */ /* @@ -1451,6 +1474,18 @@ rf_check_recon_status(RF_Raid_t *raidPtr, int *data) return 0; } +/* + * Copy a RF_SingleComponent_t from 'data', ensuring nul-termination + * on the component_name[] array. + */ +static void +rf_copy_single_component(RF_SingleComponent_t *component, void *data) +{ + + memcpy(component, data, sizeof *component); + component->component_name[sizeof(component->component_name) - 1] = '\0'; +} + static int raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { @@ -1466,7 +1501,6 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) int retcode = 0; int column; RF_ComponentLabel_t *clabel; - RF_SingleComponent_t *sparePtr,*componentPtr; int d; if ((rs = raidget(unit, false)) == NULL) @@ -1555,21 +1589,18 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) rf_RewriteParityThread, raidPtr,"raid_parity"); case RAIDFRAME_ADD_HOT_SPARE: - sparePtr = (RF_SingleComponent_t *) data; - memcpy(&component, sparePtr, sizeof(RF_SingleComponent_t)); + rf_copy_single_component(&component, data); return rf_add_hot_spare(raidPtr, &component); case RAIDFRAME_REMOVE_HOT_SPARE: return retcode; case RAIDFRAME_DELETE_COMPONENT: - componentPtr = (RF_SingleComponent_t *)data; - memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t)); + rf_copy_single_component(&component, data); return rf_delete_component(raidPtr, &component); case RAIDFRAME_INCORPORATE_HOT_SPARE: - componentPtr = (RF_SingleComponent_t *)data; - memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t)); + rf_copy_single_component(&component, data); return rf_incorporate_hot_spare(raidPtr, &component); case RAIDFRAME_REBUILD_IN_PLACE: |
