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,30 +556,31 @@
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) {
+ if (m < 0 || m >= di_max_opens) {
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);
+ 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));
- mutex_exit(&di_lock);
return (0);
}
@@ -601,11 +602,13 @@
if (m < 0 || m >= di_max_opens) {
return (ENXIO);
}
st = di_states[m];
- ASSERT(st != NULL);
+ if(st == NULL) {
+ return (ENXIO);
+ }
dcmn_err2((CE_CONT, "di_ioctl: mode = %x, cmd = %x\n", mode, cmd));
switch (cmd) {
case DINFOIDENT: