Skip to content

Commit 262ba9b

Browse files
yuwatabluca
authored andcommitted
icmp6-util: make icmp6_receive() accept the null source address
Fixes #29050. (cherry picked from commit 4961f56) (cherry picked from commit fabdb28)
1 parent bd96e3a commit 262ba9b

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

src/libsystemd-network/fuzz-ndisc-rs.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ int icmp6_bind_router_advertisement(int index) {
2424
return -ENOSYS;
2525
}
2626

27+
static struct in6_addr dummy_link_local = {
28+
.s6_addr = {
29+
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30+
0x12, 0x34, 0x56, 0xff, 0xfe, 0x78, 0x9a, 0xbc,
31+
},
32+
};
33+
2734
int icmp6_receive(
2835
int fd,
2936
void *iov_base,
@@ -36,6 +43,9 @@ int icmp6_receive(
3643
if (ret_timestamp)
3744
triple_timestamp_get(ret_timestamp);
3845

46+
if (ret_sender)
47+
*ret_sender = dummy_link_local;
48+
3949
return 0;
4050
}
4151

src/libsystemd-network/icmp6-util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ int icmp6_receive(
182182
sa.in6.sin6_family == AF_INET6) {
183183

184184
addr = sa.in6.sin6_addr;
185-
if (!in6_addr_is_link_local(&addr))
185+
if (!in6_addr_is_link_local(&addr) && !in6_addr_is_null(&addr))
186186
return -EADDRNOTAVAIL;
187187

188188
} else if (msg.msg_namelen > 0)

src/libsystemd-network/sd-ndisc.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
227227

228228
switch (r) {
229229
case -EADDRNOTAVAIL:
230-
log_ndisc(nd, "Received RA from non-link-local address. Ignoring.");
230+
log_ndisc(nd, "Received RA from neither link-local nor null address. Ignoring.");
231231
break;
232232

233233
case -EMULTIHOP:
@@ -246,6 +246,11 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
246246
return 0;
247247
}
248248

249+
/* The function icmp6_receive() accepts the null source address, but RFC 4861 Section 6.1.2 states
250+
* that hosts MUST discard messages with the null source address. */
251+
if (in6_addr_is_null(&rt->address))
252+
log_ndisc(nd, "Received RA from null address. Ignoring.");
253+
249254
(void) event_source_disable(nd->timeout_event_source);
250255
(void) ndisc_handle_datagram(nd, rt);
251256
return 0;

src/libsystemd-network/sd-radv.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
271271

272272
switch (r) {
273273
case -EADDRNOTAVAIL:
274-
log_radv(ra, "Received RS from non-link-local address. Ignoring");
274+
log_radv(ra, "Received RS from neither link-local nor null address. Ignoring");
275275
break;
276276

277277
case -EMULTIHOP:
@@ -295,6 +295,9 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
295295
return 0;
296296
}
297297

298+
/* TODO: if the sender address is null, check that the message does not have the source link-layer
299+
* address option. See RFC 4861 Section 6.1.1. */
300+
298301
const char *addr = IN6_ADDR_TO_STRING(&src);
299302

300303
r = radv_send(ra, &src, ra->lifetime_usec);

src/libsystemd-network/test-ndisc-rs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ static void router_dump(sd_ndisc_router *rt) {
4141
assert_se(rt);
4242

4343
log_info("--");
44-
assert_se(sd_ndisc_router_get_address(rt, &addr) == -ENODATA);
44+
assert_se(sd_ndisc_router_get_address(rt, &addr) >= 0);
45+
log_info("Sender: %s", IN6_ADDR_TO_STRING(&addr));
4546

4647
assert_se(sd_ndisc_router_get_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
4748
log_info("Timestamp: %s", FORMAT_TIMESTAMP(t));
@@ -176,6 +177,13 @@ int icmp6_bind_router_advertisement(int ifindex) {
176177
return -ENOSYS;
177178
}
178179

180+
static struct in6_addr dummy_link_local = {
181+
.s6_addr = {
182+
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183+
0x12, 0x34, 0x56, 0xff, 0xfe, 0x78, 0x9a, 0xbc,
184+
},
185+
};
186+
179187
int icmp6_receive(
180188
int fd,
181189
void *iov_base,
@@ -188,6 +196,9 @@ int icmp6_receive(
188196
if (ret_timestamp)
189197
triple_timestamp_get(ret_timestamp);
190198

199+
if (ret_sender)
200+
*ret_sender = dummy_link_local;
201+
191202
return 0;
192203
}
193204

0 commit comments

Comments
 (0)