[Kos-dev] Double Fault

Christophe Avoinne kos-dev@yoda.isnpro.com
Fri, 16 Mar 2001 00:30:13 +0100


C'est un message de format MIME en plusieurs parties.

------=_NextPart_000_0015_01C0ADB0.440065E0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Salut Thomas !

Ok, je regarde...

----- Original Message -----
From: "Thomas Petazzoni" <thomas.petazzoni@utbm.fr>


> > l'adresse EIP  du TSS pointe par le Back Link du TSS courant (celui =
du
> double fault) a ete mise a jour (elle est a 0 avant l'execution d'un
> double fault), et semble etre correcte (elle est a l'interieur de
> l'identity mapping). Je ne sais pas si c'est la bonne adresse, mais je
> vois pas pourquoi il mettrait un truc presque vrai, au pif. Ca serait
> con de sa part.
>

Ce doit =EAtre l'adresse du code fautif ! r=E9cup=E8re cette adresse et =
fais un
d=E9sassemblage comme je te l'avais montr=E9 chez toi. Pas sur le faux =
EIP
empil=E9 dans la pile du Double Fault, hein ! ;) mais bien l'EIP du TSS
syst=E8me !

> En fait, j'ai remarque que si on mettait pas le champ ESP du TSS du
> double fault a une bonne adresse, celui ci se lancait quand meme mais
> avec une adresse de pile egale =E0 0xFFFFFFFF. il devait donc ecraser =
le
> PD present a cette adresse, sympa nan ?
>

Arf ! tu avais oubli=E9 de le placer =E0 la bonne valeur ? j'ai laiss=E9 =
passer =E7a
? honte =E0 moi !

> en fait dans le TSS, les champs ESP et ESP0 sont importants : si on =
est
> deja en CPL0, et qu'on reste en CPL0, apparement il utilise le champ
> ESP, mais a mon avis, si on est en CPL3, et qu'on passe en CPL0 il =
doit
> surement utiliser l'adresse dans le champ ESP0.
>

Oui, et comme ESP0 pointe sur la base de pile syst=E8me - =E0 priori =
d=E9j=E0
existante ! il ne peut pas avoir de double fault d'un code CPL3, donc le
probl=E8me n'en est pas un. Donc il faudra toujours consid=E9rer ESP =
quand il y
a Double Fault - sauf s'il n'y a pas de pile syst=E8me, mais =E7a reste =
un faux
probl=E8me, car il faut une pile syst=E8me pour pouvoir passer en CPL3 =
depuis
CPL0.

> maintenant le probleme est de retourner de ce handler de double fault.
> il y a des choses presentes sur la pile, mais pas bcp. pas de EIP, =
juste
> un EFLAGS a une valeur de 0x1000. j'ai pas verifie ce que signifiait
> cette valeur.
>

S'agissant d'un TASK GATE, il ne peut y avoir un CS:EIP dans la pile, tu
trouveras en fait en lieu et place du CS:EIP probablement des 0. Cela =
est
normal car le CS:EIP du code interrompu est en fait enregistr=E9 dans =
les
champs CS et EIP du TSS se trouvant dans le backlink. Le EFLAGS contient =
un
bit =E0 1 qui indique au IRETD de l'exception de faire un TASK GATE sur =
le tss
d=E9crit dans le backlink plut=F4t que de lire le cs:eip dans la pile. =
Dans
notre cas, nous avons le CS:EIP du code interrompu dans les champs CS et =
EIP
du TSS syst=E8me qui est lui m=EAme point=E9 par le backlink du TSS =
responsable de
la gestion du doublefault.

