Discussion:
Sichere Stringoperationen z.B. fuer Socket-Anwendungen - Danke.
(zu alt für eine Antwort)
Stefan Reuther
2006-07-05 16:25:55 UTC
Permalink
Auf heutigen moderneren Architekturen, und dazu zähle ich auch die Intel
ab '386, sollte sowas doch aufgrund von Speicherschutzmechanismen nicht
möglich sein. Das Datensegment ist zwar les- und schreibbar, aber nicht
ausführbar. Dafür ist das Codesegment nur les- und ausführbar, aber
nicht schreibbar.
Das gilt für 286er-Betriebssysteme. OS/2 2.x oder Windows 3.0. Aktuelle
Betriebssysteme nutzen einen flachen Adressraum, in dem erstmal alle
Bytes gleich sind. Das "No-Execute"-Bit in der Pagetabelle ist auf x86
erst eine neuere Erfindung.

Hilft alles nicht dagegen, dass jemand einfach die Rücksprungadresse
tauscht ("return-to-libc-Attacke").
Ich habe mal folgendes kleine C-Programm als WIN-
Consolanwendung übersetzt. Beim Start bekomme ich einen Absturz
(privilegierte Anweisung). Unter DOS funktioniert es und ich ich erhalte
2 mal die Ausgabe von Func.
Das liegt aber nicht daran, dass die Kopie von func() nicht ausführbar
(im Sinne von Speicherschutz wäre). Vielmehr wird der Aufruf von
printf() über einen IP-relativen call aufgelöst. Wenn du den Code um
1000 Bytes nach hinten verschiebst, landet also auch der 'call printf'
1000 Bytes weiter hinten, irgendwo im Nirvana. Unter DOS hast du
vermutlich in einem Speichermodell compiliert, das den 'call printf' als
absoluten far-call ausführt, der unabhängig von der Stelle, wo er
ausgeführt wird, immer an die gleiche Stelle springt.
void Func() {
printf("Func is here\n");
}
Ersetze das durch
void Func() {
int (*volatile p)(const char*, ...) = printf;
p("Func is here\n");
}
und schon "funktioniert" auch die Kopie. Zur Initialisierung von
Zeigervariablen werden wieder absolute Adressen benutzt.

xp&fup Assemblerprogrammierer.


Stefan
Jan Bruns
2006-07-05 18:09:55 UTC
Permalink
Post by Stefan Reuther
Auf heutigen moderneren Architekturen, und dazu zähle ich auch die Intel
ab '386, sollte sowas doch aufgrund von Speicherschutzmechanismen nicht
möglich sein. Das Datensegment ist zwar les- und schreibbar, aber nicht
ausführbar. Dafür ist das Codesegment nur les- und ausführbar, aber
nicht schreibbar.
Das gilt für 286er-Betriebssysteme. OS/2 2.x oder Windows 3.0. Aktuelle
Betriebssysteme nutzen einen flachen Adressraum, in dem erstmal alle
Bytes gleich sind. Das "No-Execute"-Bit in der Pagetabelle ist auf x86
erst eine neuere Erfindung.
Trotzdem hat Heinz ja recht: Es sollte nicht möglich sein,
ist es aber, weil man (bzw. die Betriebsystementwickler) auf die
konsequente Anwendung von Segmentierung verzichtet hat.

Im Prinzip völlig unnötig. So furchtbar kompliziert
ist die Unterscheidung von near und far Zeigern ja nicht.

Wär' nur ein klein wenig unschön, die meisten Speicherzugriffe
ausgerechnet im Stack-Segment, und nicht im Datensegment zu haben.

Wie war das noch gleich? Kann man nicht das Stacksegment auch als
"readonly" setzen, mit der Auswrikung, daß nur mit PUSH und so
geschrieben werden kann, oder so ähnlich?

Dann hätte man manuell einen "Daten/Parameterstapel" im DS verwalten
können, und hätte nur für "dynamisch allozierten Speicher" far-pointer
verwenden müssen, und schwubs, schon hätten wir den grösseren Anteil
aller Speicheroperationen (globale und lokale Variablen) über
near-pointer bezogen auf DS, im SS nur readonly Flusskontrolle,
dann bspw. im ES den Heap, dessen pointer Verwaltungstechnisch ebenfalls
near-pointer sein könnten.
Der Hochsprachenprogrammierer müsste lediglich zwischen
"eigenen" Zeigern und Systempointern unterscheiden, der Compiler
zusätzlich zwischen Variablen- und Heapzugriffen (und folglich
im Zweifel far-pointer verwenden).

Hab' ich was übersehen?

Gruss

Jan Bruns
Stefan Reuther
2006-07-05 19:04:06 UTC
Permalink
Post by Jan Bruns
Post by Stefan Reuther
Auf heutigen moderneren Architekturen, und dazu zähle ich auch die Intel
ab '386, sollte sowas doch aufgrund von Speicherschutzmechanismen nicht
möglich sein. Das Datensegment ist zwar les- und schreibbar, aber nicht
ausführbar. Dafür ist das Codesegment nur les- und ausführbar, aber
nicht schreibbar.
Das gilt für 286er-Betriebssysteme. OS/2 2.x oder Windows 3.0. Aktuelle
Betriebssysteme nutzen einen flachen Adressraum, in dem erstmal alle
Bytes gleich sind. Das "No-Execute"-Bit in der Pagetabelle ist auf x86
erst eine neuere Erfindung.
Trotzdem hat Heinz ja recht: Es sollte nicht möglich sein,
ist es aber, weil man (bzw. die Betriebsystementwickler) auf die
konsequente Anwendung von Segmentierung verzichtet hat.
Im Prinzip völlig unnötig. So furchtbar kompliziert
ist die Unterscheidung von near und far Zeigern ja nicht.
Dummerweise sind far-Zeiger lahm (das Neuladen der Deskriptoren kostet.
Du hast nur 3 frei verwendbare Segmentregister, obwohl die 6 GPRs
bereits als knapp gelten) und inkompatibel zu real existierenden
C-Programmieren (passt nicht in einen Integertyp).
Post by Jan Bruns
Wie war das noch gleich? Kann man nicht das Stacksegment auch als
"readonly" setzen, mit der Auswrikung, daß nur mit PUSH und so
geschrieben werden kann, oder so ähnlich?
Nein, das geht nicht.

Du kannst aber das Segmentlimit von CS einfach auf die maximal mögliche
Code-Adresse setzen und das vom SS auf die minimal mögliche Stackadresse
(nebst gesetztem expand-down-Bit). Dann sind Code- und Stackbereich
disjunkt. WIMRE macht OpenBSD das.

Bringt aber Probleme mit beispielsweise Trampolinen.
Post by Jan Bruns
Der Hochsprachenprogrammierer müsste lediglich zwischen
"eigenen" Zeigern und Systempointern unterscheiden, der Compiler
zusätzlich zwischen Variablen- und Heapzugriffen (und folglich
im Zweifel far-pointer verwenden).
Der Hochsprachenprogrammierer müsste einfach nur ein korrektes Programm
abliefern, dann ist das alles egal.

Und da neuere Prozessoren ein No-Execute-Bit haben und im 64-bit-Modus
die Segmentierung eh ignorieren, ist es erst recht egal :-)


Stefan
Jan Bruns
2006-07-05 20:38:14 UTC
Permalink
Post by Stefan Reuther
Post by Jan Bruns
Wie war das noch gleich? Kann man nicht das Stacksegment auch als
"readonly" setzen, mit der Auswrikung, daß nur mit PUSH und so
geschrieben werden kann, oder so ähnlich?
Nein, das geht nicht.
Ja, scheinst recht zu haben.

Keine Ahnung, wo ich das herhabe.
Post by Stefan Reuther
Du kannst aber das Segmentlimit von CS einfach auf die maximal mögliche
Code-Adresse setzen und das vom SS auf die minimal mögliche Stackadresse
(nebst gesetztem expand-down-Bit). Dann sind Code- und Stackbereich
disjunkt. WIMRE macht OpenBSD das.
Naja, aber das hilft ja bspw. nicht gegen Buffer-Overflows auf dem Stack,
mit der Rücksprungadressenproblematik.

