Skip to content

Commit 7bae337

Browse files
committed
Fixed crashes in dhcpv4
1 parent 38f7526 commit 7bae337

File tree

2 files changed

+94
-29
lines changed

2 files changed

+94
-29
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/target
2+
rust-toolchain
3+
.history
24
Cargo.lock
35
*.pcap

src/wire/dhcpv4.rs

Lines changed: 92 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,45 +28,99 @@ enum_with_unknown! {
2828
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2929
#[allow(unused)]
3030
pub enum ClientArchType {
31-
/// Intel x86PC
32-
X86PC = 0,
33-
/// NEC/PC98
31+
X86Bios = 0,
3432
PC98 = 1,
35-
/// EFI Itanium
3633
EfiItanium = 2,
37-
/// DEC Alpha
3834
DecAlpha = 3,
39-
/// Arc x86
4035
ArcX86 = 4,
41-
/// Intel Lean Client
4236
IntelLeanClient = 5,
43-
/// EFI IA32
44-
EfiIA32 = 6,
45-
/// EFI BC
46-
EfiBc = 7,
47-
/// EFI Xscale
37+
X86Uefi = 6,
38+
X64Uefi = 7,
4839
EfiXscale = 8,
49-
/// EFI x86-64
50-
EfiX86_64 = 9,
40+
Ebc = 9,
41+
Arm32Uefi = 10,
42+
Arm64Uefi = 11,
43+
PowerPcOpenFimware = 12,
44+
PowerPcepapr = 13,
45+
PowerOpalv3 = 14,
46+
X86UefiHttp = 15,
47+
X64UefiHttp = 16,
48+
EbcFromHttp = 17,
49+
Arm32UefiHttp = 18,
50+
Arm64UefiHttp = 19,
51+
X86BiosHttp = 20,
52+
Arm32Uboot = 21,
53+
Arm64Uboot = 22,
54+
Arm32UbootHttp = 23,
55+
Arm64UbootHttp = 24,
56+
Riscv32Uefi = 25,
57+
Riscv32UefiHttp = 26,
58+
Riscv64Uefi = 27,
59+
Riscv64UefiHttp = 28,
60+
Riscv128Uefi = 29,
61+
Riscv128UefiHttp = 30,
62+
S390Basic = 31,
63+
S390Extended = 32,
64+
Mips32Uefi = 33,
65+
Mips64Uefi = 34,
66+
Sunway32Uefi = 35,
67+
Sunway64Uefi = 36,
68+
LoongArch32Uefi = 37,
69+
LoongArch32UefiHttp = 38,
70+
LoongArch64Uefi = 39,
71+
LoongArch64UefiHttp = 40,
5172
}
5273

5374
impl TryFrom<u16> for ClientArchType {
5475
type Error = Error;
5576

5677
fn try_from(value: u16) -> Result<Self> {
57-
match value {
58-
0 => Ok(Self::X86PC),
59-
1 => Ok(Self::PC98),
60-
2 => Ok(Self::EfiItanium),
61-
3 => Ok(Self::DecAlpha),
62-
4 => Ok(Self::ArcX86),
63-
5 => Ok(Self::IntelLeanClient),
64-
6 => Ok(Self::EfiIA32),
65-
7 => Ok(Self::EfiBc),
66-
8 => Ok(Self::EfiXscale),
67-
9 => Ok(Self::EfiX86_64),
68-
_ => Err(Error::Unrecognized),
69-
}
78+
use ClientArchType::*;
79+
let res = match value {
80+
0 => X86Bios,
81+
1 => PC98,
82+
2 => EfiItanium,
83+
3 => DecAlpha,
84+
4 => ArcX86,
85+
5 => IntelLeanClient,
86+
6 => X86Uefi,
87+
7 => X64Uefi,
88+
8 => EfiXscale,
89+
9 => Ebc,
90+
10 => Arm32Uefi,
91+
11 => Arm64Uefi,
92+
12 => PowerPcOpenFimware,
93+
13 => PowerPcepapr,
94+
14 => PowerOpalv3,
95+
15 => X86UefiHttp,
96+
16 => X64UefiHttp,
97+
17 => EbcFromHttp,
98+
18 => Arm32UefiHttp,
99+
19 => Arm64UefiHttp,
100+
20 => X86BiosHttp,
101+
21 => Arm32Uboot,
102+
22 => Arm64Uboot,
103+
23 => Arm32UbootHttp,
104+
24 => Arm64UbootHttp,
105+
25 => Riscv32Uefi,
106+
26 => Riscv32UefiHttp,
107+
27 => Riscv64Uefi,
108+
28 => Riscv64UefiHttp,
109+
29 => Riscv128Uefi,
110+
30 => Riscv128UefiHttp,
111+
31 => S390Basic,
112+
32 => S390Extended,
113+
33 => Mips32Uefi,
114+
34 => Mips64Uefi,
115+
35 => Sunway32Uefi,
116+
36 => Sunway64Uefi,
117+
37 => LoongArch32Uefi,
118+
38 => LoongArch32UefiHttp,
119+
39 => LoongArch64Uefi,
120+
40 => LoongArch64UefiHttp,
121+
_ => return Err(Error::Unrecognized),
122+
};
123+
Ok(res)
70124
}
71125
}
72126

@@ -197,6 +251,7 @@ impl<'a> DhcpOption<'a> {
197251
let length = *buffer.get(1).ok_or(Error::Truncated)? as usize;
198252
skip_len = length + 2;
199253
let data = buffer.get(2..skip_len).ok_or(Error::Truncated)?;
254+
200255
match (kind, length) {
201256
(field::OPT_END, _) | (field::OPT_PAD, _) => unreachable!(),
202257
(field::OPT_DHCP_MESSAGE_TYPE, 1) => {
@@ -212,6 +267,10 @@ impl<'a> DhcpOption<'a> {
212267
}
213268
(field::OPT_CLIENT_ARCH, _) => option = DhcpOption::ClientArchTypeList(data),
214269
(field::OPT_CLIENT_MACHINE_ID, _) => {
270+
if data.len() < 2 {
271+
return Err(Error::Truncated);
272+
}
273+
215274
let id_type = MachineIdType::try_from(data[0])?;
216275

217276
option = DhcpOption::ClientMachineId(MachineId {
@@ -303,6 +362,9 @@ impl<'a> DhcpOption<'a> {
303362
}
304363
_ => {
305364
skip_length = self.buffer_len();
365+
366+
assert!(skip_length <= buffer.len());
367+
306368
buffer[1] = (skip_length - 2) as u8;
307369
match *self {
308370
DhcpOption::EndOfList | DhcpOption::Pad => unreachable!(),
@@ -1402,8 +1464,9 @@ mod test {
14021464
],
14031465
})
14041466
.emit(options);
1405-
options = DhcpOption::ClientArchTypeList(&(ClientArchType::X86PC as u16).to_be_bytes())
1406-
.emit(options);
1467+
options =
1468+
DhcpOption::ClientArchTypeList(&(ClientArchType::X86Bios as u16).to_be_bytes())
1469+
.emit(options);
14071470
options = DhcpOption::ClientNetworkInterfaceId(NetworkInterfaceVersion {
14081471
interface_type: NetworkInterfaceType::Undi,
14091472
major: 2,

0 commit comments

Comments
 (0)