aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2017-06-08 13:22:06 +0200
committerAlexey Kardashevskiy <aik@ozlabs.ru>2017-06-15 16:11:32 +1000
commit8c41240bc4e9f4e3a0b331af18d7305caae024b7 (patch)
treeb45bad54e0917096e159d255e2c2bb7615849888 /lib
parentfa94a3bb20734cb8e0280b232d16b6d466ec3d53 (diff)
downloadSLOF-8c41240bc4e9f4e3a0b331af18d7305caae024b7.zip
SLOF-8c41240bc4e9f4e3a0b331af18d7305caae024b7.tar.gz
SLOF-8c41240bc4e9f4e3a0b331af18d7305caae024b7.tar.bz2
libnet: Allocate ICMPv6 packet space on the heap, not on the stack
While doing IPv6 network booting in SLOF, I recently ran into "ERROR: stack overflow in engine()!" messages. Looks like the huge ether_packet arrays that are created on the stack in icmpv6.c can cause these stack overflows. Fix this issue by allocating the ether_packets from the heap instead (the functions should not be timing critical, so the additional overhead should not be an issue here). Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Diffstat (limited to 'lib')
-rw-r--r--lib/libnet/icmpv6.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/lib/libnet/icmpv6.c b/lib/libnet/icmpv6.c
index e897588..2e0cf7c 100644
--- a/lib/libnet/icmpv6.c
+++ b/lib/libnet/icmpv6.c
@@ -31,9 +31,15 @@ void
send_router_solicitation (int fd)
{
ip6_addr_t dest_addr;
- uint8_t ether_packet[ETH_MTU_SIZE];
+ uint8_t *ether_packet;
struct packeth headers;
+ ether_packet = malloc(ETH_MTU_SIZE);
+ if (!ether_packet) {
+ fprintf(stderr, "send_router_solicitation: Out of memory\n");
+ return;
+ }
+
headers.ip6h = (struct ip6hdr *) (ether_packet + sizeof(struct ethhdr));
headers.icmp6h = (struct icmp6hdr *) (ether_packet +
sizeof(struct ethhdr) +
@@ -59,6 +65,8 @@ send_router_solicitation (int fd)
send_ip (fd, headers.ip6h, sizeof(struct ip6hdr) +
ICMPv6_HEADER_SIZE + sizeof(struct router_solicitation));
+
+ free(ether_packet);
}
/**
@@ -200,10 +208,15 @@ void
send_neighbour_solicitation (int fd, ip6_addr_t *dest_ip6)
{
ip6_addr_t snma;
-
- uint8_t ether_packet[ETH_MTU_SIZE];
+ uint8_t *ether_packet;
struct packeth headers;
+ ether_packet = malloc(ETH_MTU_SIZE);
+ if (!ether_packet) {
+ fprintf(stderr, "send_neighbour_solicitation: Out of memory\n");
+ return;
+ }
+
memset(ether_packet, 0, ETH_MTU_SIZE);
headers.ethh = (struct ethhdr *) ether_packet;
headers.ip6h = (struct ip6hdr *) (ether_packet + sizeof(struct ethhdr));
@@ -236,6 +249,8 @@ send_neighbour_solicitation (int fd, ip6_addr_t *dest_ip6)
send_ip (fd, ether_packet + sizeof(struct ethhdr),
sizeof(struct ip6hdr) + ICMPv6_HEADER_SIZE +
sizeof(struct neighbour_solicitation));
+
+ free(ether_packet);
}
/**
@@ -250,9 +265,14 @@ static void
send_neighbour_advertisement (int fd, struct neighbor *target)
{
struct na_flags na_adv_flags;
- uint8_t ether_packet[ETH_MTU_SIZE];
+ uint8_t *ether_packet;
struct packeth headers;
+ ether_packet = malloc(ETH_MTU_SIZE);
+ if (!ether_packet) {
+ fprintf(stderr, "send_neighbour_advertisement: Out of memory\n");
+ return;
+ }
headers.ip6h = (struct ip6hdr *) (ether_packet + sizeof(struct ethhdr));
headers.icmp6h = (struct icmp6hdr *) (ether_packet +
@@ -301,6 +321,8 @@ send_neighbour_advertisement (int fd, struct neighbor *target)
send_ip (fd, ether_packet + sizeof(struct ethhdr),
sizeof(struct ip6hdr) + ICMPv6_HEADER_SIZE +
sizeof(struct neighbour_advertisement));
+
+ free(ether_packet);
}
/**