Bagikan melalui


Gagal Memeriksa Ukuran Buffer

Saat menangani IOCTL dan FSCTL yang mengimplementasikan I/O buffer, driver harus selalu memeriksa ukuran buffer input dan output untuk memastikan bahwa buffer dapat menyimpan semua data yang diminta. Jika permintaan menentukan FILE_ANY_ACCESS, seperti yang dilakukan sebagian besar IOCTL driver dan FSCTL, pemanggil apa pun yang memiliki handel ke perangkat memiliki akses ke permintaan IOCTL atau FSCTL yang di-buffer untuk perangkat tersebut, dan dapat membaca atau menulis data di luar akhir buffer.

Ukuran Buffer Input

Misalnya, asumsikan bahwa kode berikut muncul dalam rutinitas yang dipanggil dari rutinitas Pengiriman, dan bahwa driver belum memvalidasi ukuran buffer yang diteruskan dalam IRP:

   switch (ControlCode)
      ...
      ...
      case IOCTL_NEW_ADDRESS:{
         tNEW_ADDRESS *pNewAddress = 
            pIrp->AssociatedIrp.SystemBuffer;

         pDeviceContext->Addr = RtlUlongByteSwap (pNewAddress->Address);

Contoh tidak memeriksa ukuran buffer sebelum pernyataan penugasan (disorot). Akibatnya, referensi pNewAddress-Address> di baris berikutnya dapat rusak jika buffer input tidak cukup besar untuk berisi struktur tNEW_ADDRESS.

Kode berikut memeriksa ukuran buffer, menghindari potensi masalah:

   case IOCTL_NEW_ADDRESS: {
      tNEW_ADDRESS *pNewAddress =
         pIrp->AssociatedIrp.SystemBuffer;

      if (pIrpSp->Parameters.DeviceIoControl.InputBufferLength >=
             sizeof(tNEW_ADDRESS)) {
         pDeviceContext->Addr = RtlUlongByteSwap (pNewAddress->Address);

Kode untuk menangani I/O buffer lainnya, seperti permintaan WMI yang menggunakan buffer ukuran variabel, dapat memiliki kesalahan serupa.

Ukuran Buffer Output

Masalah buffer output mirip dengan masalah buffer input. Mereka dapat dengan mudah merusak kumpulan, dan pemanggil mode pengguna mungkin tidak menyadari bahwa kesalahan apa pun telah terjadi.

Dalam contoh berikut, driver gagal memeriksa ukuran SystemBuffer:

   case IOCTL_GET_INFO: {

       Info = Irp->AssociatedIrp.SystemBuffer;

       Info->NumIF = NumIF;
       ...
       ...
       Irp->IoStatus.Information =
             NumIF*sizeof(GET_INFO_ITEM)+sizeof(ULONG);
       Irp->IoStatus.Status = ntStatus;
   }

Dengan asumsi bahwa bidang NumIF dari buffer sistem menentukan jumlah item input, contoh ini dapat mengatur IoStatus.Information ke nilai yang lebih besar dari buffer output dan dengan demikian mengembalikan terlalu banyak informasi ke kode mode pengguna. Jika aplikasi dikodekan dengan tidak benar, dan memanggil dengan buffer output yang terlalu kecil, kode sebelumnya dapat merusak kumpulan dengan menulis di luar akhir buffer sistem.

Ingatlah bahwa manajer I/O mengasumsikan bahwa nilai di bidang Informasi valid. Jika penelepon melewati alamat mode kernel yang valid untuk buffer output dan ukuran nol byte, masalah serius dapat terjadi jika driver tidak memeriksa ukuran buffer output dan dengan demikian menemukan kesalahan.