diff mbox

libnet: Allocate ICMPv6 packet space on the heap, not on the stack

Message ID 1496920926-14738-1-git-send-email-thuth@redhat.com
State Accepted
Headers show

Commit Message

Thomas Huth June 8, 2017, 11:22 a.m. UTC
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>
---
 lib/libnet/icmpv6.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

Comments

Alexey Kardashevskiy June 15, 2017, 6:13 a.m. UTC | #1
On 08/06/17 21:22, Thomas Huth wrote:
> 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).
> 

Thanks, applied.

> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
>  lib/libnet/icmpv6.c | 30 ++++++++++++++++++++++++++----
>  1 file 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);
>  }
>  
>  /**
>
diff mbox

Patch

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);
 }
 
 /**