authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2021-08-09 22:44:23+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-08-09 22:44:23+02:00
log2ccd023c6ae590b4ff311814ccf5ff508c7669ef
tree6d3e420271225b5e5d22bf8f1d1e9666d8eb01e8
parent799fedf612aa8742c446b015c12d21707a1dbec0
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Ip4Address parser: reject 0-prefixed components (#9538)

Some parsers interpret these as octal, some don't, and the confusion can lead to vulnerabilities. Return error.NonCanonical when parsing IPv4 addresses with 0 prefixes.

2 files changed, 11 insertions(+), 0 deletions(-)

lib/std/net.zig+10
...@@ -34,6 +34,7 @@ pub const Address = extern union {...@@ -34,6 +34,7 @@ pub const Address = extern union {
34 error.InvalidEnd,34 error.InvalidEnd,
35 error.InvalidCharacter,35 error.InvalidCharacter,
36 error.Incomplete,36 error.Incomplete,
37 error.NonCanonical,
37 => {},38 => {},
38 }39 }
3940
...@@ -55,6 +56,7 @@ pub const Address = extern union {...@@ -55,6 +56,7 @@ pub const Address = extern union {
55 error.InvalidEnd,56 error.InvalidEnd,
56 error.InvalidCharacter,57 error.InvalidCharacter,
57 error.Incomplete,58 error.Incomplete,
59 error.NonCanonical,
58 => {},60 => {},
59 }61 }
6062
...@@ -204,6 +206,7 @@ pub const Ip4Address = extern struct {...@@ -204,6 +206,7 @@ pub const Ip4Address = extern struct {
204 var x: u8 = 0;206 var x: u8 = 0;
205 var index: u8 = 0;207 var index: u8 = 0;
206 var saw_any_digits = false;208 var saw_any_digits = false;
209 var has_zero_prefix = false;
207 for (buf) |c| {210 for (buf) |c| {
208 if (c == '.') {211 if (c == '.') {
209 if (!saw_any_digits) {212 if (!saw_any_digits) {
...@@ -216,7 +219,13 @@ pub const Ip4Address = extern struct {...@@ -216,7 +219,13 @@ pub const Ip4Address = extern struct {
216 index += 1;219 index += 1;
217 x = 0;220 x = 0;
218 saw_any_digits = false;221 saw_any_digits = false;
222 has_zero_prefix = false;
219 } else if (c >= '0' and c <= '9') {223 } else if (c >= '0' and c <= '9') {
224 if (c == '0' and !saw_any_digits) {
225 has_zero_prefix = true;
226 } else if (has_zero_prefix) {
227 return error.NonCanonical;
228 }
220 saw_any_digits = true;229 saw_any_digits = true;
221 x = try std.math.mul(u8, x, 10);230 x = try std.math.mul(u8, x, 10);
222 x = try std.math.add(u8, x, c - '0');231 x = try std.math.add(u8, x, c - '0');
...@@ -1149,6 +1158,7 @@ fn linuxLookupNameFromHosts(...@@ -1149,6 +1158,7 @@ fn linuxLookupNameFromHosts(
1149 error.Incomplete,1158 error.Incomplete,
1150 error.InvalidIPAddressFormat,1159 error.InvalidIPAddressFormat,
1151 error.InvalidIpv4Mapping,1160 error.InvalidIpv4Mapping,
1161 error.NonCanonical,
1152 => continue,1162 => continue,
1153 };1163 };
1154 try addrs.append(LookupAddr{ .addr = addr });1164 try addrs.append(LookupAddr{ .addr = addr });
lib/std/net/test.zig+1
...@@ -92,6 +92,7 @@ test "parse and render IPv4 addresses" {...@@ -92,6 +92,7 @@ test "parse and render IPv4 addresses" {
92 try testing.expectError(error.InvalidEnd, net.Address.parseIp4("127.0.0.1.1", 0));92 try testing.expectError(error.InvalidEnd, net.Address.parseIp4("127.0.0.1.1", 0));
93 try testing.expectError(error.Incomplete, net.Address.parseIp4("127.0.0.", 0));93 try testing.expectError(error.Incomplete, net.Address.parseIp4("127.0.0.", 0));
94 try testing.expectError(error.InvalidCharacter, net.Address.parseIp4("100..0.1", 0));94 try testing.expectError(error.InvalidCharacter, net.Address.parseIp4("100..0.1", 0));
95 try testing.expectError(error.NonCanonical, net.Address.parseIp4("127.01.0.1", 0));
95}96}
9697
97test "resolve DNS" {98test "resolve DNS" {