[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