Bug Summary

File:programs/pluto/iface_udp.c
Warning:line 504, column 3
Value stored to 'sizeof_buffer' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name iface_udp.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/build/quick-libreswan-2/programs/pluto -resource-dir /usr/lib64/clang/13.0.0 -D TimeZoneOffset=timezone -D PIE -D NSS_IPSEC_PROFILE -D XFRM_LIFETIME_DEFAULT=30 -D USE_IKEv1 -D XFRM_SUPPORT -D USE_XFRM_INTERFACE -D USE_DNSSEC -D DEFAULT_DNSSEC_ROOTKEY_FILE="/var/lib/unbound/root.key" -D HAVE_LABELED_IPSEC -D HAVE_SECCOMP -D LIBCURL -D USE_LINUX_AUDIT -D HAVE_NM -D USE_PAM_AUTH -D USE_3DES -D USE_AES -D USE_CAMELLIA -D USE_CHACHA -D USE_DH31 -D USE_MD5 -D USE_SHA1 -D USE_SHA2 -D USE_PRF_AES_XCBC -D USE_NSS_KDF -D DEFAULT_RUNDIR="/run/pluto" -D IPSEC_CONF="/etc/ipsec.conf" -D IPSEC_CONFDDIR="/etc/ipsec.d" -D IPSEC_NSSDIR="/var/lib/ipsec/nss" -D IPSEC_CONFDIR="/etc" -D IPSEC_EXECDIR="/usr/local/libexec/ipsec" -D IPSEC_SBINDIR="/usr/local/sbin" -D IPSEC_VARDIR="/var" -D POLICYGROUPSDIR="/etc/ipsec.d/policies" -D IPSEC_SECRETS_FILE="/etc/ipsec.secrets" -D FORCE_PR_ASSERT -D USE_FORK=1 -D USE_VFORK=0 -D USE_DAEMON=0 -D USE_PTHREAD_SETSCHEDPRIO=1 -D GCC_LINT -D HAVE_LIBCAP_NG -I . -I ../../OBJ.linux.x86_64/programs/pluto -I ../../include -I /usr/include/nss3 -I /usr/include/nspr4 -I /home/build/quick-libreswan-2/programs/pluto/linux-copy -D HERE_FILENAME="programs/pluto/iface_udp.c" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu99 -fdebug-compilation-dir=/home/build/quick-libreswan-2/programs/pluto -ferror-limit 19 -stack-protector 3 -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-01-205714-1273399-1 -x c /home/build/quick-libreswan-2/programs/pluto/iface_udp.c
1/* udp packet processing, for libreswan
2 *
3 * Copyright (C) 1997 Angelos D. Keromytis.
4 * Copyright (C) 1998-2002, 2013,2016 D. Hugh Redelmeier <hugh@mimosa.com>
5 * Copyright (C) 2003-2008 Michael C Richardson <mcr@xelerance.com>
6 * Copyright (C) 2003-2010 Paul Wouters <paul@xelerance.com>
7 * Copyright (C) 2008-2009 David McCullough <david_mccullough@securecomputing.com>
8 * Copyright (C) 2009 Avesh Agarwal <avagarwa@redhat.com>
9 * Copyright (C) 2010 Tuomo Soini <tis@foobar.fi>
10 * Copyright (C) 2012-2017 Paul Wouters <pwouters@redhat.com>
11 * Copyright (C) 2013 Wolfgang Nothdurft <wolfgang@linogate.de>
12 * Copyright (C) 2016-2019 Andrew Cagney <cagney@gnu.org>
13 * Copyright (C) 2017 D. Hugh Redelmeier <hugh@mimosa.com>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * for more details.
24 */
25
26#include <sys/types.h>
27#include <sys/socket.h> /* MSG_ERRQUEUE if defined */
28#include <netinet/udp.h>
29#include <errno(*__errno_location ()).h>
30#include <fcntl.h>
31#include <unistd.h>
32
33#ifdef MSG_ERRQUEUEMSG_ERRQUEUE
34# include <netinet/in.h> /* for IP_RECVERR */
35# include <linux1/errqueue.h>
36# include <poll.h>
37#endif
38
39#include "ip_address.h"
40
41#include "defs.h"
42#include "kernel.h"
43#include "server.h" /* for pluto_sock_bufsize */
44#include "iface.h"
45#include "demux.h"
46#include "state_db.h" /* for state_by_ike_spis() */
47#include "log.h"
48#include "ip_info.h"
49#include "ip_sockaddr.h"
50#include "nat_traversal.h" /* for nat_traversal_enabled which seems like a broken idea */
51
52static int bind_udp_socket(const struct iface_dev *ifd, ip_port port,
53 struct logger *logger)
54{
55 const struct ip_info *type = address_type(&ifd->id_address);
56 int fd = socket(type->af, SOCK_DGRAMSOCK_DGRAM, IPPROTO_UDPIPPROTO_UDP);
57 if (fd < 0) {
58 log_errno(logger, errno, "socket() in %s()", __func__){ int e_ = (*__errno_location ()); log_error(logger, e_, "socket() in %s()"
, __func__); }
;
59 return -1;
60 }
61
62 int fcntl_flags;
63 static const int on = true1; /* by-reference parameter; constant, we hope */
64
65 /* Set socket Nonblocking */
66 if ((fcntl_flags = fcntl(fd, F_GETFL3)) >= 0) {
67 if (!(fcntl_flags & O_NONBLOCK04000)) {
68 fcntl_flags |= O_NONBLOCK04000;
69 if (fcntl(fd, F_SETFL4, fcntl_flags) == -1) {
70 log_errno(logger, errno, "fcntl(,, O_NONBLOCK) in create_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "fcntl(,, O_NONBLOCK) in create_socket()"
); }
;
71 }
72 }
73 }
74
75 if (fcntl(fd, F_SETFD2, FD_CLOEXEC1) == -1) {
76 log_errno(logger, errno, "fcntl(,, FD_CLOEXEC) in create_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "fcntl(,, FD_CLOEXEC) in create_socket()"
); }
;
77 close(fd);
78 return -1;
79 }
80
81 if (setsockopt(fd, SOL_SOCKET1, SO_REUSEADDR2,
82 (const void *)&on, sizeof(on)) < 0) {
83 log_errno(logger, errno, "setsockopt SO_REUSEADDR in create_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "setsockopt SO_REUSEADDR in create_socket()"
); }
;
84 close(fd);
85 return -1;
86 }
87
88#ifdef SO_PRIORITY12
89 static const int so_prio = 6; /* rumored maximum priority, might be 7 on linux? */
90 if (setsockopt(fd, SOL_SOCKET1, SO_PRIORITY12,
91 (const void *)&so_prio, sizeof(so_prio)) < 0) {
92 log_errno(logger, errno, "setsockopt(SO_PRIORITY) in create_udp_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "setsockopt(SO_PRIORITY) in create_udp_socket()"
); }
;
93 /* non-fatal */
94 }
95#endif
96
97 if (pluto_sock_bufsize != IKE_BUF_AUTO0) {
98#if defined(linux1)
99 /*
100 * Override system maximum
101 * Requires CAP_NET_ADMIN
102 */
103 int so_rcv = SO_RCVBUFFORCE33;
104 int so_snd = SO_SNDBUFFORCE32;
105#else
106 int so_rcv = SO_RCVBUF8;
107 int so_snd = SO_SNDBUF7;
108#endif
109 if (setsockopt(fd, SOL_SOCKET1, so_rcv,
110 (const void *)&pluto_sock_bufsize, sizeof(pluto_sock_bufsize)) < 0) {
111 log_errno(logger, errno, "setsockopt(SO_RCVBUFFORCE) in create_udp_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "setsockopt(SO_RCVBUFFORCE) in create_udp_socket()"
); }
;
112 }
113 if (setsockopt(fd, SOL_SOCKET1, so_snd,
114 (const void *)&pluto_sock_bufsize, sizeof(pluto_sock_bufsize)) < 0) {
115 log_errno(logger, errno, "setsockopt(SO_SNDBUFFORCE) in create_udp_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "setsockopt(SO_SNDBUFFORCE) in create_udp_socket()"
); }
;
116 }
117 }
118
119 /* To improve error reporting. See ip(7). */
120#ifdef MSG_ERRQUEUEMSG_ERRQUEUE
121 if (pluto_sock_errqueue) {
122 if (setsockopt(fd, SOL_IP0, IP_RECVERR11, (const void *)&on, sizeof(on)) < 0) {
123 log_errno(logger, errno, "setsockopt IP_RECVERR in create_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "setsockopt IP_RECVERR in create_socket()"
); }
;
124 close(fd);
125 return -1;
126 }
127 dbg("MSG_ERRQUEUE enabled on fd %d", fd){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE enabled on fd %d", fd); } }
;
128 }
129#endif
130
131 /* With IPv6, there is no fragmentation after
132 * it leaves our interface. PMTU discovery
133 * is mandatory but doesn't work well with IKE (why?).
134 * So we must set the IPV6_USE_MIN_MTU option.
135 * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
136 */
137#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
138 if (type == &ipv6_info &&
139 setsockopt(fd, SOL_SOCKET1, IPV6_USE_MIN_MTU,
140 (const void *)&on, sizeof(on)) < 0) {
141 log_errno(logger, errno, "setsockopt IPV6_USE_MIN_MTU in create_udp_socket()"){ int e_ = (*__errno_location ()); log_error(logger, e_, "setsockopt IPV6_USE_MIN_MTU in create_udp_socket()"
); }
;
142 close(fd);
143 return -1;
144 }
145#endif
146
147 /*
148 * NETKEY requires us to poke an IPsec policy hole that allows
149 * IKE packets. This installs one IPsec policy per socket
150 * but this function is called for each: IPv4 port 500 and
151 * 4500 IPv6 port 500
152 */
153 if (kernel_ops->poke_ipsec_policy_hole != NULL((void*)0) &&
154 !kernel_ops->poke_ipsec_policy_hole(ifd, fd, logger)) {
155 close(fd);
156 return -1;
157 }
158
159 /*
160 * ??? does anyone care about the value of port of ifp->addr?
161 * Old code seemed to assume that it should be reset to pluto_port.
162 * But only on successful bind. Seems wrong or unnecessary.
163 */
164 ip_endpoint if_endpoint = endpoint_from_address_protocol_port(ifd->id_address,
165 &ip_protocol_udpip_protocols[IPPROTO_UDP],
166 port);
167 ip_sockaddr if_sa = sockaddr_from_endpoint(if_endpoint);
168 if (bind(fd, &if_sa.sa.sa, if_sa.len) < 0) {
169 endpoint_buf b;
170 log_errno(logger, errno, "bind() for %s %s in process_raw_ifaces()",{ int e_ = (*__errno_location ()); log_error(logger, e_, "bind() for %s %s in process_raw_ifaces()"
, ifd->id_rname, str_endpoint(&if_endpoint, &b)); }
171 ifd->id_rname, str_endpoint(&if_endpoint, &b)){ int e_ = (*__errno_location ()); log_error(logger, e_, "bind() for %s %s in process_raw_ifaces()"
, ifd->id_rname, str_endpoint(&if_endpoint, &b)); }
;
172 close(fd);
173 return -1;
174 }
175
176 /* poke a hole for IKE messages in the IPsec layer */
177 if (kernel_ops->exceptsocket != NULL((void*)0)) {
178 if (!kernel_ops->exceptsocket(fd, AF_INET2, logger)) {
179 close(fd);
180 return -1;
181 }
182 }
183
184 return fd;
185}
186
187static bool_Bool nat_traversal_espinudp(int sk, struct iface_dev *ifd,
188 struct logger *logger)
189{
190 const char *fam = address_type(&ifd->id_address)->ip_name;
191 dbg("NAT-Traversal: Trying sockopt style NAT-T"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-Traversal: Trying sockopt style NAT-T"); }
}
;
192
193 /*
194 * The SOL (aka socket level) is really the the protocol
195 * number which, for UDP, is always 17. Linux provides a
196 * SOL_* macro, the others don't.
197 */
198#if defined(SOL_UDP17)
199 const int sol_udp = SOL_UDP17;
200#elif defined(IPPROTO_UDPIPPROTO_UDP)
201 const int sol_udp = IPPROTO_UDPIPPROTO_UDP;
202#endif
203
204 /*
205 * Was UDP_ESPINUDP (aka 100). Linux/NetBSD have the value
206 * 100, FreeBSD has the value 1.
207 */
208 const int sol_name = UDP_ENCAP100;
209
210 /*
211 * Was ESPINUDP_WITH_NON_ESP (aka 2) defined in "libreswan.h"
212 * which smells like something intended for the old KLIPS
213 * module. <netinet/udp.h> defines the below across linux and
214 * *BSD.
215 */
216 const int sol_value = UDP_ENCAP_ESPINUDP2;
217
218 int r = setsockopt(sk, sol_udp, sol_name, &sol_value, sizeof(sol_value));
219 if (r == -1) {
220 dbg("NAT-Traversal: ESPINUDP(%d) setup failed for sockopt style NAT-T family %s (errno=%d)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-Traversal: ESPINUDP(%d) setup failed for sockopt style NAT-T family %s (errno=%d)"
, sol_value, fam, (*__errno_location ())); } }
221 sol_value, fam, errno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-Traversal: ESPINUDP(%d) setup failed for sockopt style NAT-T family %s (errno=%d)"
, sol_value, fam, (*__errno_location ())); } }
;
222 /* all methods failed to detect NAT-T support */
223 llog(RC_LOG_SERIOUS, logger,
224 "NAT-Traversal: ESPINUDP for this kernel not supported or not found for family %s; NAT-traversal is turned OFF", fam);
225 nat_traversal_enabled = false0;
226 return false0;
227 }
228
229 dbg("NAT-Traversal: ESPINUDP(%d) setup succeeded for sockopt style NAT-T family %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-Traversal: ESPINUDP(%d) setup succeeded for sockopt style NAT-T family %s"
, sol_value, fam); } }
230 sol_value, fam){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-Traversal: ESPINUDP(%d) setup succeeded for sockopt style NAT-T family %s"
, sol_value, fam); } }
;
231 return true1;
232}
233
234#ifdef MSG_ERRQUEUEMSG_ERRQUEUE
235static bool_Bool check_msg_errqueue(const struct iface_endpoint *ifp,
236 short interest, const char *func,
237 struct logger *logger);
238#endif
239
240static enum iface_read_status udp_read_packet(struct iface_endpoint *ifp,
241 struct iface_packet *packet,
242 struct logger *logger)
243{
244#ifdef MSG_ERRQUEUEMSG_ERRQUEUE
245 /*
246 * Even though select(2) says that there is a message, it
247 * might only be a MSG_ERRQUEUE message. At least sometimes
248 * that leads to a hanging recvfrom. To avoid what appears to
249 * be a kernel bug, check_msg_errqueue uses poll(2) and tells
250 * us if there is anything for us to read.
251 *
252 * This is early enough that teardown isn't required:
253 * just return on failure.
254 */
255 if (pluto_sock_errqueue) {
256 threadtime_t errqueue_start = threadtime_start();
257 bool_Bool errqueue_ok = check_msg_errqueue(ifp, POLLIN0x001, __func__,
258 packet->logger);
259 threadtime_stop(&errqueue_start, SOS_NOBODY0,
260 "%s() calling check_incoming_msg_errqueue()", __func__);
261 if (!errqueue_ok) {
262 return IFACE_READ_IGNORE; /* no normal message to read */
263 }
264 }
265#endif
266
267 /*
268 * COVERITY reports an overflow because FROM.LEN (aka
269 * sizeof(FROM.SA)) > sizeof(from.sa.sa). That's the point.
270 * The FROM.SA union is big enough to hold sockaddr,
271 * sockaddr_in and sockaddr_in6.
272 */
273 ip_sockaddr from = {
274 .len = sizeof(from.sa),
275 };
276 packet->len = recvfrom(ifp->fd, packet->ptr, packet->len, /*flags*/ 0,
277 &from.sa.sa, &from.len);
278 int packet_errno = errno(*__errno_location ()); /* save!!! */
279
280 /*
281 * Try to decode the from address.
282 *
283 * If that fails report some sense of error and then always
284 * give up.
285 */
286 ip_address sender_udp_address;
287 ip_port sender_udp_port;
288 const char *from_ugh = sockaddr_to_address_port(from, &sender_udp_address, &sender_udp_port);
289 if (from_ugh != NULL((void*)0)) {
290 if (packet->len >= 0) {
291 /* technically it worked, but returned value was useless */
292 llog(RC_LOG, packet->logger,
293 "recvfrom on %s returned malformed source sockaddr: %s",
294 ifp->ip_dev->id_rname, from_ugh);
295 } else if (from.len == sizeof(from) &&
296 all_zero((const void *)&from, sizeof(from)) &&
297 packet_errno == ECONNREFUSED111) {
298 /*
299 * Tone down scary message for vague event: We
300 * get "connection refused" in response to
301 * some datagram we sent, but we cannot tell
302 * which one.
303 */
304 llog(RC_LOG, packet->logger,
305 "recvfrom on %s failed; some IKE message we sent has been rejected with ECONNREFUSED (kernel supplied no details)",
306 ifp->ip_dev->id_rname);
307 } else {
308 /* if from==0, this prints "unspecified", not "undisclosed", oops */
309 llog_errno(RC_LOG, packet->logger, packet_errno,
310 "recvfrom on %s failed; cannot decode source sockaddr in rejection: %s"/*: */,
311 ifp->ip_dev->id_rname, from_ugh);
312 }
313 return IFACE_READ_IGNORE;
314 }
315
316 packet->sender = endpoint_from_address_protocol_port(sender_udp_address,
317 &ip_protocol_udpip_protocols[IPPROTO_UDP],
318 sender_udp_port);
319
320
321 /*
322 * Managed to decode the from address; switch to a "from"
323 * logger so that it be used as log context prefix.
324 */
325 struct logger from_logger = logger_from(logger, &packet->sender);
326 logger = &from_logger;
327
328 if (packet->len < 0) {
329 llog_errno(RC_LOG, logger, packet_errno,
330 "recvfrom on %s failed"/*: */, ifp->ip_dev->id_rname);
331 return IFACE_READ_IGNORE;
332 }
333
334 if (ifp->esp_encapsulation_enabled) {
335 uint32_t non_esp;
336
337 if (packet->len < (int)sizeof(uint32_t)) {
338 llog(RC_LOG, logger, "too small packet (%zd)",
339 packet->len);
340 return IFACE_READ_IGNORE;
341 }
342 memcpy(&non_esp, packet->ptr, sizeof(uint32_t));
343 if (non_esp != 0) {
344 llog(RC_LOG, logger, "has no Non-ESP marker");
345 return IFACE_READ_IGNORE;
346 }
347 packet->ptr += sizeof(uint32_t);
348 packet->len -= sizeof(uint32_t);
349 }
350
351 /* We think that in 2013 Feb, Apple iOS Racoon
352 * sometimes generates an extra useless buggy confusing
353 * Non ESP Marker
354 */
355 {
356 static const uint8_t non_ESP_marker[NON_ESP_MARKER_SIZE4] =
357 { 0x00, };
358 if (ifp->esp_encapsulation_enabled &&
359 packet->len >= NON_ESP_MARKER_SIZE4 &&
360 memeq(packet->ptr, non_ESP_marker,(memcmp((packet->ptr), (non_ESP_marker), (4)) == 0)
361 NON_ESP_MARKER_SIZE)(memcmp((packet->ptr), (non_ESP_marker), (4)) == 0)) {
362 llog(RC_LOG, logger,
363 "mangled with potential spurious non-esp marker");
364 return IFACE_READ_IGNORE;
365 }
366 }
367
368 if (packet->len == 1 && packet->ptr[0] == 0xff) {
369 /**
370 * NAT-T Keep-alive packets should be discarded by kernel ESPinUDP
371 * layer. But bogus keep-alive packets (sent with a non-esp marker)
372 * can reach this point. Complain and discard them.
373 * Possibly too if the NAT mapping vanished on the initiator NAT gw ?
374 */
375 endpoint_buf eb;
376 dbg("NAT-T keep-alive (bogus ?) should not reach this point. Ignored. Sender: %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T keep-alive (bogus ?) should not reach this point. Ignored. Sender: %s"
, str_endpoint(&packet->sender, &eb)); } }
377 str_endpoint(&packet->sender, &eb)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T keep-alive (bogus ?) should not reach this point. Ignored. Sender: %s"
, str_endpoint(&packet->sender, &eb)); } }
; /* sensitive? */
378 return IFACE_READ_IGNORE;
379 }
380
381 return IFACE_READ_OK;
382}
383
384static ssize_t udp_write_packet(const struct iface_endpoint *ifp,
385 const void *ptr, size_t len,
386 const ip_endpoint *remote_endpoint,
387 struct logger *logger /*possibly*/UNUSED__attribute__ ((unused)))
388{
389#ifdef MSG_ERRQUEUEMSG_ERRQUEUE
390 if (pluto_sock_errqueue) {
391 check_msg_errqueue(ifp, POLLOUT0x004, __func__, logger);
392 }
393#endif
394
395 ip_sockaddr remote_sa = sockaddr_from_endpoint(*remote_endpoint);
396 return sendto(ifp->fd, ptr, len, 0, &remote_sa.sa.sa, remote_sa.len);
397};
398
399static void udp_listen(struct iface_endpoint *ifp,
400 struct logger *unused_logger UNUSED__attribute__ ((unused)))
401{
402 if (ifp->udp_message_listener == NULL((void*)0)) {
403 attach_fd_read_sensor(&ifp->udp_message_listener, ifp->fd,
404 process_iface_packet, ifp);
405 }
406}
407
408static int udp_bind_iface_endpoint(struct iface_dev *ifd, ip_port port,
409 bool_Bool esp_encapsulation_enabled,
410 struct logger *logger)
411{
412 int fd = bind_udp_socket(ifd, port, logger);
413 if (fd < 0) {
414 return -1;
415 }
416 if (esp_encapsulation_enabled &&
417 !nat_traversal_espinudp(fd, ifd, logger)) {
418 dbg("nat-traversal failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("nat-traversal failed"); } }
;
419 }
420 return fd;
421}
422
423static void udp_cleanup(struct iface_endpoint *ifp)
424{
425 event_free(ifp->udp_message_listener);
426 ifp->udp_message_listener = NULL((void*)0);
427}
428
429const struct iface_io udp_iface_io = {
430 .send_keepalive = true1,
431 .protocol = &ip_protocol_udpip_protocols[IPPROTO_UDP],
432 .read_packet = udp_read_packet,
433 .write_packet = udp_write_packet,
434 .listen = udp_listen,
435 .bind_iface_endpoint = udp_bind_iface_endpoint,
436 .cleanup = udp_cleanup,
437};
438
439#ifdef MSG_ERRQUEUEMSG_ERRQUEUE
440
441/* Process any message on the MSG_ERRQUEUE
442 *
443 * This information is generated because of the IP_RECVERR socket option.
444 * The API is sparsely documented, and may be LINUX-only, and only on
445 * fairly recent versions at that (hence the conditional compilation).
446 *
447 * - ip(7) describes IP_RECVERR
448 * - recvmsg(2) describes MSG_ERRQUEUE
449 * - readv(2) describes iovec
450 * - cmsg(3) describes how to process auxiliary messages
451 *
452 * ??? we should link this message with one we've sent
453 * so that the diagnostic can refer to that negotiation.
454 *
455 * ??? how long can the message be?
456 *
457 * ??? poll(2) has a very incomplete description of the POLL* events.
458 * We assume that POLLIN, POLLOUT, and POLLERR are all we need to deal with
459 * and that POLLERR will be on iff there is a MSG_ERRQUEUE message.
460 *
461 * We have to code around a couple of surprises:
462 *
463 * - Select can say that a socket is ready to read from, and
464 * yet a read will hang. It turns out that a message available on the
465 * MSG_ERRQUEUE will cause select to say something is pending, but
466 * a normal read will hang. poll(2) can tell when a MSG_ERRQUEUE
467 * message is pending.
468 *
469 * This is dealt with by calling check_msg_errqueue after select has
470 * indicated that there is something to read, but before the read is
471 * performed. check_msg_errqueue will return "true" if there is
472 * something left to read.
473 *
474 * - A write to a socket may fail because there is a pending MSG_ERRQUEUE
475 * message, without there being anything wrong with the write. This
476 * makes for confusing diagnostics.
477 *
478 * To avoid this, we call check_msg_errqueue before a write. True,
479 * there is a race condition (a MSG_ERRQUEUE message might arrive
480 * between the check and the write), but we should eliminate many
481 * of the problematic events. To narrow the window, the poll(2)
482 * will await until an event happens (in the case or a write,
483 * POLLOUT; this should be benign for POLLIN).
484 */
485
486static struct state *find_likely_sender(size_t packet_len, uint8_t *buffer,
487 size_t sizeof_buffer)
488{
489 if (packet_len > sizeof_buffer) {
490 /*
491 * When the message is too big it is truncated. But
492 * what about the returned packet length? Force
493 * truncation.
494 */
495 dbg("MSG_ERRQUEUE packet longer than %zu bytes; truncated", sizeof_buffer){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet longer than %zu bytes; truncated"
, sizeof_buffer); } }
;
496 packet_len = sizeof_buffer;
497 }
498
499 static const uint8_t non_ESP_marker[NON_ESP_MARKER_SIZE4] = { 0x00, };
500 if (packet_len >= sizeof(non_ESP_marker) &&
501 memeq(buffer, non_ESP_marker, sizeof(non_ESP_marker))(memcmp((buffer), (non_ESP_marker), (sizeof(non_ESP_marker)))
== 0)
) {
502 buffer += sizeof(non_ESP_marker);
503 packet_len -= sizeof(non_ESP_marker);
504 sizeof_buffer -= sizeof(non_ESP_marker);
Value stored to 'sizeof_buffer' is never read
505 dbg("MSG_ERRQUEUE packet has leading ESP:0 marker - discarded"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet has leading ESP:0 marker - discarded"
); } }
;
506 }
507
508 if (packet_len < sizeof(struct isakmp_hdr)) {
509 dbg("MSG_ERRQUEUE packet is smaller than an IKE header"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet is smaller than an IKE header"
); } }
;
510 return NULL((void*)0);
511 }
512
513 struct pbs_inpacket_byte_stream packet_pbs;
514 init_pbs(&packet_pbs, buffer, packet_len, __func__);
515 struct isakmp_hdr hdr;
516 diag_t d = pbs_in_struct(&packet_pbs, &raw_isakmp_hdr_desc,
517 &hdr, sizeof(hdr), NULL((void*)0));
518 if (d != NULL((void*)0)) {
519 /*
520 * XXX: Only thing interesting is that there was an
521 * error, toss the message.
522 */
523 pfree_diag(&d);
524 return NULL((void*)0);
525 }
526
527 enum ike_version ike_version = hdr_ike_version(&hdr);
528 struct state *st;
529 switch (ike_version) {
530 case IKEv1:
531 /* might work? */
532 st = state_by_ike_spis(ike_version,
533 NULL((void*)0)/*ignore-clonedfrom*/,
534 NULL((void*)0)/*ignore-v1_msgid*/,
535 NULL((void*)0)/*ignore-role*/,
536 &hdr.isa_ike_spis,
537 NULL((void*)0), NULL((void*)0),
538 __func__);
539 break;
540 case IKEv2:
541 {
542 /*
543 * Since this end sent the message mapping IKE_I is
544 * straight forward.
545 */
546 enum sa_role ike_role = (hdr.isa_flags & ISAKMP_FLAGS_v2_IKE_I(1<<ISAKMP_FLAGS_v2_IKE_I_IX)) ? SA_INITIATOR : SA_RESPONDER;
547 so_serial_t clonedfrom = SOS_NOBODY0;
548 st = state_by_ike_spis(ike_version,
549 &clonedfrom/*IKE*/,
550 NULL((void*)0)/*ignore-v1_msgid*/,
551 &ike_role,
552 &hdr.isa_ike_spis,
553 NULL((void*)0), NULL((void*)0),
554 __func__);
555 break;
556 }
557 default:
558 dbg("MSG_ERRQUEUE packet IKE header version unknown"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet IKE header version unknown"
); } }
;
559 return NULL((void*)0);
560 }
561 if (st == NULL((void*)0)) {
562 dbg("MSG_ERRQUEUE packet has no matching %s SA",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet has no matching %s SA", enum_name
(&ike_version_names, ike_version)); } }
563 enum_name(&ike_version_names, ike_version)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet has no matching %s SA", enum_name
(&ike_version_names, ike_version)); } }
;
564 return NULL((void*)0);
565 }
566
567 dbg("MSG_ERRQUEUE packet matches %s SA #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet matches %s SA #%lu", enum_name
(&ike_version_names, ike_version), st->st_serialno); }
}
568 enum_name(&ike_version_names, ike_version),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet matches %s SA #%lu", enum_name
(&ike_version_names, ike_version), st->st_serialno); }
}
569 st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("MSG_ERRQUEUE packet matches %s SA #%lu", enum_name
(&ike_version_names, ike_version), st->st_serialno); }
}
;
570 return st;
571}
572
573static bool_Bool check_msg_errqueue(const struct iface_endpoint *ifp, short interest,
574 const char *before,
575 struct logger *logger)
576{
577 struct pollfd pfd;
578 int again_count = 0;
579
580 pfd.fd = ifp->fd;
581 pfd.events = interest | POLLPRI0x002 | POLLOUT0x004;
582
583 while (/*clear .revents*/ pfd.revents = 0,
584 /*poll .revents*/ poll(&pfd, 1, -1) > 0 &&
585 /*test .revents*/ (pfd.revents & POLLERR0x008)) {
586
587 /*
588 * A single IOV (I/O Vector) pointing at a buffer for
589 * storing the message fragment.
590 *
591 * It needs to be large enough to fit the IKE header +
592 * leading ESP:0 prefix so that the IKE SPIs and flags
593 * can be extracted and used to find the sender of the
594 * message.
595 *
596 * Give it double that.
597 */
598 uint8_t buffer[sizeof(struct isakmp_hdr) * 2];
599 struct iovec eiov[1] = {
600 {
601 .iov_base = buffer, /* see readv(2) */
602 .iov_len = sizeof(buffer),
603 },
604 };
605
606 union {
607 /* force alignment (not documented as necessary) */
608 struct cmsghdr ecms;
609
610 /* how much space is enough? */
611 unsigned char space[256];
612 } ecms_buf;
613
614 ip_sockaddr from = { 0, };
615 struct msghdr emh = {
616 .msg_name = &from.sa, /* ??? filled in? */
617 .msg_namelen = sizeof(from.sa),
618 .msg_iov = eiov,
619 .msg_iovlen = elemsof(eiov)(sizeof(eiov) / sizeof(*(eiov))),
620 .msg_control = &ecms_buf,
621 .msg_controllen = sizeof(ecms_buf),
622 .msg_flags = 0,
623 };
624
625 ssize_t packet_len = recvmsg(ifp->fd, &emh, MSG_ERRQUEUEMSG_ERRQUEUE);
626
627 if (packet_len == -1) {
628 /* XXX: all paths either break. return, or continue */
629 if (errno(*__errno_location ()) == EAGAIN11) {
630 /* 32 is picked from thin air */
631 if (again_count == 32) {
632 llog(RC_LOG_SERIOUS, logger,
633 "recvmsg(,, MSG_ERRQUEUE): given up reading socket after 32 EAGAIN errors");
634 return false0;
635 }
636 again_count++;
637 log_errno(logger, errno,{ int e_ = (*__errno_location ()); log_error(logger, e_, "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s) (attempt %d)"
, ifp->ip_dev->id_rname, before, again_count); }
638 "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s) (attempt %d)",{ int e_ = (*__errno_location ()); log_error(logger, e_, "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s) (attempt %d)"
, ifp->ip_dev->id_rname, before, again_count); }
639 ifp->ip_dev->id_rname, before, again_count){ int e_ = (*__errno_location ()); log_error(logger, e_, "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s) (attempt %d)"
, ifp->ip_dev->id_rname, before, again_count); }
;
640 continue;
641 }
642 log_errno(logger, errno,{ int e_ = (*__errno_location ()); log_error(logger, e_, "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s)"
, ifp->ip_dev->id_rname, before); }
643 "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s)",{ int e_ = (*__errno_location ()); log_error(logger, e_, "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s)"
, ifp->ip_dev->id_rname, before); }
644 ifp->ip_dev->id_rname, before){ int e_ = (*__errno_location ()); log_error(logger, e_, "recvmsg(,, MSG_ERRQUEUE) on %s failed (noticed before %s)"
, ifp->ip_dev->id_rname, before); }
;
645 break;
646 }
647 passert(packet_len >= 0)({ _Bool assertion__ = packet_len >= 0; if (!assertion__) {
where_t here = ({ static const struct where here = { .func =
__func__, .file = "programs/pluto/iface_udp.c", .line = 647,
}; &here; }); const struct logger *logger_ = &failsafe_logger
; llog_passert(logger_, here, "%s", "packet_len >= 0"); } (
void) 1; })
;
648
649 /*
650 * Getting back a truncated IKE datagram isn't a big
651 * deal - find_likely_sender() only needs the header
652 * when figuring out which state sent the packet.
653 */
654 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX)))) && (emh.msg_flags & MSG_TRUNCMSG_TRUNC)) {
655 DBG_log("recvmsg(,, MSG_ERRQUEUE) on %s returned a truncated (IKE) datagram (MSG_TRUNC)",
656 ifp->ip_dev->id_rname);
657 }
658
659 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
660 if (packet_len > 0) {
661 DBG_log("rejected packet:");
662 DBG_dump(NULL((void*)0), buffer, packet_len);
663 }
664 DBG_log("control:");
665 DBG_dump(NULL((void*)0), emh.msg_control,
666 emh.msg_controllen);
667 }
668
669 struct state *sender = find_likely_sender((size_t) packet_len,
670 buffer, sizeof(buffer));
671
672 /* ??? Andi Kleen <ak@suse.de> and misc documentation
673 * suggests that name will have the original destination
674 * of the packet. We seem to see msg_namelen == 0.
675 * Andi says that this is a kernel bug and has fixed it.
676 * Perhaps in 2.2.18/2.4.0.
677 */
678 passert(emh.msg_name == &from.sa)({ _Bool assertion__ = emh.msg_name == &from.sa; if (!assertion__
) { where_t here = ({ static const struct where here = { .func
= __func__, .file = "programs/pluto/iface_udp.c", .line = 678
, }; &here; }); const struct logger *logger_ = &failsafe_logger
; llog_passert(logger_, here, "%s", "emh.msg_name == &from.sa"
); } (void) 1; })
;
679 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
680 DBG_log("name:");
681 DBG_dump(NULL((void*)0), emh.msg_name, emh.msg_namelen);
682 }
683
684 const struct ip_info *afi = aftoinfo(from.sa.sa.sa_family);
685 /* usual case :-( */
686 char fromstr[sizeof(" for message to ?") + sizeof(endpoint_buf)] = "";
687 if (afi != NULL((void*)0) && emh.msg_namelen == afi->sockaddr_size) {
688 ip_address sender_udp_address;
689 ip_port sender_udp_port;
690 if (sockaddr_to_address_port(from, &sender_udp_address, &sender_udp_port) == NULL((void*)0)) {
691 /* this is a udp socket so presumably the endpoint is udp */
692 endpoint_buf ab;
693 ip_endpoint endpoint = endpoint_from_address_protocol_port(sender_udp_address,
694 &ip_protocol_udpip_protocols[IPPROTO_UDP],
695 sender_udp_port);
696 snprintf(fromstr, sizeof(fromstr),
697 " for message to %s",
698 str_endpoint_sensitive(&endpoint, &ab));
699 }
700 }
701
702 for (struct cmsghdr *cm = CMSG_FIRSTHDR(&emh)((size_t) (&emh)->msg_controllen >= sizeof (struct cmsghdr
) ? (struct cmsghdr *) (&emh)->msg_control : (struct cmsghdr
*) 0)
; cm != NULL((void*)0); cm = CMSG_NXTHDR(&emh, cm)__cmsg_nxthdr (&emh, cm)) {
703 if (cm->cmsg_level == SOL_IP0 &&
704 cm->cmsg_type == IP_RECVERR11) {
705 /* ip(7) and recvmsg(2) specify:
706 * ee_origin is SO_EE_ORIGIN_ICMP for ICMP
707 * or SO_EE_ORIGIN_LOCAL for locally generated errors.
708 * ee_type and ee_code are from the ICMP header.
709 * ee_info is the discovered MTU for EMSGSIZE errors
710 * ee_data is not used.
711 *
712 * ??? recvmsg(2) says "SOCK_EE_OFFENDER" but
713 * means "SO_EE_OFFENDER". The OFFENDER is really
714 * the router that complained. As such, the port
715 * is meaningless.
716 */
717
718 /* ??? cmsg(3) claims that CMSG_DATA returns
719 * void *, but RFC 2292 and /usr/include/bits/socket.h
720 * say unsigned char *. The manual is being fixed.
721 */
722 struct sock_extended_err *ee =
723 (void *)CMSG_DATA(cm)((cm)->__cmsg_data);
724 const char *offstr = "unspecified";
725 char offstrspace[INET6_ADDRSTRLEN46];
726 char orname[50];
727
728 if (cm->cmsg_len >
729 CMSG_LEN(sizeof(struct sock_extended_err))((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (sizeof(struct sock_extended_err)
))
)
730 {
731 const struct sockaddr *offender =
732 SO_EE_OFFENDER(ee)((struct sockaddr*)((ee)+1));
733
734 switch (offender->sa_family) {
735 case AF_INET2:
736 offstr = inet_ntop(
737 offender->sa_family,
738 &((const
739 struct sockaddr_in *)
740 offender)->sin_addr,
741 offstrspace,
742 sizeof(offstrspace));
743 break;
744 case AF_INET610:
745 offstr = inet_ntop(
746 offender->sa_family,
747 &((const
748 struct sockaddr_in6
749 *)offender)->sin6_addr,
750 offstrspace,
751 sizeof(offstrspace));
752 break;
753 default:
754 offstr = "unknown";
755 break;
756 }
757 }
758
759 switch (ee->ee_origin) {
760 case SO_EE_ORIGIN_NONE0:
761 snprintf(orname, sizeof(orname),
762 "none");
763 break;
764 case SO_EE_ORIGIN_LOCAL1:
765 snprintf(orname, sizeof(orname),
766 "local");
767 break;
768 case SO_EE_ORIGIN_ICMP2:
769 snprintf(orname, sizeof(orname),
770 "ICMP type %d code %d (not authenticated)",
771 ee->ee_type, ee->ee_code);
772 break;
773 case SO_EE_ORIGIN_ICMP63:
774 snprintf(orname, sizeof(orname),
775 "ICMP6 type %d code %d (not authenticated)",
776 ee->ee_type, ee->ee_code);
777 break;
778 default:
779 snprintf(orname, sizeof(orname),
780 "invalid origin %u",
781 ee->ee_origin);
782 break;
783 }
784
785 enum stream log_to;
786 if (packet_len == 1 && buffer[0] == 0xff &&
787 (cur_debugging & DBG_BASE((lset_t)1 << (DBG_BASE_IX))) == 0) {
788 /*
789 * don't log NAT-T keepalive related errors unless NATT debug is
790 * enabled
791 */
792 log_to = NO_STREAM;
793 } else if (sender != NULL((void*)0) && sender->st_connection != NULL((void*)0) &&
794 LDISJOINT(sender->st_connection->policy, POLICY_OPPORTUNISTIC)(((sender->st_connection->policy) & (((lset_t)1 <<
(POLICY_OPPORTUNISTIC_IX)))) == ((lset_t)0))
) {
795 /*
796 * The sender is known and
797 * this isn't an opportunistic
798 * connection, so log.
799 *
800 * XXX: originally this path
801 * was taken unconditionally
802 * but with opportunistic that
803 * got too verbose. Is there
804 * a global opportunistic
805 * disabled test so that
806 * behaviour can be restored?
807 *
808 * HACK: So that the logging
809 * system doesn't accidentally
810 * include a prefix for the
811 * wrong state et.al., switch
812 * out everything but SENDER.
813 * Better would be to make the
814 * state/connection an
815 * explicit parameter to the
816 * logging system?
817 */
818 log_to = ALL_STREAMS;
819 } else if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
820 /*
821 * Since this output is forced
822 * using DBGP, report the
823 * error using debug-log.
824 *
825 * A NULL SENDER here doesn't
826 * matter - it just gets
827 * ignored.
828 */
829 log_to = DEBUG_STREAM;
830 } else {
831 log_to = NO_STREAM;
832 }
833 if (log_to != NO_STREAM) {
834 endpoint_buf epb;
835 llog(log_to, (sender != NULL((void*)0) ? sender->st_logger : logger),
836 "ERROR: asynchronous network error report on %s (%s)%s, complainant %s: %s [errno %" PRIu32"u" ", origin %s]",
837 ifp->ip_dev->id_rname,
838 str_endpoint(&ifp->local_endpoint, &epb),
839 fromstr,
840 offstr,
841 strerror(ee->ee_errno),
842 ee->ee_errno, orname);
843 }
844 } else if (cm->cmsg_level == SOL_IP0 &&
845 cm->cmsg_type == IP_PKTINFO8) {
846 /* do nothing */
847 } else {
848 /* .cmsg_len is a kernel_size_t(!),
849 * but the value certainly ought to
850 * fit in a size_t.
851 */
852 llog(RC_LOG, logger,
853 "unknown cmsg: level %d, type %d, len %zu",
854 cm->cmsg_level, cm->cmsg_type,
855 cm->cmsg_len);
856 }
857 }
858 }
859 return (pfd.revents & interest) != 0;
860}
861
862#endif /* MSG_ERRQUEUE */