Andererseits könnten compiler ja von sich aus darauf verzichten,
Schreibzugriffe über/im SS zu verwenden (s. mein voriges Posting).
Post by Stefan Reuther
Dummerweise sind far-Zeiger lahm (das Neuladen der Deskriptoren kostet.
Code ( muss nichtmal lesbar sein )
Stack ( enthält freiwillig nur Rücksprungadressen, so daß gar keine
Codeschnipsel existieren, die Daten über SS schreiben )
Daten ( rw, enthält "manuell" verwalteten Datenstapel )
System( rw, Zugriffkontrolle/Gestaltung per paging; OS hat die Option,
Systemdaten ins DS der Anwendung zu blenden )

Da müssten gar keine Selektoren neugeladen werden,
hatte ich falsch gesehen.

Aber irgendwer, ob nun Betriebsystem, Compiler, oder Programmierer müsste
immer noch zwischen Daten bzw. Systempointer unterscheiden.

Gruss

Jan Bruns
Stefan Reuther
2006-07-06 17:07:33 UTC
Permalink
Hallo,
Post by Jan Bruns
Post by Stefan Reuther
Dummerweise sind far-Zeiger lahm (das Neuladen der Deskriptoren kostet.
Code ( muss nichtmal lesbar sein )
Stack ( enthält freiwillig nur Rücksprungadressen, so daß gar keine
Codeschnipsel existieren, die Daten über SS schreiben )
Daten ( rw, enthält "manuell" verwalteten Datenstapel )
Auch nicht so prall, da du damit weitere Register und/oder Performance
opferst (nehmen wir EBP als Datenstackpointer, müssen wir immer ein
DS:-Prefix verwenden. Nehmen wir EBX o.ä., haben wir ein weiteres
Register verloren).

Und dann überschreibe ich dir eben statt der Rückkehradressen vtbl-Pointer.

Ich bin ja immer noch dafür, einfach Programme ohne Buffer Overflows zu
schreiben :-)


Stefan
Jan Bruns
2006-07-06 21:42:51 UTC
Permalink
Post by Stefan Reuther
Post by Jan Bruns
Post by Stefan Reuther
Dummerweise sind far-Zeiger lahm (das Neuladen der Deskriptoren kostet.
Code ( muss nichtmal lesbar sein )
Stack ( enthält freiwillig nur Rücksprungadressen, so daß gar keine
Codeschnipsel existieren, die Daten über SS schreiben )
Daten ( rw, enthält "manuell" verwalteten Datenstapel )
Auch nicht so prall, da du damit weitere Register und/oder Performance
opferst (nehmen wir EBP als Datenstackpointer, müssen wir immer ein
DS:-Prefix verwenden. Nehmen wir EBX o.ä., haben wir ein weiteres
Register verloren).
So? Hat denn Intel bei der Auflistung der 32-Bit Adressierungen
die Fussnote vergessen, die darauf hinweist? Diese fussnote findet
sich nämlich nur an der Auflistung der 16-bit Adressierungen.
Post by Stefan Reuther
Und dann überschreibe ich dir eben statt der Rückkehradressen vtbl-Pointer.
Was ist ein vtbl-pointer?
Post by Stefan Reuther
Ich bin ja immer noch dafür, einfach Programme ohne Buffer
Overflows zu schreiben :-)
Besser wär's.

Gruss

Jan Bruns
Stefan Reuther
2006-07-07 16:20:07 UTC
Permalink
Post by Jan Bruns
Post by Stefan Reuther
Post by Jan Bruns
Code ( muss nichtmal lesbar sein )
Stack ( enthält freiwillig nur Rücksprungadressen, so daß gar keine
Codeschnipsel existieren, die Daten über SS schreiben )
Daten ( rw, enthält "manuell" verwalteten Datenstapel )
Auch nicht so prall, da du damit weitere Register und/oder Performance
opferst (nehmen wir EBP als Datenstackpointer, müssen wir immer ein
DS:-Prefix verwenden. Nehmen wir EBX o.ä., haben wir ein weiteres
Register verloren).
So? Hat denn Intel bei der Auflistung der 32-Bit Adressierungen
die Fussnote vergessen, die darauf hinweist? Diese fussnote findet
sich nämlich nur an der Auflistung der 16-bit Adressierungen.
386intel.txt, Zeile 1737ff:
# When EBP is used as the base register in an offset calculation, the
# offset is calculated automatically in the current stack segment (i.e.,
# the segment currently selected by SS). Because SS does not have to be
# explicitly specified, instruction encoding in such cases is more
# efficient.
Post by Jan Bruns
Post by Stefan Reuther
Und dann überschreibe ich dir eben statt der Rückkehradressen vtbl-Pointer.
Was ist ein vtbl-pointer?
Tabelle für virtuelle Funktionen, auch als VMT bekannt. Objekt-
orientierte Programme sind voll von indirekten Funktionsaufrufen über
Tabellen. Die Tabelle ist im allgemeinen schreibgeschützt, aber der
Zeiger auf die Tabelle liegt mitten im RAM, innerhalb des Objekts. Eine
prima Gelegenheit, eigene Zeiger einzuführen.


Stefan
Jan Bruns
2006-07-08 21:20:06 UTC
Permalink
Post by Stefan Reuther
Post by Jan Bruns
Post by Stefan Reuther
Post by Jan Bruns
Code ( muss nichtmal lesbar sein )
Stack ( enthält freiwillig nur Rücksprungadressen, so daß gar keine
Codeschnipsel existieren, die Daten über SS schreiben )
Daten ( rw, enthält "manuell" verwalteten Datenstapel )
Auch nicht so prall, da du damit weitere Register und/oder Performance
opferst (nehmen wir EBP als Datenstackpointer, müssen wir immer ein
DS:-Prefix verwenden. Nehmen wir EBX o.ä., haben wir ein weiteres
Register verloren).
Naja, aber "verloren" ist ja auch nicht ganz richtig.

Dann wäre EBP ja frei (bspw. anstelle von EBX) benutzbar.
So furchtbar oft habe ich EBX nun auch wieder nicht zur
Adressierung verwendet, als daß ein zusätzliches Präfix
ernsthaft problematisch wäre.

Klar, macht marginal mehr "Registerdruck", und ist auch neinfach
nicht so schön, wenn eines der "freien Register" anders
funktioniert, als die anderen.
Post by Stefan Reuther
Post by Jan Bruns
So? Hat denn Intel bei der Auflistung der 32-Bit Adressierungen
die Fussnote vergessen, die darauf hinweist? Diese fussnote findet
sich nämlich nur an der Auflistung der 16-bit Adressierungen.
# When EBP is used as the base register in an offset calculation, the
# offset is calculated automatically in the current stack segment (i.e.,
# the segment currently selected by SS). Because SS does not have to be
# explicitly specified, instruction encoding in such cases is more
# efficient.
Ja, selbst nochmal in aktuellerer Dou nachgelesen.
Hast recht.
Post by Stefan Reuther
Post by Jan Bruns
Post by Stefan Reuther
Und dann überschreibe ich dir eben statt der Rückkehradressen vtbl-Pointer.
Was ist ein vtbl-pointer?
Tabelle für virtuelle Funktionen, auch als VMT bekannt.
Ja, die kenne ich allerdings.

Aber da liesse sich doch ganz wunderbar mit verschiedenen
Segmenten arbeiten:

Stapelobjekte:

VMT einschl. Datenzeiger im SS, Daten auf dem manuell
verwalteten DS-Stack


Globalobjekte und dynamische Objekte:

VMT + Datenzeiger im SS, oberhalb des gültigen
Stapeladressraumes, verwaltet durch zusätzlichen
Heap-manager,
Daten weiterhin im DS


Also, ich will das Problem ja auch gar nicht schönreden,
soweit dem Programmierer Zeiger zur freien Verfügung stehen,
kann er sich natürlich immer so einiges kaputt machen.

Aber ob man nun als Programmierer unbedingt gleichzeitig
frei belegbare Methoden-Zeiger, frei überschreibbare
Rüclsprungadressen sowie u.U. sogar frei überschreibbaren
Code benötigt?

Gruss

Jan Bruns
Sebastian Biallas
2006-07-06 00:39:57 UTC
Permalink
Post by Jan Bruns
Trotzdem hat Heinz ja recht: Es sollte nicht möglich sein,
ist es aber, weil man (bzw. die Betriebsystementwickler) auf die
konsequente Anwendung von Segmentierung verzichtet hat.
Da die Segmentierung seit 32 Bit Betriebssystemen fast völlig
vernachlässigt wurde, ist die inzwischen auch in den Prozessoren "am
aussterben". Im Longmode gibt es sie nicht mehr wirklich und im 32 Bit
Modus empfiehlt AMD die CS-Basis immer auf 0 zu setzen, sonst gibts
irgendeine extra mistaken-branch-penalty.

Gibts eigentlich ein halbwegs aktuelles Bestriebssystem, dass noch
Segmentierung mit unterschiedlichen Basisadressen benutzt? Irgendein
Microkernel?
--
Gruß,
Sebastian
Florian Weimer
2006-07-14 19:13:33 UTC
Permalink
Post by Sebastian Biallas
Gibts eigentlich ein halbwegs aktuelles Bestriebssystem, dass noch
Segmentierung mit unterschiedlichen Basisadressen benutzt?
Üblicherweise wird das zur Implementierung von Thread-Local Storage
eingesetzt. 8-)

