[CrackMonkey] Fwd: [PATCH] Linux 0.01 disk lockup
Aaron Lehmann
aaronl at vitelus.com
Thu Sep 27 08:07:29 PDT 2001
----- Forwarded message from Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz> -----
From: Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
Date: Thu, 27 Sep 2001 15:34:11 +0200 (CEST)
To: linux-kernel at vger.kernel.org
cc: torvalds at transmeta.com
Subject: [PATCH] Linux 0.01 disk lockup
Hi.
Linux 0.01 has a bug in disk request sorting - when interrupt happens
while sorting is active, the interrupt routine won't clear do_hd - thus
the disk will stay locked up forever.
Function add_request also lacks memory barriers - the compiler could
reorder writes to variable sorting and writes to request queue - producing
race conditions. Because gcc 1.40 does not have __asm__("":::"memory"), I
had to use dummy function call as a memory barrier.
The following patch fixes both issues.
Mikulas
diff -u -r linux-orig/kernel/hd.c linux/kernel/hd.c
--- linux-orig/kernel/hd.c Tue Sep 17 17:05:21 1991
+++ linux/kernel/hd.c Thu Sep 27 15:14:38 2001
@@ -55,9 +55,9 @@
((s1)->head<(s2)->head || (s1)->head==(s2)->head && \
((s1)->sector<(s2)->sector))))
-static struct hd_request * this_request = NULL;
+struct hd_request * this_request = NULL;
-static int sorting=0;
+int sorting=0;
static void do_request(void);
static void reset_controller(void);
@@ -293,8 +293,10 @@
{
int i,r;
- if (sorting)
+ if (sorting) {
+ do_hd=NULL;
return;
+ }
if (!this_request) {
do_hd=NULL;
return;
@@ -319,6 +321,8 @@
panic("unknown hd-command");
}
+void barrier();
+
/*
* add-request adds a request to the linked list.
* It sets the 'sorting'-variable when doing something
@@ -338,6 +342,7 @@
* disabling interrupts.
*/
sorting=1;
+ barrier();
if (!(tmp=this_request))
this_request=req;
else {
@@ -354,15 +359,19 @@
tmp->next=req;
}
}
+ barrier();
sorting=0;
+ barrier();
/*
* NOTE! As a result of sorting, the interrupts may have died down,
* as they aren't redone due to locking with sorting=1. They might
* also never have started, if this is the first request in the queue,
* so we restart them if necessary.
*/
- if (!do_hd)
+ if (!do_hd) {
+ barrier();
do_request();
+ }
}
void rw_abs_hd(int rw,unsigned int nr,unsigned int sec,unsigned int head,
diff -u -r linux-orig/kernel/system_call.s linux/kernel/system_call.s
--- linux-orig/kernel/system_call.s Tue Sep 17 17:50:52 1991
+++ linux/kernel/system_call.s Thu Sep 27 14:59:37 2001
@@ -47,7 +47,7 @@
nr_system_calls = 67
-.globl _system_call,_sys_fork,_timer_interrupt,_hd_interrupt,_sys_execve
+.globl _system_call,_sys_fork,_timer_interrupt,_hd_interrupt,_sys_execve,_barrier
.align 2
bad_sys_call:
@@ -186,6 +186,9 @@
call _copy_process
addl $20,%esp
1: ret
+
+_barrier:
+ ret
_hd_interrupt:
pushl %eax
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
----- End forwarded message -----
--
#define m(i)(x[i]^s[i+84])<< /* I do not condone improper use of this code */
unsigned char x[5],y,s[2048];main(n){for(read(0,x,5);read(0,s,n=2048);write(1,s
,n))if(s[y=s[13]%8+20]/16%4==1){int i=m(1)17^256+m(0)8,k=m(2)0,j=m(4)17^m(3)9^k
*2-k%8^8,a=0,c=26;for(s[y]-=16;--c;j*=2)a=a*2^i&1,i=i/2^j&1<<24;for(j=127;++j<n
;c=c>y)c+=y=i^i/8^i>>4^i>>12,i=i>>8^y<<17,a^=a>>14,y=a^a*8^a<<6,a=a>>8^y<<9,k=s
[j],k="7Wo~'G_\216"[k&7]+2^"cr3sfw6v;*k+>/n."[k>>4]*2^k*257/8,s[j]=k^(k&k*2&34)
*6^c+~y;}}//Please join us in civil disobedience and distribute DeCSS(or efdtt!)
More information about the Crackmonkey
mailing list