Etant donn=E9 qu'il s'agit d'un changement de TSS, il faut consid=E9rer =
le champ
ESP et non ESP0, car seuls les registres g=E9n=E9raux (%eax, %ebx, %ecx, =
%edx,
%ebp, %esp, %esi, %edi), les registres de s=E9lecteurs (%cs, %ss, %ds, =
%es,
%fs, %gs), et enfin le registre %EFLAGS sont sauv=E9s dans le TSS =
sortant
avant de prendre les nouvelles valeurs de ceux du TSS entrant. Les seuls
champs du TSS syst=E8me se trouvant donc mise =E0 jour avant le passage =
au TSS
du Double Fault sont donc ces trois cat=E9gories. En aucun cas, les =
champs
SS0:ESP0, SS1:ESP1, SS2:ESP2, CR3, LDT, etc. du TSS syst=E8me sont =
sauv=E9s
avant le passage au TSS du Double Fault.

Donc quelque soit le niveau de privil=E8ge du code tournant sous le TSS
syst=E8me, c'est bien dans ESP que l'on trouvera l'adresse incrimin=E9e =
de la
pile. l'ESP0 n'est mis uniquement dans %esp que lors il y a passage du =
CPL3
=E0 CPL0 dans le M=CBME TSS ! En aucun cas le CPU viendra modifier =
implicitement
le champ ESP0 autrement que par un "mov" explicite du programmeur dans =
ce
champ, autrement dit le changement effectif de la pile syst=E8me du TSS. =
Ce
que j'ai du mal =E0 expliquer, c'est que ESP0 n'est pas le pointeur ESP =
de la
pile syst=E8me, mais la base de la pile syst=E8me (i.e, une pile =
syst=E8me vide),
nuance donc ! c'est pourquoi je vous expliquais la n=E9cessit=E9 de ne =
pas avoir
la m=EAme pile syst=E8me pour tous les t=E2ches, car si deux se =
trouvaient en
CPL0, l'une =E9craserait les donn=E9es empil=E9es de l'autre dans cette =
pile.
ESP0, ESP1 et ESP2 sont les bases des piles syst=E8mes pour les trois =
niveaux
de privil=E8ge. Un SS3:ESP3 est totalement inutile dans le TSS, car ces =
champs
ne sont utilis=E9s que lorsque l'on passe =E0 un niveau de privil=E8ge =
plus
important (i.e, quand on passe =E0 un num=E9ro CPL plus petit).

> si on fait fais juste un return comme ca ca marche pas. j'ai mis  =
ajour
> dans la pile ce qui devrait etre EIP, mais ca chie aussi....
> le hic c'est que je sais pas ce que le proc empile sur la nouvelle =
pile
> pointee par le nouveau TSS. et j'ai pas trouve ou c'etait dans la doc
> Intel. est-ce que ca marche comme normalement pour une interruption, =
ou
> alors il empile plus de choses ? ou moins ?
>

Je pars du principe que c'est le Double Fault qui g=E8re =
l'aggrandissement de
la pile syst=E8me ou la punition de la t=E2che fautive.

Bon tu ne trouveras rien dans la pile du TSS du Double Fault qui
t'int=E9ressera =E0 mon avis, c'est dans les champs CS,EIP, EFLAGS et =
ESP du TSS
syst=E8me :

1) La pile syst=E8me existe et on peut l'aggrandir :
  - Aggrandir la pile syst=E8me et rendre accessible l'adresse point=E9e =
par le
champ ESP de la TSS syst=E8me qui ne change pas.
  - Le champ ESP0  de la TSS syst=E8me n'a pas besoin d'=EAtre chang=E9 =
pas, car
il s'agit de la base de la pile syst=E8me qui ne change pas.
  - Dans les champs CS, EIP et EFLAGS doivent se trouver le CS:EIP et =
EFLAGS
du code responsable du Page Fault qui n'a pu avoir lieu (du moins je
l'esp=E8re !). A priori, pas de changement =E0 faire si l'on consid=E8re =
que c'est
le Double Fault qui se charge de traiter la pile syst=E8me =E0 la place =
du Page
Fault.
  - Faire IRETD.

2) La pile syst=E8me existe et on ne peut plus l'aggrandir :
  - Placer dans le champ ESP de la TSS syst=E8me la base de la pile =
syst=E8me
(ESP0 de la TSS syst=E8me).
  - Placer dans le champ CS:EIP de la TSS syst=E8me le handler =
