summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authormrg <mrg@NetBSD.org>2022-08-10 01:16:38 +0000
committermrg <mrg@NetBSD.org>2022-08-10 01:16:38 +0000
commit99225d721c88a4f2993ace6adc7a9f2492c16111 (patch)
tree2f3851264af40795dcdfc32d0d79ddf1819cb5b9 /sys/dev/raidframe
parente22e9bfc8a7f15de1857843618eae3865280424d (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.c15
-rw-r--r--sys/dev/raidframe/rf_driver.c9
-rw-r--r--sys/dev/raidframe/rf_netbsdkintf.c51
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: