[DB] CLoginData memory leak

Larry Watterson

Üye
Üye
Mesaj
62
Çözümler
1
Beğeni
209
Puan
699
Ticaret Puanı
0
TL;DR: YMIR dev ağabeyler duplicate login'i temizleyeceğiz derken bir mekanizma kurmuşlar ama normal çıkışa bağlamayı unutup sıvamışlar.

oyuncumuz bilal olsun;

bilal oyuna giriş yapıyor. arka planda ne oluyor?

QUERY_AUTH_LOGIN çalışıyor, bir CLoginData nesnesi free store'dan allocate ediliyor. bu nesneye dört farklı container'dan non-owning raw pointer ile erişiliyor amma velakin "non-owning" demek aslında doğru değil(inanın böyle demeyi çok isterdim) çünkü codebasede ownership'i taşıyan tek tip yok, dördü de fiilen "owner" gibi davranıyor, gerçi bi refcount falan var ama dökümantasyon falan olmadığı için pek anlamlandıramadım, binevi elle shared_ptr taklit edilmiş işte danglinge düşmeyelin falan ama 10 saatimi kodu anlamaya çalışarak geçirecek değilim. ben yine de laf atacağım(ağğbi YMIR ağğbi adamlar harika programcılar ağğğbiii, zamanın en iyisi ağğğbiii, adamlardan daha mı iyi bileceksiniz ağğğbiii).

"o nasıl oluyor la?" derseniz non-static data memberları inceleyebilirsiniz:

m_map_pkLoginData // login-key -> nesne
m_map_pkLoginDataByLogin // "bilal123" -> nesne
m_map_pkLoginDataByAID // account id -> nesne
m_map_kLogonAccount // "bilal123" -> nesne

yani şu..., neyse(hocam dayanamıyorum YMIR'e laf atıcam).

diyelim ki bilal biraz takılıp çıkıyor veya alt + f4 çekiyor. şimdi arka planda ne oluyor? QUERY_LOGOUT çalışıyor, orada da işte DeleteLogonAccount("bilal123") çağrılıyor.

Burayı görüntülemek için üye girişi yapmalı veya kayıt olmalısınız.



"IsDeleted() nedir lo?" m_bDeleted non-static data memberı return eden bir accessor. bunu true set eden tek yer SetDeleted mutator, o da yalnızca DeleteLoginData() içinde çağrılıyor. DeleteLoginData()'yı çağıran tek yer ise QUERY_AUTH_LOGIN, yani bu demek oluyor ki aynı hesabın tekrar login olması gerekiyor.

yani düşünelim;

bilal DB processi hiç restart olmayan bir sunucuda bir kez login/logout tetiklese ve bir daha hiç girmese ne olur? süper olurdu aslında ama, neyse olacak olan şu: QUERY_AUTH_LOGIN bir daha tetiklenmez, bu da sırayla şunlara yol açar:

Burayı görüntülemek için üye girişi yapmalı veya kayıt olmalısınız.



vay be bilalim, dağları devirdin.

ek olarak bilalden bağımsız aynı pattern RemovePeer() içinde de tekrar ediyor:

Burayı görüntülemek için üye girişi yapmalı veya kayıt olmalısınız.


bu sefer bilalin suçu yok, bir game server peer'i koparsa (artık crash mi olur restart mı olur siz karar verin) o peer üzerinden bağlı tüm hesapları m_map_kLogonAccount'tan silmeye çalışlıyor ama yine aynı döngü IsDeleted normal şartlarda hep false.

yani game server bir sebepten ötürü restart attığı anda o sırada bağlı olan (kaç kişi olduğuna siz karar verin) oyuncuların CLoginData'sı free edilmiyor.

ee noldu yani derseniz olay tam olarak CWE-772(araştırın bi zahmet)

gözümden kaçmadıysa herhangi bir dangling pointer, use after free falan yok, diğer 3 containerda halen geçerli ve erişilebilir. olay nesnenin işi bitmiş ama halen serbest bırakılmamış olması. uğraştırıcı ve fark edilmesi yüksek ihtimal olsa da bir saldırı senaryosu kurulabilir. zaten normal oyuncu devride başlı başına bir dert, art niyetli birini aramanıza da gerek yok uptime'da yardımcı olur.

fix(naked pointer kullanmaya devam etmek isteyenler için):


Burayı görüntülemek için üye girişi yapmalı veya kayıt olmalısınız.


burda iteratoru önce erase etmezseniz "DeleteLoginData" çağrısının hiçbir anlamı kalmaz, önce erase edin. bu oyunun codebaseinin içine biraz dalmak bile insanı akıl sağlığından eder, bu büyük ihtimalle açtığım son konu.

rica ederim, iyi forumlar.
 
Klasik YMIR çöpü, şaşırtmadı. Source içinde raw pointer ile amele gibi memory management yapmaya çalışırsan sonu bu olur zaten. Uzun uptime gören sunucularda zamanında az baş ağrıtmadı bu leak mevzuları. Public'e inmesi güzel olmuş, bilmeyenlerin epey işine yarar. Eline sağlık.
 
büyük ymir irfanı böyle yaptıysa kesin vardır bir bildiği
 
kesinlikle, beni fonlayanlar olduğu için laf atıyorum yoksa besmele çekmek lazım anmadan önce
işte bunlar hep amerikanın oyunları

hem belki adam metin2yi sevmiyodu oyun olarak ve batmasını istediği için böyle bir açık bıraktı nerden bileceğiz????? biz o ymir irfanı devlerin akıl ve zeka seviyesine erişebilir miyiz???? sanmıyorum...
 
Geri
Üst