Arbitrary read via msg_msg¶
Bir System V
struct msg_msg'inm_tssize field'ını corrupt et; böylecemsgrcv(..., MSG_COPY)orijinal allocation'ın ötesine kopyalar ve relative bir out-of-bounds kernel read elde edersin.
Mechanism¶
Note
msgsnd(), bir struct msg_msg header'ını ve hemen ardından inline olarak mesaj
payload'ını tutan tek bir kmalloc chunk allocate eder. Header field'ı m_ts, text
boyutunu kaydeder. Bir attacker m_ts'i gerçek payload'dan daha büyük bir değere
corrupt ederse (bitişik bir overflow ile veya header'a bir UAF write ile), sonraki bir
read m_ts byte transfer eder ve allocation'ın ötesini okur. MSG_COPY bunu mümkün
kılan numaradır: MSG_COPY ile do_msgrcv(), mesajı memcpy ile kopyalarken onu
queue'da bırakır (non-destructive) ve hardened-usercopy doğrulamasını bypass eder,
böylece şişirilmiş mesaj tekrar tekrar okunabilir.
Header layout'u:
struct msg_msg {
struct list_head m_list; /* also leaks heap pointers if read */
long m_type;
size_t m_ts; /* message text size <-- corrupt this */
struct msg_msgseg *next;
void *security;
/* message payload follows immediately */
}; /* 0x30 bytes */
struct msg_msgseg {
struct msg_msgseg *next;
/* inline data follows */
}; /* 0x8-byte header */
DATALEN_MSG = PAGE_SIZE - sizeof(struct msg_msg) = 0xfd0;
DATALEN_SEG = PAGE_SIZE - sizeof(struct msg_msgseg) = 0xff8.
Walkthrough¶
int qid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT);
struct { long mtype; char mtext[SZ]; } m = { .mtype = 1 };
msgsnd(qid, &m, SZ, 0); /* allocates msg_msg + payload */
/* ... overflow/UAF raises m_ts to a larger value (and sets next as needed) ... */
struct { long mtype; char buf[BIG]; } out;
msgrcv(qid, &out, BIG, 0, MSG_COPY | IPC_NOWAIT); /* OOB read of m_ts bytes */
Warning
Şişirilmiş m_ts kopyanın bir segment olacak bölgeye geçmesine neden olduğunda,
copy_msg()'nin next olarak okuduğu qword NULL olmalıdır — "kernel panic'leri
önlemek için bir sonraki segment null bir qword ile başlamalı." Layout'u öyle hazırla ki
traverse edilen next pointer'ı NULL ya da kontrol edilen geçerli bir msg_msgseg
olsun.
Sibling not
Bu not yalnızca m_ts şişirme → relative OOB read varyantını kapsar (read-only,
sabit yönde, allocation'ın hemen ötesi). next pointer'ını hijack ederek elde edilen
arbitrary read/write engine'i ayrı bir nottadır: bkz.
msg_msg arbitrary read/write object.
Detection¶
MSG_COPY, CONFIG_CHECKPOINT_RESTORE gerektirir; unprivileged process'lerden gelen
MSG_COPY'li msgrcv çağrılarını izlemek bu read varyantını işaretler.
Mitigation¶
CONFIG_CHECKPOINT_RESTORE'u kapatmak,MSG_COPYnon-destructive read yolunu ortadan kaldırır.- Kopya
memcpyüzerinden gittiğinden hardened-usercopy onu durdurmaz — savunma, başlangıçtakim_tscorruption'ını engellemeye dayanır (allocator hardening, cache isolation).