Print this page
NEX-3997 Kernel BAD TRAP type=d panic from di_mem_addr on bogus di_state_t structure
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>

*** 556,585 **** di_close(dev_t dev, int flag, int otype, cred_t *cred_p) { struct di_state *st; int m = (int)getminor(dev) - DI_NODE_SPECIES; ! if (m < 0) { cmn_err(CE_WARN, "closing non-existent devinfo minor %d", m + DI_NODE_SPECIES); return (ENXIO); } - st = di_states[m]; - ASSERT(m < di_max_opens && st != NULL); - - di_freemem(st); - kmem_free(st, sizeof (struct di_state)); - /* * empty slot in state table */ mutex_enter(&di_lock); di_states[m] = NULL; dcmn_err((CE_CONT, "di_close: thread = %p, assigned minor = %d\n", (void *)curthread, m + DI_NODE_SPECIES)); - mutex_exit(&di_lock); return (0); } --- 556,586 ---- di_close(dev_t dev, int flag, int otype, cred_t *cred_p) { struct di_state *st; int m = (int)getminor(dev) - DI_NODE_SPECIES; ! if (m < 0 || m >= di_max_opens) { cmn_err(CE_WARN, "closing non-existent devinfo minor %d", m + DI_NODE_SPECIES); return (ENXIO); } /* * empty slot in state table */ mutex_enter(&di_lock); + st = di_states[m]; di_states[m] = NULL; + mutex_exit(&di_lock); + + if (st != NULL) { + di_freemem(st); + kmem_free(st, sizeof (struct di_state)); + } + dcmn_err((CE_CONT, "di_close: thread = %p, assigned minor = %d\n", (void *)curthread, m + DI_NODE_SPECIES)); return (0); }
*** 601,611 **** if (m < 0 || m >= di_max_opens) { return (ENXIO); } st = di_states[m]; ! ASSERT(st != NULL); dcmn_err2((CE_CONT, "di_ioctl: mode = %x, cmd = %x\n", mode, cmd)); switch (cmd) { case DINFOIDENT: --- 602,614 ---- if (m < 0 || m >= di_max_opens) { return (ENXIO); } st = di_states[m]; ! if(st == NULL) { ! return (ENXIO); ! } dcmn_err2((CE_CONT, "di_ioctl: mode = %x, cmd = %x\n", mode, cmd)); switch (cmd) { case DINFOIDENT: