2013-03-19 24 views
15

Gcc, arabellek taşması saldırısını önlemek için akıllıca bellek ayırma yapar mı?gcc bellek ayırma sorunu - arabellek taşması saldırısı

int function(char *str) { 
    int a = 0;     // See the 
    char b[16] = "abcd";  // changes here 

    if(!strcmp(b, str)) 
     a = 1; 

    return a; 
} 

ve

int function(char *str) { 
    char b[16] = "abcd";  // See the 
    int a = 0;     // changes here 

    if(!strcmp(b, str)) 
     a = 1; 

    return a; 
} 

o zaman değişkenleri ve karakter dizisi tamsayı ilk bellek tahsis GDB ile hata ayıklama; değişken beyanının sırası ne olursa olsun. i.e. Her iki durumda da, derleyici önce belleği a ve daha sonra b'a ayırır.

(higher address) 
    Memory 
|  | 
|  | 
+--------+ 
|  | 
|  | 
|  | 
|  | 
+--------+ <----- b (16 bytes) 
|  | 
+--------+ <----- a (4 bytes) 
|  | 
(lower address) 

Demek ki str 16'dan fazla karakter arz bile, a değerini etkileyemez. Burada kimse bana yardım edebilir mi?

Teşekkür ederiz.

+1

_The Standard_, herhangi bir amaç için böyle bir yeniden sıralama yapılmasına izin verir, derleyici bunu yapmak ister. En yaygın - optimizasyon. Hala "zeka", ama "tampon taşma saldırısı" önlemek için değil. Ve hala bir _undefined behavior_ (arabellek taşması) –

cevap

11

Evet, -fstack-protector bayrağı ile çalıştırırsanız.

Bayrak ile çalışırken, GCC yığın kanarcıkları ekler, yığın değişkenlerinin en yüksek kısmına dizi değişkenlerini sıralar ve taşmaları daha zor hale getirir ve diğer değişkenleri bozar ve işlev argümanlarının kopyalarını diğer yerliler.

fazla bilgi için Wikipedia page on Buffer overflow protection ve ProPolice sitesine bakınız

+0

@Ravi: Bazı dağıtımlar varsayılan olarak etkinleştirir. '-fno-stack-protector' ile derlemeyi deneyin ve bir fark yaratıp yaratmadığını görün. – Hasturkun

+0

@ MM .: Eklendi. Genellikle kısırlık için dışarı çıktı. – Hasturkun

+1

Haklısınız. GCC varsayılan olarak etkinleştirir. Eğer '-fno-stack-protector' ile derlersek, sıra diziliminin en yüksek kısmına _array değişkenleri yerine sırayla sırayla bellek ayırır. teşekkür ederim – Ravi

-1

Gcc, bellek taşması saldırılarını önlemek için akıllıca bellek ayırma yapar mı?

Hayır, öyle değil. Her zaman mümkün olmayan bir saldırıyı veya sınır denetimi olmadan arabellek taşmasını önleyemezsiniz. Bazen bir olaydan sonra bir taşma tespit edebilirsiniz.

En iyi ihtimalle, derleyici yığındaki geri dönüş adresinin yakınında ek bilgi (canary value adı verilen) içerebilir ve işlevden geri dönmeden önce, bellek taşması nedeniyle bozulmamış ve üzerine yazılmadığını kontrol edin.

+2

Bu yanlış, GCC arabellek taşması etkilerini önlemek için değişkenleri yeniden sıralayabilir ve yeniden düzenler – Hasturkun

+0

@Hasturkun Sınır denetimi olmadan taşmayı önleyemezsiniz. Bazen sadece birini tespit edebilirsin. –

+0

Bu doğru. Ancak ProPolice, vb. Tarafından yapılanları azaltabilirsiniz. – Hasturkun

2

GCC tampon taşmaları karşı korumak için böyle bir özellik olsa bile, sabit bir değişken bildirim emri neden olabilir burada birçok diğer konuları vardır. Bildirimin yapıldığı yer önemli değilse, derleyici, değişkenin çalışma zamanında ne zaman ve nasıl kullanıldığına bağlı olarak tahsis kararları alacaktır.

Daha da önemlisi, derleyici değişkenleri yığın çerçevesinde mümkün olan en iyi hizaya getirerek umuyoruz. Bu, CPU'ya ve ayarın optimize edilmesine bağlı olarak tamamen farklı şekillerde yapılabilir. Hız için optimize etmek, bellek tüketimini optimize etmek için karşılaştırıldığında tamamen farklı bir tahsis sağlayabilir. Ve büyük olasılıkla, tüm RAM ayırma ihtiyacını ortadan kaldırarak CPU kayıtlarında bazı değişkenler koyacaktır.

Sorunuzu yanıtlamak için: GCC, derleyici bağlantı noktasına bağlı olarak değişkenleri çeşitli yollarla ayırır. Nasıl yapar, programcının aşırı endişelenmesi gereken bir şey değildir. Arabellek taşması saldırılarına karşı korumak için yığının yeniden düzenlenmesi için seçenekler olabilir, ancak bu bazı uygulamalarda yalnızca anlamlıdır. Bildiğimiz her şey için belirli bir sisteme herhangi bir girdi bile olmayabilir. Bu nedenle, bir derleyicinin varsayılan olarak bu güvenlik özelliğini etkinleştirmesi mantıklı değildir.