Skip to content

_IO_file_jumps

Disk-destekli glibc stream'leri için varsayılan vtable; onu kullanan bir FILE forge etmek __overflow/__underflow'u (_IO_new_file_overflow/_underflow) attacker-kontrollü buffer pointer'ları üzerinden yönlendirir.

Mechanism

Note

_IO_file_jumps, bir file descriptor ile desteklenen FILE* stream'lerine (fopen, stdin/stdout/stderr) kurulan standart vtable'dır. Erişilebilir slot'lar __overflow → _IO_new_file_overflow (write buffer dolduğunda ya da flush'ta çağrılır) ve __underflow → _IO_new_file_underflow (read buffer'ı yeniden doldurmak için çağrılır)'dır. Bu fonksiyonlar yalnızca FILE'ın kendi buffer pointer'ları (_IO_write_base/ptr/end, _IO_read_ptr/end, _IO_buf_base/end) ve _fileno üzerinde işler. FSOP'un bozduğu invariant: o pointer'lar ve _flags/_fileno attacker-yazılabilir libc data'sıdır, dolayısıyla forge edilmiş ya da corrupt edilmiş bir FILE, zararsız bir flush'ı (ör. exit_IO_flush_all sırasında) attacker-seçimli memory aralıklarının kontrollü bir write(2)/read(2)'sine, ya da bir vtable swap ile birleştirildiğinde bir arbitrary call'a çevirir (bkz. io-vtable-check-bypass.md).

Walkthrough

_IO_file_jumps, FSOP zincirlerinin başladığı base table'dır. Anahtar slot'lar (glibc libio/fileops.c):

const struct _IO_jump_t _IO_file_jumps = {
  JUMP_INIT(finish,    _IO_file_finish),
  JUMP_INIT(overflow,  _IO_file_overflow),   /* _IO_new_file_overflow */
  JUMP_INIT(underflow, _IO_file_underflow),  /* _IO_new_file_underflow */
  JUMP_INIT(xsputn,    _IO_file_xsputn),
  JUMP_INIT(seekoff,   _IO_new_file_seekoff),
  ...
};

_IO_2_1_stdout_ aracılığıyla bir controlled-write (vtable swap gerekmez, hiçbir şeyi yenmez — salt field abuse):

  1. _flags = 0xfbad1800 ayarla (magic | _IO_IS_APPENDING), _IO_NO_WRITES'ı temizle.
  2. _IO_write_base'i leak'lemek istediğin libc/secret'e ve _IO_write_ptr/end'i onun ötesine işaret ettir; _fileno = 1 ayarla.
  3. Bir sonraki buffered print _IO_new_file_overflow_IO_do_writewrite(1, _IO_write_base, len) üzerinden flush'lanır — o aralığı stdout'a leak eder.

Warning

_IO_file_jumps slot'larının salt-field abuse'ü vtable check tarafından kapatılmaz (vtable gerçek olandır). Doğrudan arbitrary call değil, controlled read/write verir; code execution için in-range kalırken _IO_str_jumps/_IO_wfile_jumps'a swap edersin.

Detection

  • _IO_do_write/_IO_file_xsputn'den kaynaklanan beklenmedik büyük write/read syscall'ları.
  • Tutarsız buffer pointer'larında takılan hardened FILE yapıları (_IO_USE_OLD_IO_FILE, glibc check build'leri).

Mitigation

  • glibc 2.24+ vtable range check'i (io-vtable-check-bypass.md) arbitrary-vtable varyantlarını durdurur; full RELRO ve pointer guard takip eden çağrıları sınırlar.

References