Google har publicerat källkoden för GWPSan-verktyget, som är avsett för att upptäcka fel vid körningen av program som har byggts för x86-64 och ARM64-arkitekturer. GWPSan levereras som ett delat bibliotek som länkas vid programstart med hjälp av LD_PRELOAD och använder tillgängliga mekanismer i Linux-kärnan för att analysera programmet, såsom stopp (PERF_TYPE_BREAKPOINT) och processprovtagning. Koden är skriven i C++ och distribueras under Apache 2.0-licensen.
GWPSan är designat som ett modulärt ramverk som stödjer anslutning av moduler med implementeringar av detektorer för olika klasser av fel. GWPSan utför dynamisk analys, aktiverad genom signalhanterare, vilket gör det möjligt att undvika att ändra den körbara koden för programmet. För att de flesta detektorer ska fungera effektivt krävs att programmet byggs med vissa kompilatorflaggor som lägger till nödvändig metadata. Minimikravet är Clang 18 och Linux-kärnan 6.4.
För närvarande finns det tre detektorer:
- UAR (Use-after-return) — identifierar fel som orsakas av att ett objekt på stacken används efter att funktionen, där detta objekt definierats, har avslutats. Skyddet organiseras genom att fånga ingångs- och utgångspunkter för funktionen — vid ingång ersätts stacken med en kopia för användning under körningen av funktionen, och vid utgång återställs det gamla tillståndet för stacken.
- TSan (Thread Sanitizer) — identifierar race conditions mellan trådar (Data-race), som uppstår när olika trådar som körs samtidigt kan läsa eller ändra gemensamma minnesområden utan att använda synkroniseringsmetoder. Skyddet baseras på hårdvarupunkter som kopplas till gemensamma minnesområden. Den aktiverade hanteraren pausar tråden under en kort tidsperiod vid minnesåtkomst och kontrollerar under denna paus om en stopppunkt har aktiverats för en annan tråd.
- LMSan (Lightweight Memory Sanitizer) — identifierar användningen av oinitialiserade data i minnet. Detektorn är markerad som experimentell och rekommenderas inte för användning.
GWPSan analyserar den körbara koden av programmet med hjälp av DynamoRIO-ramverket för att avkoda maskinkoden till abstrakta ISA-instruktioner, som sedan utförs via emulering. Genom periodiska signaler från timern anropas den enhetliga hanteraren, som vid varje anrop kör en specifik del av instruktionerna för den analyserade strömmen. Vid upptäckten av vissa instruktioner under körningen aktiveras en specifik problemdetektor för dessa instruktioner, till exempel aktiveras en detektor för race-tillstånd för instruktioner som gör minnesåtkomst.
Källa: opennet.ru
