ShadowCallStack (SCS), bir işlevin döndürdüğü adresi, yapraklı olmayan işlevlerin işlev prologunda ayrı olarak ayrılmış bir ShadowCallStack'e kaydederek ve döndürülen adresi işlev epilogunda ShadowCallStack'ten yükleyerek döndürülen adresin üzerine yazılmasına (ör. yığın arabelleği taşmaları) karşı koruma sağlayan bir LLVM enstrümantasyonu modudur. İade adresi, çözücüler ile uyumluluk için normal yığınta da depolanır ancak başka bir şekilde kullanılmaz. Bu sayede, normal yığıntaki dönüş adresini değiştiren saldırıların program kontrol akışını etkilemesi önlenir.
aarch64'te, ShadowCallStack'e referans vermek için x18
kaydedicisi kullanılır. Bu, ShadowCallStack'e yapılan referansların bellekte saklanması gerekmediği anlamına gelir.
Bu sayede, ShadowCallStack'in adresini rastgele belleği okuyabilen saldırganlara göstermeyen bir çalışma zamanı uygulamak mümkün olur.
Uygulama
Android, hem çekirdek hem de kullanıcı alanı için ShadowCallStack'i destekler.
Çekirdek için SCS'yi etkinleştirme
ShadowCallStack'i çekirdek için etkinleştirmek üzere çekirdek yapılandırma dosyasına aşağıdaki satırı ekleyin:
CONFIG_SHADOW_CALL_STACK=y
Kullanıcı alanında SCS'yi etkinleştirme
ShadowCallStack'i kullanıcı alanı bileşenlerinde etkinleştirmek için aşağıdaki satırları bileşenin taslak dosyasına ekleyin:
sanitize: { scs: true }
SCS, x18
yazmaçının ShadowCallStack'in adresini depolamak için ayrıldığını ve başka amaçlar için kullanılmadığını varsayar. Tüm sistem kitaplıkları, x18
yazmacını ayırmak için derlenir. Ancak, işlemdeki eski kodla birlikte çalışan kullanıcı alanı bileşenleri (ör. üçüncü taraf uygulamaları tarafından yüklenebilecek kitaplıklar) için SCS etkinleştirilirse bu durum x18
yazmacını bozabilir ve soruna yol açabilir. Bu nedenle, SCS'yi yalnızca eski ikili dosyalara yüklenmeyecek olan kendi kendine yeten bileşenlerde etkinleştirmenizi öneririz.
Doğrulama
SCS için özel bir CTS testi yoktur. Bunun yerine, SCS'nin cihazı etkilemediğini doğrulamak için CTS testlerinin SCS etkinken ve devre dışıyken geçtiğinden emin olun.