responsable de
la terminaison de la t=E2che fautive (sorte de exit();).
  - Modifier le champ EFLAGS de la TSS syst=E8me en cons=E9quence.
  - Faire IRETD.

3) La pile syst=E8me n'existe pas :
  - Allouer cette pile et la rendre accessible.
  - Placer dans le champ ESP0 de la TSS syst=E8me la base de la pile =
syst=E8me.
  - Placer aussi dans le champ ESP de la TSS syst=E8me la base de la =
pile
syst=E8me (une t=E2che en CPL3 a forc=E9ment une pile syst=E8me de =
valide sinon je
ne vois pas comment on passera au CPL3 sans partir du CPL0 pour cette
t=E2che).
  - Faire IRETD.

Amicalement

Hlide


------=_NextPart_000_0015_01C0ADB0.440065E0
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 5.50.4134.100" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2><FONT face=3D"Times New Roman" =
size=3D3>Salut Thomas=20
!<BR><BR>Ok, je regarde...<BR><BR>----- Original Message -----<BR>From: =
"Thomas=20
Petazzoni" &lt;</FONT><A href=3D"mailto:thomas.petazzoni@utbm.fr"><FONT=20
face=3D"Times New Roman" =
size=3D3>thomas.petazzoni@utbm.fr</FONT></A><FONT=20
face=3D"Times New Roman" size=3D3>&gt;<BR><BR><BR>&gt; &gt; l'adresse =
EIP&nbsp; du=20
TSS pointe par le Back Link du TSS courant (celui du<BR>&gt; double =
fault) a ete=20
mise a jour (elle est a 0 avant l'execution d'un<BR>&gt; double fault), =
et=20
semble etre correcte (elle est a l'interieur de<BR>&gt; l'identity =
mapping). Je=20
ne sais pas si c'est la bonne adresse, mais je<BR>&gt; vois pas pourquoi =
il=20
mettrait un truc presque vrai, au pif. Ca serait<BR>&gt; con de sa=20
part.<BR>&gt;<BR><BR>Ce doit =EAtre l'adresse du code fautif ! =
r=E9cup=E8re cette=20
adresse et fais un<BR>d=E9sassemblage comme je te l'avais montr=E9 chez =
toi. Pas sur=20
le faux EIP<BR>empil=E9 dans la pile du Double Fault, hein ! ;) mais =
bien l'EIP du=20
TSS<BR>syst=E8me !<BR><BR>&gt; En fait, j'ai remarque que si on mettait =
pas le=20
champ ESP du TSS du<BR>&gt; double fault a une bonne adresse, celui ci =
se=20
lancait quand meme mais<BR>&gt; avec une adresse de pile egale =E0 =
0xFFFFFFFF. il=20
devait donc ecraser le<BR>&gt; PD present a cette adresse, sympa nan=20
?<BR>&gt;<BR><BR>Arf ! tu avais oubli=E9 de le placer =E0 la bonne =
valeur ? j'ai=20
laiss=E9 passer =E7a<BR>? honte =E0 moi !<BR><BR>&gt; en fait dans le =
TSS, les champs=20
ESP et ESP0 sont importants : si on est<BR>&gt; deja en CPL0, et qu'on =
reste en=20
CPL0, apparement il utilise le champ<BR>&gt; ESP, mais a mon avis, si on =
est en=20
CPL3, et qu'on passe en CPL0 il doit<BR>&gt; surement utiliser l'adresse =
dans le=20
champ ESP0.<BR>&gt;<BR><BR>Oui, et comme ESP0 pointe sur la base de pile =
syst=E8me=20
- =E0 priori d=E9j=E0<BR>existante ! il ne peut pas avoir de double =
fault d'un code=20
CPL3, donc le<BR>probl=E8me n'en est pas un. Donc il faudra toujours =
consid=E9rer=20
ESP quand il y<BR>a Double Fault - sauf s'il n'y a pas de pile =
syst=E8me, mais =E7a=20
reste un faux<BR>probl=E8me, car il faut une pile syst=E8me pour pouvoir =
passer en=20
CPL3 depuis<BR>CPL0.<BR><BR>&gt; maintenant le probleme est de retourner =
de ce=20
handler de double fault.<BR>&gt; il y a des choses presentes sur la =
pile, mais=20
pas bcp. pas de EIP, juste<BR>&gt; un EFLAGS a une valeur de 0x1000. =
j'ai pas=20
verifie ce que signifiait<BR>&gt; cette =
valeur.<BR>&gt;<BR><BR>S'agissant d'un=20
TASK GATE, il ne peut y avoir un CS:EIP dans la pile, tu<BR>trouveras en =
fait en=20
lieu et place du CS:EIP probablement des 0. Cela est<BR>normal car le =
CS:EIP du=20
code interrompu est en fait enregistr=E9 dans les<BR>champs CS et EIP du =
TSS se=20
trouvant dans le backlink. Le EFLAGS contient un<BR>bit =E0 1 qui =
indique au IRETD=20
de l'exception de faire un TASK GATE sur le tss<BR>d=E9crit dans le =
backlink=20
plut=F4t que de lire le cs:eip dans la pile. Dans<BR>notre cas, nous =
avons le=20
CS:EIP du code interrompu dans les champs CS et EIP<BR>du TSS syst=E8me =
qui est=20
lui m=EAme point=E9 par le backlink du TSS responsable de<BR>la gestion =
du=20
doublefault.<BR><BR>Etant donn=E9 qu'il s'agit d'un changement de TSS, =
il faut=20
consid=E9rer le champ<BR>ESP et non ESP0, car seuls les registres =
g=E9n=E9raux (%eax,=20
%ebx, %ecx, %edx,<BR>%ebp, %esp, %esi, %edi), les registres de =
s=E9lecteurs (%cs,=20
%ss, %ds, %es,<BR>%fs, %gs), et enfin le registre %EFLAGS sont sauv=E9s =
dans le=20
TSS sortant<BR>avant de prendre les nouvelles valeurs de ceux du TSS =
entrant.=20
Les seuls<BR>champs du TSS syst=E8me se trouvant donc mise =E0 jour =
avant le passage=20
au TSS<BR>du Double Fault sont donc ces trois cat=E9gories. En aucun =
cas, les=20
champs<BR>SS0:ESP0, SS1:ESP1, SS2:ESP2, CR3, LDT, etc. du TSS syst=E8me =
sont=20
sauv=E9s<BR>avant le passage au TSS du Double Fault.<BR><BR>Donc quelque =
soit le=20
niveau de privil=E8ge du code tournant sous le TSS<BR>syst=E8me, c'est =
bien dans ESP=20
que l'on trouvera l'adresse incrimin=E9e de la<BR>pile. l'ESP0 n'est mis =

