Ha programozási hiba folytán egy adott buffer méretén túlírható, akkor az adott függvény visszatérési címe - amely a stack-en a buffer vége után tárolódik - átírható. Ennek oka az, hogy a C compilerek fordításkor nem ügyelnek a tömbhatár-túllépésre, illetve léteznek olyan könyvtári függvények, melyek a bufferbe írás során nem ellenőrzik, hogy a beírandó adat mérete nem haladja-e meg a tömb méretét. Ez nem lenne gond, mert minden ilyen függvénynek létezik biztonságos (a tömbhatárokat ellenőrző) változata, csakhogy könnyű a rosszabb megoldást választani. Így azokon a rendszereken, ahol a stack-en lévő kód futtatható, érdekes dolgokat művelhetünk (pl. a futó program jogaival shell hívható a visszatérési cím egy exec("/bin/sh"...)-ra állításával). Ha a program setuid/setgid-es, akkor az a kód, amire a visszatérési cím mutat, örökli a futó program jogait, tehát pl. az előbbi esetben egy setuid-es shell-t kaphatunk.
Súlyosabb a helyzet, ha az adott program egy hálózati kiszolgáló, mert bizonyos esetekben a hiba távolról is kihasználható, lehetőséget adva ezzel bárkinek a jogosulatlan hozzáféréshez.
A programozói gondatlanság ellen általában védelmet nyújt a StackGuard[18], amely egy GCC kiterjesztés. Érdemes használni setuid-es program fejlesztésekor, de ha nem bízunk egy más által fejlesztett programban, az is újrafordítható vele. Erre a feladatra készült a StackShield is.
Remélhetőleg rövid időn belül bekerül a kernelbe a Capabilities[41] is.
Solar Designertől származik egy kernel patch[19], amely korlátozott mértékben védelmet nyújt a stack futtathatóságát kihasználó támadások ellen, de létezik módszer a megkerülésére.
Sajnos ma már szinte művészetté vált a buffer overflow-k exploit-olása, így a heap buffer overflow-ké is, tehát a legjobb védekezés a setuid/setgid-es programok ellenőrzése.
Általában igaz, hogy a setuid bitet csak azon a programon szabad meghagyni, amit biztosan használunk és tudjuk, hogy szükség van rá. Egy jól beállított rendszeren csak néhány ilyen program van (pl. login, a passwd programjai, X wrapper, lp*, crontab és még néhány). Olyan programokról, mint az xterm vagy az rxvt, célszerű levenni, hacsak nem használjuk ki azokat a lehetőségeiket, amihez a setuid bitre szükség van.
Néhány program futtatása biztonságosabb, ha valamilyen wrapper-t használunk (pl. X wrapper). Ennek előnye, hogy maga a program nem setuid-os, csak a wrapper, ami a programnál jóval kisebb méretű és többé-kevésbé ellenőrzött kódot tartalmaz. Ezzel csökken egy esetleges programozási hiba kockázata.
A setuid/setgid-es programokat a következőképp kereshetjük
meg:
$ find / -type f \( -perm +4000 -o -perm +2000 \) -exec ls -la \{\} \;