-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
mknod does not validate major/minor device number range
Component
mknod
Description
GNU mknod validates that major and minor device numbers fit within the platform's major_t and minor_t type ranges. When a value exceeds the valid range (e.g., 4294967296 which is 2^32), it rejects the input with an error message.
In uutils mknod, the major/minor values are parsed as u64 using value_parser!(u64) and passed directly to the makedev function without any range validation.
.arg(
Arg::new(options::MAJOR)
.value_name(options::MAJOR)
.help(translate!("mknod-help-major"))
.value_parser(value_parser!(u64)),
)(_, Some(&major), Some(&minor)) => makedev(major, minor),The custom makedev function performs bit manipulation that causes silent overflow.
fn makedev(maj: u64, min: u64) -> dev_t {
((min & 0xff) | ((maj & 0xfff) << 8) | ((min & !0xff) << 12) | ((maj & !0xfff) << 32)) as dev_t
}When maj = 4294967296 (0x100000000), the following happens.
maj & 0xfff= 0 (lower 12 bits are 0)maj & !0xfff= 0x100000000, and<< 32causes overflow
This results in a corrupted device number being created without any error message.
Test / Reproduction Steps
# GNU mknod rejects out-of-range major number
$ mknod lg32 c 4294967296 1
mknod: invalid major device number '4294967296'
# uutils mknod accepts it and creates device with wrong major number (overflow)
$ sudo strace coreutils mknod lg32 c 4294967296 1
mknodat(AT_FDCWD, "lg32", S_IFCHR|0666, makedev(0x2, 0x1)) = 0Impact
Silently accepting out-of-range device numbers causes creation of devices with incorrect major/minor values, which can lead to potential system instability.
Recommendations
Add range validation after parsing major/minor values.