Du willtest vermutlich "unterschiedliche Deskriptoren" schreiben. Da
muß ich allerdings passen.
Erik S.
2006-07-22 19:56:14 UTC
Permalink
Hallo,
...., weil man (bzw. die Betriebsystementwickler) auf die
konsequente Anwendung von Segmentierung verzichtet hat.
Ich hab damals für Demos einen primitiven DOS-Extender (das Wort ist
schon viel zu groß für mein damaliges Werk) programmiert um die
64k-Grenze zu überwinden. Ich hatte mir dafür extra ein gutes Buch über
die Protected-Mode-Fähigkeiten der 386/486-CPUs gekauft und so richtig
auf Segmentierung und den ganzen anderen Kram gesetzt, Paging hatte ich
nur für einen einzigen Sonderfall benötigt.

Als ich das erste mal unter Windoof95 programmiert hatte war ich richtig
entsetzt das Kleinweich die ganzen tollen Möglichkeiten des
Protected-Mode völlig ungenutzt ließ. Als ich merkte das Linux die selbe
Schwäche hat war ich noch mehr enttäuscht. Seit dem Programmiere ich
unter den /modernen/ Betriebssystemen nur noch Anwendungsprogramme.

Der Flat-Mode ist IMHO die größte Fehlentscheidung der letzten 20 Jahre
Betriebssystementwicklung. Der einzigste Nachteil der Segmentierung,
auf 386, ist das sich die Programme die 4 GByte linearen Adressraum
teilen müssen (was damals aber noch nicht übermäßig schlimm war) und
auch heute für normale Bürorechner noch reichen tät (ja ich gebs zu die
4 GByte sind mittlerweile schon etwas eng aber man hätte in den
vergangenen 15 Jahren darauf reagieren können so wie AMD, vor 3 Jahren,
das ja auch tat aber dummerweise nur für den Flat-Mode). Der Vorteil
währe das man das Paging in der CPU komplett abschalten könnte falls die
laufenden Programme mit dem vorhandenen physikalischen Speicher
auskommen und das kann einiges an Performance bringen. Zusätzlich könnte
man die Segmente mit Hilfe vom Paging im laufenden Betrieb
defragmentieren (um danach das Paging wieder auszuschalten).
So furchtbar kompliziert ist die Unterscheidung
von near und far Zeigern ja nicht.
ACK. Das könnte eine Hochsprache ganz gut verstecken, nur C ist dafür zu
alt (obwohl das alte Borland-C unter DOS mit dem Mix aus FAR und NEAR
ganz gut zurecht kommt und der Programmierer davon auch kaum etwas merkt).
Hab' ich was übersehen?
Nicht wirklich. Ein paar Details sind in einem segmentierten System
schon anders aber im wesentlichen ist das ganz einfach.


