[Bug 238748] several race conditions in nandsim
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Fri Jun 21 14:12:50 UTC 2019
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238748
Bug ID: 238748
Summary: several race conditions in nandsim
Product: Base System
Version: 12.0-RELEASE
Hardware: Any
OS: Any
Status: New
Severity: Affects Only Me
Priority: ---
Component: kern
Assignee: bugs at FreeBSD.org
Reporter: emaste at freebsd.org
Reported to secteam (admbugs 795) but does not need to be treated as a security
issue because the NAND framework is not built by default, nandsim is not
intended for production use, and the device is root-only.
Reported by: Ilja Van Sprundel <ivansprundel at ioactive.com>
the nandsim driver has a global variable called crtls. when it's used no locks
are held. this can cause race conditions in several places leading -among other
things- to:
- double free
- NULL deref
- memory leak
freebsd-master\sys\dev\nand\nandsim.c
static int
nandsim_create_chip(struct sim_chip *chip)
{
struct sim_chip *sim_chip;
nand_debug(NDBG_SIM,"create chip num:%d at ctrl:%d", chip->num,
chip->ctrl_num);
if (chip->ctrl_num >= MAX_SIM_DEV ||
chip->num >= MAX_CTRL_CS) {
return (EINVAL);
}
if (ctrls[chip->ctrl_num].chips[chip->num]) {
return (EEXIST);
}
sim_chip = malloc(sizeof(*sim_chip), M_NANDSIM,
M_WAITOK);
if (sim_chip == NULL) {
return (ENOMEM);
}
memcpy(sim_chip, chip, sizeof(*sim_chip));
ctrls[chip->ctrl_num].chips[chip->num] = sim_chip; <-- <-- no ctrls lock held,
this can leak
sim_chip->created = 1;
return (0);
}
static int
nandsim_destroy_chip(struct sim_ctrl_chip *chip)
{
struct sim_ctrl_conf *ctrl_conf;
nand_debug(NDBG_SIM,"destroy chip num:%d at ctrl:%d", chip->chip_num,
chip->ctrl_num);
if (chip->ctrl_num >= MAX_SIM_DEV ||
chip->chip_num >= MAX_CTRL_CS)
return (EINVAL);
ctrl_conf = &ctrls[chip->ctrl_num];
if (!ctrl_conf->created || !ctrl_conf->chips[chip->chip_num])
return (ENODEV);
if (ctrl_conf->running)
return (EBUSY);
free(ctrl_conf->chips[chip->chip_num], M_NANDSIM); <-- no ctrls lock held, this
could double free
ctrl_conf->chips[chip->chip_num] = NULL;
return (0);
}
static int
nandsim_modify(struct sim_mod *mod)
{
struct sim_chip *sim_conf = NULL;
struct nandsim_chip *sim_chip = NULL;
nand_debug(NDBG_SIM,"modify ctlr %d chip %d", mod->ctrl_num,
mod->chip_num);
if (mod->field != SIM_MOD_LOG_LEVEL) {
if (mod->ctrl_num >= MAX_SIM_DEV ||
mod->chip_num >= MAX_CTRL_CS)
return (EINVAL);
sim_conf = ctrls[mod->ctrl_num].chips[mod->chip_num]; <-- can be NULL!
sim_chip = get_nandsim_chip(mod->ctrl_num, mod->chip_num); <-- can be NULL!
}
switch (mod->field) {
case SIM_MOD_LOG_LEVEL:
nandsim_log_level = mod->new_value; <-- NULL deref
break;
case SIM_MOD_ERASE_TIME:
sim_conf->erase_time = sim_chip->erase_delay = mod->new_value; <-- NULL deref
break;
case SIM_MOD_PROG_TIME:
sim_conf->prog_time = sim_chip->prog_delay = mod->new_value; <-- NULL deref
break;
case SIM_MOD_READ_TIME:
sim_conf->read_time = sim_chip->read_delay = mod->new_value; <-- NULL deref
break;
case SIM_MOD_ERROR_RATIO:
sim_conf->error_ratio = mod->new_value; <-- NULL deref
sim_chip->error_ratio = mod->new_value;
break;
default:
break;
}
return (0);
}
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list