Merge ~alfonsosanchezbeato/snappy-hwe-snaps/+git/network-manager:fix-dhcp-busy-loop into ~snappy-hwe-team/snappy-hwe-snaps/+git/network-manager:network-manager/xenial/1.2.2

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Konrad Zapałowicz
Approved revision: f3a9eb6524d947a79e0fd619f3965415332e9bed
Merged at revision: 04d207d59c0764f5cffb7163e4dd3af5dd9a074b
Proposed branch: ~alfonsosanchezbeato/snappy-hwe-snaps/+git/network-manager:fix-dhcp-busy-loop
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/network-manager:network-manager/xenial/1.2.2
Diff against target: 102 lines (+26/-10)
3 files modified
src/systemd/src/libsystemd-network/sd-dhcp-client.c (+1/-1)
src/systemd/src/libsystemd-network/sd-dhcp6-client.c (+1/-1)
src/systemd/src/libsystemd-network/sd-ipv4acd.c (+24/-8)
Reviewer Review Type Date Requested Status
System Enablement Bot continuous-integration Approve
Alfonso Sanchez-Beato continuous-integration Approve
Konrad Zapałowicz (community) Approve
Review via email: mp+354462@code.launchpad.net

Description of the change

Use recv() instead of read() when reading DHCP packets

This applies systemd commit cf447cb62 to fix a busy loop when an empty
DHCP UDP package has been (LP: #1790974).

To post a comment you must log in.
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

Ack

review: Approve
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
2index 758dba4..5ca3b4d 100644
3--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
4+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
5@@ -1591,7 +1591,7 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
6 if (!message)
7 return -ENOMEM;
8
9- len = read(fd, message, buflen);
10+ len = recv(fd, message, buflen, 0);
11 if (len < 0) {
12 if (errno == EAGAIN || errno == EINTR)
13 return 0;
14diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
15index 8fa1822..d9ef249 100644
16--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
17+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
18@@ -899,7 +899,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
19 if (!message)
20 return -ENOMEM;
21
22- len = read(fd, message, buflen);
23+ len = recv(fd, message, buflen, 0);
24 if (len < 0) {
25 if (errno == EAGAIN || errno == EINTR)
26 return 0;
27diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
28index 9b5ce72..867987c 100644
29--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c
30+++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
31@@ -157,8 +157,10 @@ static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counte
32 static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) {
33 assert(ll);
34
35- if (ll->cb)
36- ll->cb(ll, event, ll->userdata);
37+ if (!ll->cb)
38+ return;
39+
40+ ll->cb(ll, event, ll->userdata);
41 }
42
43 static void ipv4acd_stop(sd_ipv4acd *ll) {
44@@ -348,22 +350,36 @@ static void ipv4acd_on_conflict(sd_ipv4acd *ll) {
45 ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT);
46 }
47
48-static int ipv4acd_on_packet(sd_event_source *s, int fd,
49- uint32_t revents, void *userdata) {
50+static int ipv4acd_on_packet(
51+ sd_event_source *s,
52+ int fd,
53+ uint32_t revents,
54+ void *userdata) {
55+
56 sd_ipv4acd *ll = userdata;
57 struct ether_arp packet;
58+ ssize_t n;
59 int r;
60
61+ assert(s);
62 assert(ll);
63 assert(fd >= 0);
64
65- r = read(fd, &packet, sizeof(struct ether_arp));
66- if (r < (int) sizeof(struct ether_arp))
67+ n = recv(fd, &packet, sizeof(struct ether_arp), 0);
68+ if (n < 0) {
69+ r = log_ipv4acd_debug_errno(ll, errno, "Failed to read ARP packet: %m");
70 goto out;
71+ }
72+ if ((size_t) n != sizeof(struct ether_arp)) {
73+ log_ipv4acd_debug(ll, "Ignoring too short ARP packet.");
74+ return 0;
75+ }
76
77 switch (ll->state) {
78+
79 case IPV4ACD_STATE_ANNOUNCING:
80 case IPV4ACD_STATE_RUNNING:
81+
82 if (ipv4acd_arp_conflict(ll, &packet)) {
83 usec_t ts;
84
85@@ -382,15 +398,15 @@ static int ipv4acd_on_packet(sd_event_source *s, int fd,
86 } else
87 ipv4acd_on_conflict(ll);
88 }
89-
90 break;
91+
92 case IPV4ACD_STATE_WAITING_PROBE:
93 case IPV4ACD_STATE_PROBING:
94 case IPV4ACD_STATE_WAITING_ANNOUNCE:
95 /* BPF ensures this packet indicates a conflict */
96 ipv4acd_on_conflict(ll);
97-
98 break;
99+
100 default:
101 assert_not_reached("Invalid state.");
102 }

Subscribers

People subscribed via source and target branches