Grüße
Erik

Heinz Saathoff
2006-07-06 06:35:00 UTC
Permalink
Moin,

[wg. F'Up: es geht um die Möglichkeit, per Pufferüberlauf die Return-
Adresse auf dem Stack zu ändern und damit im Datenpuffer eingeschleusten
Schadcode ausführen zu können]

Stefan Reuther schrieb...
Post by Stefan Reuther
Auf heutigen moderneren Architekturen, und dazu zähle ich auch die Intel
ab '386, sollte sowas doch aufgrund von Speicherschutzmechanismen nicht
möglich sein. Das Datensegment ist zwar les- und schreibbar, aber nicht
ausführbar. Dafür ist das Codesegment nur les- und ausführbar, aber
nicht schreibbar.
Das gilt für 286er-Betriebssysteme. OS/2 2.x oder Windows 3.0. Aktuelle
Betriebssysteme nutzen einen flachen Adressraum, in dem erstmal alle
Bytes gleich sind. Das "No-Execute"-Bit in der Pagetabelle ist auf x86
erst eine neuere Erfindung.
Flache Adressierung schließt aber das Segmentieren nicht aus, was man
spätestens dann merkt, wenn man mal eins der Segmentregister willkürlich
setzt. Soweit ich weiß, werden die Selektoren so initialisiert, daß sie
den gleichen logischen Adressraum abbilden, der dann durch die
Pagingunit auf den wirklichen physischen Speicher gemapped wird. Bitte
korregieren, falls ich da falsch liege. Ist schon eine Weile her, daß
ich das Prozessorhandbuch es '386 gelesen habe.
Post by Stefan Reuther
Hilft alles nicht dagegen, dass jemand einfach die Rücksprungadresse
tauscht ("return-to-libc-Attacke").
Gut, ein Rücksprung an eine beliebige Stelle im Code ist natürlich so
mörglich, aber es läßt sich kein Fremdcode einschleusen.
Post by Stefan Reuther
Ich habe mal folgendes kleine C-Programm als WIN-
Consolanwendung übersetzt. Beim Start bekomme ich einen Absturz
(privilegierte Anweisung). Unter DOS funktioniert es und ich ich erhalte
2 mal die Ausgabe von Func.
Das liegt aber nicht daran, dass die Kopie von func() nicht ausführbar
(im Sinne von Speicherschutz wäre). Vielmehr wird der Aufruf von
printf() über einen IP-relativen call aufgelöst. Wenn du den Code um
1000 Bytes nach hinten verschiebst, landet also auch der 'call printf'
1000 Bytes weiter hinten, irgendwo im Nirvana. Unter DOS hast du
vermutlich in einem Speichermodell compiliert, das den 'call printf' als
absoluten far-call ausführt, der unabhängig von der Stelle, wo er
ausgeführt wird, immer an die gleiche Stelle springt.
void Func() {
printf("Func is here\n");
}
Ersetze das durch
void Func() {
int (*volatile p)(const char*, ...) = printf;
p("Func is here\n");
}
und schon "funktioniert" auch die Kopie. Zur Initialisierung von
Zeigervariablen werden wieder absolute Adressen benutzt.
Hast recht. Funktioniert tatsächlich, auch unter Windows.
Ich dachte immer, daß für call absolute Adressen genutzt würden, da ja
der Code immer bei logischer Adresse 0 beginnt. Somit könnte der Linker
einfach die absolute Adresse eintragen.

