Trusted length fields: set_label reads past the input buffer (kernel info leak); rename/link trust FileNameLength
Audit findings against master @ a0648190 (v1.10). Two related bugs where a length field inside an input structure is trusted without being checked against the actual IRP input length.
1. set_label trusts VolumeLabelLength — OOB read of the system buffer, contents readable back
FileFsLabelInformation handling (src/btrfs.c:1479-1482) passes the system buffer straight to set_label without ever consulting IrpSp->Parameters.SetVolume.Length. set_label (src/btrfs.c:1385-1434) then reads ffli->VolumeLabelLength bytes' worth of data from it:
vollen = ffli->VolumeLabelLength; // btrfs.c:1392
for (i = 0; i < ffli->VolumeLabelLength / sizeof(WCHAR); i++) { // btrfs.c:1394 — reads VolumeLabel[i]
...
}
Status = utf16_to_utf8(NULL, 0, &utf8len, ffli->VolumeLabel, vollen); // btrfs.c:1407 — scans vollen bytesThe system buffer is only as large as the caller's declared input length, so a small buffer combined with a large VolumeLabelLength makes the driver read adjacent kernel pool. Whatever it reads (up to BTRFS_LABEL_SIZE = 255 UTF-8 bytes, if it contains no / or \) is written into Vcb->superblock.label at btrfs.c:1420 and can subsequently be read back with FileFsVolumeInformation — a kernel pool information disclosure. Requires write access to the volume (label change).
2. drv_set_information almost never validates Parameters.SetFile.Length; rename/link trust FileNameLength
The only information class in drv_set_information (src/fileinfo.c:4160) that checks the IRP input length is FileValidDataLengthInformation (fileinfo.c:4044). In particular, set_rename_information and set_link_information copy fri->FileNameLength bytes out of fri->FileName with no comparison against Parameters.SetFile.Length:
if (fri->FileNameLength < sizeof(WCHAR)) { ... } // fileinfo.c:1877 / 2119
...
fn.Length = fn.MaximumLength = (USHORT)(fri->FileNameLength - sizeof(WCHAR));
fn.Buffer = fri->FileName;An NtSetInformationFile(FileRenameInformation) with a minimal input buffer but FileNameLength = 0x10000 makes the driver walk and copy up to 64 KB past the end of the system buffer. The over-read data is then used as the new on-disk name (and is readable back), so this is an information disclosure as well as a correctness problem; set_link_information (fileinfo.c ~3038-3041) has the same pattern.
Suggested fix: validate the class-specific length fields against IrpSp->Parameters.SetVolume.Length / IrpSp->Parameters.SetFile.Length at the top of the respective dispatchers (reject with STATUS_INVALID_PARAMETER), as is already done for FileValidDataLengthInformation.
Source: maharmstone/btrfs