Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pengandar sering menerima buffer input dengan header tetap dan data panjang variabel di bagian akhir, seperti dalam contoh berikut:
typedef struct _WAIT_FOR_BUFFER {
LARGE_INTEGER Timeout;
ULONG NameLength;
BOOLEAN TimeoutSpecified;
WCHAR Name[1];
} WAIT_FOR_BUFFER, *PWAIT_FOR_BUFFER;
if (InputBufferLength < sizeof(WAIT_FOR_BUFFER)) {
IoCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
return( STATUS_INVALID_PARAMETER );
}
WaitBuffer = Irp->AssociatedIrp.SystemBuffer;
if (FIELD_OFFSET(WAIT_FOR_BUFFER, Name[0]) +
WaitBuffer->NameLength > InputBufferLength) {
IoCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
return( STATUS_INVALID_PARAMETER );
}
Jika WaitBuffer-NameLength> adalah nilai ULONG yang sangat besar, menambahkannya ke offset dapat menyebabkan luapan bilangan bulat. Sebagai gantinya, driver harus mengurangi offset (ukuran header tetap) dari InputBufferLength (ukuran buffer), dan menguji apakah hasilnya meninggalkan cukup ruang untuk WaitBuffer-NameLength> (data panjang variabel), seperti dalam contoh berikut:
if (InputBufferLength < sizeof(WAIT_FOR_BUFFER)) {
IoCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
Return( STATUS_INVALID_PARAMETER );
}
WaitBuffer = Irp->AssociatedIrp.SystemBuffer;
if ((InputBufferLength -
FIELD_OFFSET(WAIT_FOR_BUFFER, Name[0]) <
WaitBuffer->NameLength) {
IoCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
return( STATUS_INVALID_PARAMETER );
}
Dengan kata lain, jika ukuran buffer dikurangi ukuran header yang tetap menghasilkan byte yang kurang dari jumlah yang diperlukan untuk data dengan panjang variabel, kami mengembalikan kesalahan.
Pengurangan yang disebutkan di atas tidak dapat mengalami underflow karena pernyataan if pertama memastikan bahwa InputBufferLength lebih besar dari atau sama dengan ukuran dari WAIT_FOR_BUFFER.
Berikut ini menunjukkan masalah luapan yang lebih rumit:
case IOCTL_SET_VALUE:
dwSize = sizeof(SET_VALUE);
if (inputBufferLength < dwSize) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
dwSize = FIELD_OFFSET(SET_VALUE, pInfo[0]) +
pSetValue->NumEntries * sizeof(SET_VALUE_INFO);
if (inputBufferLength < dwSize) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
Dalam contoh ini, luapan bilangan bulat dapat terjadi selama perkalian. Jika ukuran struktur SET_VALUE_INFO adalah kelipatan 2, nilai NumEntries seperti 0x80000000 menghasilkan luapan, ketika bit digeser ke kiri selama perkalian. Namun, ukuran buffer tetap akan lulus tes validasi, karena luapan menyebabkan dwSize tampak cukup kecil. Untuk menghindari masalah ini, kurangi panjang seperti dalam contoh sebelumnya, bagi menurut sizeof(SET_VALUE_INFO), dan bandingkan hasilnya dengan NumEntries.