summaryrefslogtreecommitdiff
path: root/net/ipv4/cipso_ipv4.c
diff options
context:
space:
mode:
authorNazarov Sergey <s-nazarov@yandex.ru>2019-02-25 19:27:15 +0300
committerDavid S. Miller <davem@davemloft.net>2019-02-26 01:32:35 +0300
commit3da1ed7ac398f34fff1694017a07054d69c5f5c5 (patch)
treeac42a19c628b81052191fa63e832e3aca6b84df2 /net/ipv4/cipso_ipv4.c
parent9ef6b42ad6fd7929dd1b6092cb02014e382c6a91 (diff)
downloadlinux-3da1ed7ac398f34fff1694017a07054d69c5f5c5.tar.xz
net: avoid use IPCB in cipso_v4_error
Extract IP options in cipso_v4_error and use __icmp_send. Signed-off-by: Sergey Nazarov <s-nazarov@yandex.ru> Acked-by: Paul Moore <paul@paul-moore.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/cipso_ipv4.c')
-rw-r--r--net/ipv4/cipso_ipv4.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 777fa3b7fb13..eff86a71c1b0 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1735,13 +1735,26 @@ validate_return:
*/
void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
{
+ unsigned char optbuf[sizeof(struct ip_options) + 40];
+ struct ip_options *opt = (struct ip_options *)optbuf;
+
if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES)
return;
+ /*
+ * We might be called above the IP layer,
+ * so we can not use icmp_send and IPCB here.
+ */
+
+ memset(opt, 0, sizeof(struct ip_options));
+ opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr);
+ if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL))
+ return;
+
if (gateway)
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0);
+ __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0, opt);
else
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
+ __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0, opt);
}
/**