Jetzt wird mir auch klar, warum der Schutz per CS-Register nicht wirken
kann, denn wenn die Selektoren für DS un CS gleiche Startadresse und
Länge aufweisen, dann kann der Datenpuffer sowohl bezuglich CS als auch
DS adressiert werden.

Unter DOS hat mein Progrämmchen nur funktioniert, weils im FAR-Modell
ein Inter-Segment-Call war und dort wieder absolute Adressen genutzt
werden.


- Heinz
Jan Bruns
2006-07-14 15:25:12 UTC
Permalink
Was mir gerade noch dazu einfällt:

Ein unschönes Problem bei der Anwedung von Segmenten auf 386+ CPUs
ist ja auch, daß die Paging-Tabelle nur auf 2^32 Byte Adressraum
ausgelegt ist.
Das ist natürlich etwas etwas blöde, einen eigentlich 48 Bit
Adressraum (rd. 16 Bit im Segmentselektor) dann noch vor'm Paging
auf 32 Bit gekürzt zu wissen, besonders, wenn viele Anwendungen
bereits 1GB und mehr Speicher anfordern.

Hier hätte man schon viel früher (bzw. von anfang an) reagieren mit
einer Ausweitung der Paging-Fähigkeit auf wenigstens 48 Bit sollen
(war aber beim 386er noch irgendwie egal, da hatte man ja eh' nur
einige MB Speicher, da sahen 32 Bit natürlich erstmal reichlich
bemessen aus, so im Vergleich zu den 16+4=20 Bits im RM).

Da das Problem wurde anscheinend nichtmal mit dem IA32e-Mode behoben
wurde, ist 32-Bit Segmentierung wohl kaum mehr sinnvoll einzusetzen,
wenn man nicht gerade für jede Veränderung an Segmentgrössen und
bei jedem Task-switch die komplette Pagingtabelle und (L+G)DT
reorganisieren will, und selbst dann ist der adressraum für
Anwendungen (bzw. Threads) immer noch auf 32-Bit beschränkt,
obwohl hier eigentlich 48 Bit zur Verfügung ständen.

Gruss

Jan Bruns
Loading...