[linux-programlama] Re: C'de dosya okumada sorunlar

---------

From: Arman Aksoy (armish@linux-sevenler.de)
Date: Sat 31 May 2003 - 22:36:05 EEST


On Sat, 31 May 2003 20:23:00 EEST
Serdar Koylu <serdarkoylu@fisek.com.tr> wrote:

>
> Selamlar..

Merhaba

>
> Uzun uzun ugrastiktan sonra tum kodu indirmeyi becerdim. Buffer
> doldurma ve ardindan tasirma olayi yasanmis bu kesin. Kaldi ki, NULL
> pointer ile cagrilan fclose cogu zaman EBADF errno ile EOF dondurur,
> SIGSEGV'e yol acmaz. En azindan benim bildigim libc'lerde boyleydi
> seklinde hatirliyorum..
>
>

Gercekten ayirdiginiz zamana ve ilginize cok cok tesekkur ediyorum ...

> Asil koda bir gozatinca, bir p bufferi olusturuluyor:
>
>
> > char *p, gonder[1024];
>
> if((p = (char *) malloc(1024)) == 0 ) {
> printf("Yetersiz bellek...\n");
> return 1;
> }
>
> Sonrada soyle bir ana loop var. recv ile data alinip, isleniyor:
>
>
> > while(recv(soket, p, 1024, 0)) {
> > ##p;
>
> p bir artiriliyor. Arti isareti bazne kaybolabildigi icin yerine #
> koydum..
>
> ....
> ...
> >
> > if( (strstr(p, "PRIVMSG")) != 0 && (strchr(p, '@')) != 0 )
> > islet(p, &soket);
> ....
> ....
> > memset(p, '\0', 1023);
> > }
>
> Simdi buraya bakarsak, p yukarida bir artiyor, ilk pass'ta mesele yok.
> Ama ikinci pass'ta p = p arti 2 olacak. Bu durumda 1023 byte otesi
> 1025. Bayt edecekki, tipik bir buffer overflow. Bu data segmenti
> uzerinde oldugu icin cogu zaman kritik bir exploit olmaz cogunlukla.
>

Benim ogrendigim sekilde ++p; seklinde yapildiginda kendisi (char *)
turunden oldugu icin 1 byte artmasi gerekiyordu.. Ben mi yanlis
ogrenmisim acaba?
O yuzden normalde malloc'ta 1024 ayirmama ragmen burada (memset(p, '\0',
1023);) 1023 yazdim... Anladigim kadariyla yanlis yapmisim...
Bunun nedenini bana aciklayabilir misiniz?

> Bu dongunun bir sekilde 8 kez calismis olmasi soyledigim gibi bir
> tesaduf olmus. Burada sadece biraz acemilik kokuyor. Hepimiz
> acemiydik. Yani, bunu bir tur kotuleme, kinama gibi algilamayin.
> Oncelikle bir pointere dinamik olarak bellek atamissaniz bunu hic bir
> zaman degismeyecek sekilde saklamaniz gerekir. Hatta realloc yaparken
> bile. Mesela:

Inanin acemi olmak o kadar zevkli birsey ki :)
Sanirim bu mesajin kaynagi listelerde cikan yanlis anlasilmalar sagolun

>
> ptr = malloc(1024);
>
> .....
> .....
>
> ptr = realloc(ptr, 2048);
>
> Bunu yapmak bile tipik bir acemiliktir. Soyleki, ya 2048 bayt bellek
> ayiramazsaniz ? Orijinal bellegin adresini nasil geri kazanacaksiniz ?
> Gerci Linux kolay kolay burada geriye NULL dondurmez. OOM killer,
> elinde baltasi cikar, bulabildigi ne kadar program varsa bir guzel
> budar. Size bellek saglamaya calisir. Ama bir programci asla OOM
> killer'e guvenmemek durumundadir.
>
> Kaldiki burada bir sekilde p bufferi uzerinde bir referans tanimlamak
> gerekirken dogrudan p bufferi kullanilmis. Simdi, bu yazdiginiz 1024.
> otesi baytlarin, gene size ait olan ve uzerine yazsaniz bile SIGSEGV
> olusturmayan file handler bolgesi uzerine vs. gelmedigini nerden
> bileceksiniz ? Belki de oyle bir yere denk geliyor, 8 bayt daha sizin,
> ama sonrasina yazayim dedigi anda yiyorsunuz SIGSEGV'yi. Yani buradaki
> 8 konusu aslinda tamamen tesaduf. Yani oradaki kodla, open, fclose ile
> alakali degil buyuk ihtimalle. Koda bir kac degisken vs. ekleseniz,
> mesela, sorun bu kez baska bir yerde karsiniza cikabilecekti..

P nin bir hafiza tasmasi yaratmasi neden fopen'i etkiliyor. Bu konularda
hic bilgim yok. Acaba ikisi ayni hafizayi mi kullaniliyorlar? (Sanirim
dokuman okumam gerek...)

>
> C sizin gercekten programci oldugunuzu, ne yaptiginizi bildiginizi
> farzeder. Eger oyle degilseniz ve C ile ugrasmaya devam ederseniz, bir
> sure sonra C galip gelir ve siz iyi bir programci olursunuz.

Umarim...

 
> Programda baska sorunlar da var. Mesela, recv() ile aldiginiz verinin,
> karsidan gelen verinin ne kadari olduguna dair hic bir ongorude
> bulunamazsiniz. Oncelikle receive bufferinde gelen verileri
> toparlamali, tam satiri vs. elde ettikten sonra o satiri parse etmeye
> dalmalidir.

Bu benim ilk ciddi projem. O yuzden buram buram sefalet bakan kodlarimin
kusuruna bakmayin :( Bu konularda biraz pratige ihtiyacim olacak
sanirim...

>
> Saygi ve sevgiler.
>

Yeniden tesekkurler eder, saygilarimi sunarim...

>
>

-- 
Armish
http://lfs.geleceklinux.org
http://linux-sevenler.de

---------

Bu arsiv hypermail 2.1.6 tarafindan uretilmistir.