uniquement dans %esp que lors il y a passage du CPL3<BR>=E0 CPL0 dans le =
M=CBME TSS=20
! En aucun cas le CPU viendra modifier implicitement<BR>le champ ESP0 =
autrement=20
que par un "mov" explicite du programmeur dans ce<BR>champ, autrement =
dit le=20
changement effectif de la pile syst=E8me du TSS. Ce<BR>que j'ai du mal =
=E0=20
expliquer, c'est que ESP0 n'est pas le pointeur ESP de la<BR>pile =
syst=E8me, mais=20
la base de la pile syst=E8me (i.e, une pile syst=E8me vide),<BR>nuance =
donc ! c'est=20
pourquoi je vous expliquais la n=E9cessit=E9 de ne pas avoir<BR>la =
m=EAme pile syst=E8me=20
pour tous les t=E2ches, car si deux se trouvaient en<BR>CPL0, l'une =
=E9craserait les=20
donn=E9es empil=E9es de l'autre dans cette pile.<BR>ESP0, ESP1 et ESP2 =
sont les=20
bases des piles syst=E8mes pour les trois niveaux<BR>de privil=E8ge. Un =
SS3:ESP3 est=20
totalement inutile dans le TSS, car ces champs<BR>ne sont utilis=E9s que =
lorsque=20
l'on passe =E0 un niveau de privil=E8ge plus<BR>important (i.e, quand on =
passe =E0 un=20
num=E9ro CPL plus petit).<BR><BR>&gt; si on fait fais juste un return =
comme ca ca=20
marche pas. j'ai mis&nbsp; ajour<BR>&gt; dans la pile ce qui devrait =
etre EIP,=20
mais ca chie aussi....<BR>&gt; le hic c'est que je sais pas ce que le =
proc=20
empile sur la nouvelle pile<BR>&gt; pointee par le nouveau TSS. et j'ai =
pas=20
trouve ou c'etait dans la doc<BR>&gt; Intel. est-ce que ca marche comme=20
normalement pour une interruption, ou<BR>&gt; alors il empile plus de =
choses ?=20
ou moins ?<BR>&gt;<BR><BR>Je pars du principe que c'est le Double Fault =
qui g=E8re=20
l'aggrandissement de<BR>la pile syst=E8me ou la punition de la t=E2che=20
fautive.<BR><BR>Bon tu ne trouveras rien dans la pile du TSS du Double =
Fault=20
qui<BR>t'int=E9ressera =E0 mon avis, c'est dans les champs CS,EIP, =
EFLAGS et ESP du=20
TSS<BR>syst=E8me :<BR><BR>1) La pile syst=E8me existe et on peut =
l'aggrandir=20
:<BR>&nbsp; - Aggrandir la pile syst=E8me et rendre accessible l'adresse =
point=E9e=20
par le<BR>champ ESP de la TSS syst=E8me qui ne change pas.<BR>&nbsp; - =
Le champ=20
ESP0&nbsp; de la TSS syst=E8me n'a pas besoin d'=EAtre chang=E9 pas, =
car<BR>il s'agit=20
de la base de la pile syst=E8me qui ne change pas.<BR>&nbsp; - Dans les =
champs CS,=20
EIP et EFLAGS doivent se trouver le CS:EIP et EFLAGS<BR>du code =
responsable du=20
Page Fault qui n'a pu avoir lieu (du moins je<BR>l'esp=E8re !). A =
priori, pas de=20
changement =E0 faire si l'on consid=E8re que c'est<BR>le Double Fault =
qui se charge=20
de traiter la pile syst=E8me =E0 la place du Page<BR>Fault.<BR>&nbsp; - =
Faire=20
IRETD.<BR><BR>2) La pile syst=E8me existe et on ne peut plus l'aggrandir =

