[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MInixfs crash ... try this :)



earlier i wrote...

>  hmm i had crashes in rsmtp (uucp mail unbatcher), apparently in minixfs
> unlink()ing a tempfile... (looked so with fsck)  the funny thing was it
> happened only when there was an expire (cnews-xt) running at the same time...
> fixstk rsmtp cured it.  (68000, no multitos.)
> 
>  now how can one process affect anothers stack?  is this a kernel bug?
> race condition?  i have never seen update crashing but maybe this is the
> same reason...

 now i even had to repair a filesystem because of what looked like such
a stack overwrite crash... :/  after that i looked around and patched a few
things, try this:

Index: signal.c
@@ -257,8 +257,8 @@
 	long oldstack, newstack;
 	long *stack;
 	CONTEXT *call, contexts[2];
-#define oldsysctxt (contexts[0])
-#define newcurrent (contexts[1])
+#define newcurrent (contexts[0])
+#define oldsysctxt (contexts[1])
 
 	extern void sig_return();
 
@@ -346,12 +346,12 @@
 			}
 		}
 
-		++curproc->nsigs;
+		++curproc->nsigs;
 		call = &curproc->ctxt[SYSCALL];
 /*
- * what we do is build two fake stack frames; the bottom one is
+ * what we do is build two fake stack frames; the top one is
  * for a call to the user function, with (long)parameter being the
- * signal number; the top one is for sig_return.
+ * signal number; the bottom one is for sig_return.
  * When the user function returns, it returns to sig_return, which
  * calls into the kernel to restore the context in prev_ctxt
  * (thus putting us back here). We can then continue on our way.
@@ -359,7 +359,7 @@
 
 /* set a new system stack, with a bit of buffer space */
 		oldstack = curproc->sysstack;
-		newstack = ((long) ( (&newcurrent) - 2 )) - 12;
+		newstack = ((long) &newcurrent) - 0x40 - 12;
 
 		if (newstack < (long)curproc->stack + ISTKSIZE + 256) {
 			ALERT("stack overflow");
@@ -369,11 +369,6 @@
 			FATAL("system stack not in proc structure");
 		}
 
-/* unwound_stack is set by p_sigreturn() */
-		if (sig == 0 && unwound_stack)
-			curproc->sysstack = unwound_stack;
-		else
-			curproc->sysstack = newstack;
 		oldsysctxt = *call;
 		stack = (long *)(call->sr & 0x2000 ? call->ssp :
 				call->usp);
@@ -402,10 +397,6 @@
 		call->pc = (long) curproc->sighandle[sig];
 		call->sfmt = call->fstate[0] = 0;	/* don't restart FPU communication */
 
-		((long *)curproc->sysstack)[1] = FRAME_MAGIC;
-		((long *)curproc->sysstack)[2] = oldstack;
-		((long *)curproc->sysstack)[3] = sig;
-
 		if (curproc->sigflags[sig] & SA_RESET) {
 			curproc->sighandle[sig] = SIG_DFL;
 			curproc->sigflags[sig] &= ~SA_RESET;
@@ -421,6 +412,20 @@
 			newcurrent.regs[0] = CTXT_MAGIC;
 				/* set D0 so next return is different */
 			assert(curproc->magic == CTXT_MAGIC);
+
+/* unwound_stack is set by p_sigreturn() */
+			if (sig == 0 && unwound_stack)
+				stack = (long *) unwound_stack;
+			else
+/* newstack points just below our current sp, much less than ISTKSIZE away
+ * so better set it up with interrupts off...  -nox */
+				stack = (long *) newstack;
+			spl7();
+			curproc->sysstack = (long) stack;
+			++stack;
+			*stack++ = FRAME_MAGIC;
+			*stack++ = oldstack;
+			*stack = sig;
 			leave_kernel();
 			restore_context(call);
 		}
@@ -486,7 +491,7 @@
 	}
 	else {
 		valid_return = 0;
-		oldctxt = ((CONTEXT *)(&frame[2])) + 2;
+		oldctxt = (CONTEXT *) (((long)&frame[2]) + 0x40);
 		if (oldctxt->regs[0] != CTXT_MAGIC) {
 			FATAL("p_sigreturn: corrupted context");
 		}
Index: dosmem.c
@@ -644,6 +644,7 @@
 		/* we guarantee ourselves at least 2 timeslices to do an Mshrink */
 			assert(curproc->magic == CTXT_MAGIC);
 			fresh_slices(2);
+			spl7();
 			leave_kernel();
 			change_context(&(curproc->ctxt[CURRENT]));
 		}
Index: proc.c
@@ -573,10 +573,11 @@
 	curproc->ctxt[CURRENT].regs[0] = 1;
 	curproc = p;
 	proc_clock = TIME_SLICE;	/* fresh time */
+	assert(p->magic == CTXT_MAGIC);
+	spl7();
 	if ((p->ctxt[CURRENT].sr & 0x2000) == 0) {	/* user mode? */
 		leave_kernel();
 	}
-	assert(p->magic == CTXT_MAGIC);
 	change_context(&(p->ctxt[CURRENT]));
 	/* not reached */
 	return 0;
Index: syscall.spp
@@ -373,6 +373,7 @@
 	move.b	d0,(a0)			; store the character
 	addq.w	#1,d1
 	move.w	d1,_bconbsiz
+	ori.w	#$0700,sr		; spl7()
 	jsr	_leave_kernel		; restore vectors
 	moveq.l	#-1,d0			; return character output OK
 	rte
Index: intr.spp
@@ -92,6 +92,7 @@
 	jsr	_build_context		; build context
 	move.l	_curproc,a0
 	move.l	(a0),sp			; use curproc->sysstack
+	move.w	P_CTXT0+C_SR(a0),d7	; get saved int level
 %ifdef ONLY030
 	clr.w	-(sp)			; not a system call
 %else
@@ -99,6 +100,11 @@
 %endif
 	jsr	_enter_kernel		; enter kernel
 	addq.w	#2,sp
+	move.w	sr,d1
+	eor.w	d1,d7
+	and.w	#$700,d7
+	eor.w	d7,d1
+	move.w	d1,sr			; vbl allowed again
 	jsr	_preempt		; yield processor
 	ori.w	#$700,sr		; spl7()
 	jsr	_leave_kernel		; restore vectors

 cheers
	Juergen
-- 
J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
								...ohne Gewehr
PGP public key fingerprint =  8A 18 58 54 03 7B FC 12  1F 8B 63 C7 19 27 CF DA