aboutgitcodebugslistschat
path: root/icmp.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-01-16 16:16:17 +1100
committerStefano Brivio <sbrivio@redhat.com>2024-01-22 23:36:55 +0100
commitb6a4e20aa69a855ab2ce04a2eb302416730a21af (patch)
treed01962315fa924591e7cbcd24c43f3259d7add41 /icmp.c
parent6e86511f596794f987ca1114d5681e85f91eaed3 (diff)
downloadpasst-b6a4e20aa69a855ab2ce04a2eb302416730a21af.tar
passt-b6a4e20aa69a855ab2ce04a2eb302416730a21af.tar.gz
passt-b6a4e20aa69a855ab2ce04a2eb302416730a21af.tar.bz2
passt-b6a4e20aa69a855ab2ce04a2eb302416730a21af.tar.lz
passt-b6a4e20aa69a855ab2ce04a2eb302416730a21af.tar.xz
passt-b6a4e20aa69a855ab2ce04a2eb302416730a21af.tar.zst
passt-b6a4e20aa69a855ab2ce04a2eb302416730a21af.zip
icmp: Validate packets received on ping sockets
We access fields of packets received from ping sockets assuming they're echo replies, without actually checking that. Of course, we don't expect anything else from the kernel, but it's probably best to verify. While we're at it, also check for short packets, or a receive address of the wrong family. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'icmp.c')
-rw-r--r--icmp.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/icmp.c b/icmp.c
index 79f6c8c..a9dc436 100644
--- a/icmp.c
+++ b/icmp.c
@@ -86,16 +86,25 @@ void icmp_sock_handler(const struct ctx *c, int af, union epoll_ref ref)
pname, strerror(errno));
return;
}
+ if (sr.sa.sa_family != af)
+ goto unexpected;
if (af == AF_INET) {
struct icmphdr *ih4 = (struct icmphdr *)buf;
+ if ((size_t)n < sizeof(*ih4) || ih4->type != ICMP_ECHOREPLY)
+ goto unexpected;
+
/* Adjust packet back to guest-side ID */
ih4->un.echo.id = htons(ref.icmp.id);
seq = ntohs(ih4->un.echo.sequence);
} else if (af == AF_INET6) {
struct icmp6hdr *ih6 = (struct icmp6hdr *)buf;
+ if ((size_t)n < sizeof(*ih6) ||
+ ih6->icmp6_type != ICMPV6_ECHO_REPLY)
+ goto unexpected;
+
/* Adjust packet back to guest-side ID */
ih6->icmp6_identifier = htons(ref.icmp.id);
seq = ntohs(ih6->icmp6_sequence);
@@ -118,6 +127,10 @@ void icmp_sock_handler(const struct ctx *c, int af, union epoll_ref ref)
else if (af == AF_INET6)
tap_icmp6_send(c, &sr.sa6.sin6_addr,
tap_ip6_daddr(c, &sr.sa6.sin6_addr), buf, n);
+ return;
+
+unexpected:
+ warn("%s: Unexpected packet on ping socket", pname);
}
/**