:<BR>&nbsp; - Placer dans le champ ESP de la TSS syst=E8me la base de la =
pile=20
syst=E8me<BR>(ESP0 de la TSS syst=E8me).<BR>&nbsp; - Placer dans le =
champ CS:EIP de=20
la TSS syst=E8me le handler responsable de<BR>la terminaison de la =
t=E2che fautive=20
(sorte de exit();).<BR>&nbsp; - Modifier le champ EFLAGS de la TSS =
syst=E8me en=20
cons=E9quence.<BR>&nbsp; - Faire IRETD.<BR><BR>3) La pile syst=E8me =
n'existe pas=20
:<BR>&nbsp; - Allouer cette pile et la rendre accessible.<BR>&nbsp; - =
Placer=20
dans le champ ESP0 de la TSS syst=E8me la base de la pile =
syst=E8me.<BR>&nbsp; -=20
Placer aussi dans le champ ESP de la TSS syst=E8me la base de la =
pile<BR>syst=E8me=20
(une t=E2che en CPL3 a forc=E9ment une pile syst=E8me de valide sinon =
je<BR>ne vois=20
pas comment on passera au CPL3 sans partir du CPL0 pour=20
cette<BR>t=E2che).<BR>&nbsp; - Faire=20
IRETD.<BR><BR>Amicalement<BR><BR>Hlide</FONT><BR></FONT></DIV></BODY></HT=
ML>

------=_NextPart_000_0015_01C0ADB0.440065E0--