chiark / gitweb /
sd-dhcp-client: recevie_message - verify cmsg_len before reading
[elogind.git] / src / libsystemd-network / sd-dhcp-client.c
index 5824e6e..392e294 100644 (file)
@@ -593,7 +593,7 @@ static int client_start(sd_dhcp_client *client) {
 
         client->xid = random_u32();
 
-        r = dhcp_network_bind_raw_socket(client->index, &client->link);
+        r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid);
 
         if (r < 0) {
                 client_stop(client, r);
@@ -636,7 +636,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
         client->state = DHCP_STATE_REBINDING;
         client->attempt = 1;
 
-        r = dhcp_network_bind_raw_socket(client->index, &client->link);
+        r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid);
         if (r < 0) {
                 client_stop(client, r);
                 return 0;
@@ -931,12 +931,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
         assert(client->event);
         assert(message);
 
-        if (len < DHCP_MESSAGE_SIZE) {
-                log_dhcp_client(client, "message too small (%d bytes): "
-                                "ignoring", len);
-                return 0;
-        }
-
         if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
                 log_dhcp_client(client, "not a DHCP message: ignoring");
                 return 0;
@@ -1081,7 +1075,11 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
                 return -ENOMEM;
 
         len = read(fd, message, buflen);
-        if (len < 0)
+        if (len < 0) {
+                log_dhcp_client(client, "could not receive message from UDP "
+                                "socket: %s", strerror(errno));
+                return 0;
+        } else if ((size_t)len < sizeof(DHCPMessage))
                 return 0;
 
         return client_handle_message(client, message, len);
@@ -1122,11 +1120,14 @@ static int client_receive_message_raw(sd_event_source *s, int fd,
                 log_dhcp_client(client, "could not receive message from raw "
                                 "socket: %s", strerror(errno));
                 return 0;
-        }
+        } else if ((size_t)len < sizeof(DHCPPacket))
+                return 0;
 
         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-                if (cmsg->cmsg_level == SOL_PACKET && cmsg->cmsg_type == PACKET_AUXDATA) {
-                        struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);
+                if (cmsg->cmsg_level == SOL_PACKET &&
+                    cmsg->cmsg_type == PACKET_AUXDATA &&
+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
+                        struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
 
                         checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
                         break;