kernel panic in free() called from semop()
Don Lewis
truckman at FreeBSD.org
Fri Nov 12 15:12:05 PST 2004
I cvsup'ed around 18:12 UTC today and got the following kernel panic
with the new kernel right after moused started.
Starting default moused:.
panic: free: address 0xe902ecb0(0xe902e000) has not been allocated.
cpuid = 0
KDB: enter: panic
[thread 100082]
Stopped at kdb_enter+0x2c: leave
db> tr
kdb_enter(c082a57e,100,c26c8300,e902ecb0,c26c8300) at kdb_enter+0x2c
panic(c0828c9f,e902ecb0,e902e000,e902ecb6,c26c8300) at panic+0x17f
free(e902ecb0,c088f900,c082dd62,685,e902ecb6) at free+0xd4
semop(c26c8300,e902ed18,5,4,283) at semop+0x150
syscall(2f,2f,2f,805c010,bfbfed56) at syscall+0x128
Xint0x80_syscall() at Xint0x80_syscall+0x1f
--- syscall (169, FreeBSD ELF32, semsys), eip = 0x480dd5f8, esp = 0xbfbfeb04, ebp = 0xbfbfeb40 ---
I suspect that the culprit is the sysv_sema.c:1.71.
This particular part of the change looks like a mistake:
@@ -900,7 +901,7 @@ semop(td, uap)
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
if (semid < 0 || semid >= seminfo.semmni)
- return (EINVAL);
+ error = EINVAL;
/* Allocate memory for sem_ops */
if (nsops <= SMALL_SOPS)
Falling through instead of returning looks dangerous because a little
futher down there is the following code:
semakptr = &sema[semid];
sema_mtxp = &sema_mtx[semid];
Oh, this looks bad, too:
@@ -1152,6 +1153,7 @@ done2:
mtx_unlock(sema_mtxp);
if (sops != small_sops)
free(sops, M_SEM);
+ free(sops, M_SEM);
return (error);
}
sops can either point to small_sops, which is located on the stack, or
it call by allocated dynamically with malloc(). Depending on where sops
points, it will either get freed twice, or it we will pass a stack
address to free(). It looks like the latter is happening in this case.
More information about the freebsd-current
mailing list