Commit 66ed1e5e authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

pktgen: Dont leak kernel memory

While playing with pktgen, I realized IP ID was not filled and a
random value was taken, possibly leaking 2 bytes of kernel memory.
 
We can use an increasing ID, this can help diagnostics anyway.

Also clear packet payload, instead of leaking kernel memory.
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 62e20a62
...@@ -335,6 +335,7 @@ struct pktgen_dev { ...@@ -335,6 +335,7 @@ struct pktgen_dev {
__u32 cur_src_mac_offset; __u32 cur_src_mac_offset;
__be32 cur_saddr; __be32 cur_saddr;
__be32 cur_daddr; __be32 cur_daddr;
__u16 ip_id;
__u16 cur_udp_dst; __u16 cur_udp_dst;
__u16 cur_udp_src; __u16 cur_udp_src;
__u16 cur_queue_map; __u16 cur_queue_map;
...@@ -2630,6 +2631,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, ...@@ -2630,6 +2631,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
iph->protocol = IPPROTO_UDP; /* UDP */ iph->protocol = IPPROTO_UDP; /* UDP */
iph->saddr = pkt_dev->cur_saddr; iph->saddr = pkt_dev->cur_saddr;
iph->daddr = pkt_dev->cur_daddr; iph->daddr = pkt_dev->cur_daddr;
iph->id = htons(pkt_dev->ip_id);
pkt_dev->ip_id++;
iph->frag_off = 0; iph->frag_off = 0;
iplen = 20 + 8 + datalen; iplen = 20 + 8 + datalen;
iph->tot_len = htons(iplen); iph->tot_len = htons(iplen);
...@@ -2641,24 +2644,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, ...@@ -2641,24 +2644,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
skb->dev = odev; skb->dev = odev;
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
if (pkt_dev->nfrags <= 0) if (pkt_dev->nfrags <= 0) {
pgh = (struct pktgen_hdr *)skb_put(skb, datalen); pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
else { memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr));
} else {
int frags = pkt_dev->nfrags; int frags = pkt_dev->nfrags;
int i; int i, len;
pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8);
if (frags > MAX_SKB_FRAGS) if (frags > MAX_SKB_FRAGS)
frags = MAX_SKB_FRAGS; frags = MAX_SKB_FRAGS;
if (datalen > frags * PAGE_SIZE) { if (datalen > frags * PAGE_SIZE) {
skb_put(skb, datalen - frags * PAGE_SIZE); len = datalen - frags * PAGE_SIZE;
memset(skb_put(skb, len), 0, len);
datalen = frags * PAGE_SIZE; datalen = frags * PAGE_SIZE;
} }
i = 0; i = 0;
while (datalen > 0) { while (datalen > 0) {
struct page *page = alloc_pages(GFP_KERNEL, 0); struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
skb_shinfo(skb)->frags[i].page = page; skb_shinfo(skb)->frags[i].page = page;
skb_shinfo(skb)->frags[i].page_offset = 0; skb_shinfo(skb)->frags[i].page_offset = 0;
skb_shinfo(skb)->frags[i].size = skb_shinfo(skb)->frags[i].size =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment