Osobne z toho mam smisene pocity. Pravda, ABI neco vyzaduje a gcc se na to klidne muze spolehnout, neni problem, v Linuxu se to musi opravit. Ale na druhou stranu, po tech letech zkusenosti, abi-neabi, ocekavat nejakou hodnotu DF je proste cunarna :)
Znamená to jen, že když přeložíte binárku co používá memmove a během něho obhospodařuje signály 32bitově na 386, má malou pravděpodobnost, že v signálu použije memcpy se špatně nastaveným flagem.
Koukám, že zpráva o novém GCC se nikam nedostala, ale chybící CLD všude :)
x86-64 glibc nepoužívá STD a nikdy nepoužívala (stringy pozpátku jsou pomalé, ani 32bit libc by to dělat nemusela, kdyby se její maintaneři rozhodli alespoň trošku starat o výkon).
Jediná situace, kdy se může direction flag přehodit je když aplikace má vlastní ASM kód co dělá STD a v něm se stane signál. Jak jde přes objdump snadno ověřit, v openSuSE distru takové aplikace ale nejsou. Asi nejsou ani jinde. Takže bych řekl, že x86-64 je úplně v bezpečí. Na i386 je pravděpodobnost taky velmi malá (Fedora i SuSE používaly vývojové verze GCC celkem dlouho a změna byla provedena v prosinci 2006). Samozřejmně většina dister to opravila či opraví v security update....
Já bych tohle nebagatelizoval. Sice je napsaný zákon, že kódy by měly nechávat po sobě vynulovaný directon flag, ale zase pokud ho kód potřebuje, tak se nesmí spoléhat na to, v jakém stavu direction flag je!!! A pokud se na to spoléhá kompilátor, je to chyba jako hrom!!!
Jinak vůbec celé stringové operace v asm na x86 jsou velmi pomalé, vyplatí se až od velkého počtu opakování a v případě dalších podmínek - procesor je moc neoptimalizuje. A v každém dalším modelu procesorů jsou čím dál více rychlostně penalizovány oproti jiným metodám.
Sice pravděpodobnost chyby je malá, ale máte v kódu časovanou bombu, která může naprosto kdykoli vybouchnout. Situace, kdy se může přehodit directon flag je v podstatě naprosto kdykoli. Od vlastního asm kódu, přes knihovny cizích stran (kterých jsou tisíce), přes cokoli jiného. Nic není v bezpečí, ani i386, ani 64, je to prostě bug, který se může projevit kdykoli, a který celý kód dělá chatrným.
Nevím, proč se rovnou nemůže říct - tohle je chyba, je to chyba, kterou je nutné odstranit - a proč se namísto toho bagatelizuje něco takového. Chyby se stávají, ale tohle není věc, které bych věřil - a kde bych se nechal ukolébat, že je to v pořádku. Tohle je zatraceně nepříjemná věc.
Jestli jsem si všiml, tak DF je součástí EFLAGS, a tedy součástí kontextu procesu. Obecně tedy jde o interní věc daného procesu. Nehrozí, že změníte DF v programu typu Hello World, a problém se projeví v kernelu.
V daném případě je průšvihem hlavně "nesouhra" mezi kompilátorem a kódem kernelu, což je samozřejmě třeba řešit.
Pokud se nesmíte memcpy používat jako renentrantní, tak kromě toho že jsem čínský papež, tak co už ksakru chcete používat? Jakou funkci? Na memcpy není nic, co by bránilo Vám jí použít naprosto, ale úplně kdekoli - dokonce i v hodně kritických místěch.
Dnešní memcpy - tedy u dobrých a optimalizovaných kompilátorů (což asi není případ gcc) moc movs instrukce nevidí, neboť jsou nesmírně pomalé - a vyplatí se až při kopírování opravdu velkého objemu dat, a to jen někdy. Takže na dobrém kompilátoru většina volání mamcpy vůbec stringové instrukce nepoužívá.
"All functions not in the above table are considered to be unsafe with respect to signals."
Jasně, že ve většině implementací je memcpy signal-safe. Ale standard umožňuje, aby nebyla. Podle té specifikace memcpy např. může používat globální proměnnou.
Tak kompilátor, který používá implementaci memcpy, která není threadově, signálově, devicově a vůbec všelijak bezepčná za prvé já vůbec neznám, za druhé by to bylo diletantství takového rázu, že ten vývojář by měl raději kopat kanály, a za druhé takový kompilátor, nebo knihovna, která nedokáže implmentovat naprosto a všude bezpečnou memcpy funcki je pro mě nedůvěryhodná jako celek. Protože pokud někdo z memcpy udělá nebezpečnou funkci, pak se o to musí cíleně snažit - a určitě udělal daleko více bot v samotném kompilátoru, či knihovně, protože je amatér.
Druhá možnost je samozřejmě špatná implementace signálů v tom kterém operačním systému - tomu bych věřil spíš. Pokud bude implementace signálů náchylná na to, že se nesmí používat všechny běžné procesorové registry například, tak pak uvnitř implementace signálů není možné používat bezpečně naprosto žádnou C funkci - bezpečný je jedině na míru napsaný assembler.
Osobně memcpy je vůbec těžké napsat tak, aby byla nějak problémová. To člověk musí mít výrazný destrukční talent a ještě se o to snažit, aby se mu podařilo jí nějak udělat problémovou.
Jsem chtěl nový kernel zkompilovat novým gcc ... ale koukám na roota a vidím, že prvně budu muset zkompilovat nový kernel starým gcc, pak zkompilovat gcc, a pak zkompilovat nový kernel novým gcc.
Ale jsem psychopat a styk se ženami neprovozuji, tak to nevadí, že budu dnes kompilovat.