diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig index 0929f4c..9045a44 100644 --- a/grsecurity/Kconfig +++ b/grsecurity/Kconfig @@ -860,7 +860,8 @@ config GRKERNSEC_BLACKHOLE This feature supports both IPV4 and IPV6 and exempts the loopback interface from blackholing. Enabling this feature makes a host more resilient to DoS attacks and reduces network - visibility against scanners. + visibility against scanners. If the sysctl option is enabled, a + sysctl option with the name "netdev_blackhole" is created. config GRKERNSEC_SOCKET bool "Socket restrictions" diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c index 11d1f34..5a4609d 100644 --- a/grsecurity/grsec_init.c +++ b/grsecurity/grsec_init.c @@ -47,6 +47,7 @@ int grsec_enable_socket_client; int grsec_socket_client_gid; int grsec_enable_socket_server; int grsec_socket_server_gid; +int grsec_netdev_blackhole; int grsec_resource_logging; int grsec_lock; @@ -211,6 +212,9 @@ grsecurity_init(void) #ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL grsec_enable_chroot_sysctl = 1; #endif +#ifdef CONFIG_GRKERNSEC_BLACKHOLE + grsec_netdev_blackhole = 1; +#endif #ifdef CONFIG_GRKERNSEC_TPE grsec_enable_tpe = 1; grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID; diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c index cbc1327..d20fce0 100644 --- a/grsecurity/grsec_sysctl.c +++ b/grsecurity/grsec_sysctl.c @@ -315,6 +315,16 @@ ctl_table grsecurity_table[] = { .proc_handler = &proc_dointvec, }, #endif +#ifdef CONFIG_GRKERNSEC_BLACKHOLE + { + .ctl_name = CTL_UNNUMBERED, + .procname = "netdev_blackhole", + .data = &grsec_netdev_blackhole, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = &proc_dointvec, + }, +#endif #ifdef CONFIG_GRKERNSEC_AUDIT_GROUP { .ctl_name = CTL_UNNUMBERED, diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h index e152e7a..f2d09a4 100644 --- a/include/linux/grsecurity.h +++ b/include/linux/grsecurity.h @@ -22,6 +22,8 @@ #error "CONFIG_PAX enabled, but no PaX options are enabled." #endif +extern int grsec_netdev_blackhole; + void gr_handle_brute_attach(struct task_struct *p); void gr_handle_brute_check(void); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index bf6e651..2f54766 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include @@ -1543,7 +1544,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) reset: #ifdef CONFIG_GRKERNSEC_BLACKHOLE - if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK)) + if (!grsec_netdev_blackhole || !skb->dev || (skb->dev->flags & IFF_LOOPBACK)) #endif tcp_v4_send_reset(rsk, skb); discard: @@ -1654,7 +1655,7 @@ bad_packet: TCP_INC_STATS_BH(net, TCP_MIB_INERRS); } else { #ifdef CONFIG_GRKERNSEC_BLACKHOLE - if (skb->dev->flags & IFF_LOOPBACK) + if (!grsec_netdev_blackhole || skb->dev->flags & IFF_LOOPBACK) #endif tcp_v4_send_reset(NULL, skb); } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f8ff23e..4942839 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -22,6 +22,8 @@ #include #include #include +#include + #include #include #include @@ -674,7 +676,7 @@ embryonic_reset: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); #ifndef CONFIG_GRKERNSEC_BLACKHOLE - if (!(flg & TCP_FLAG_RST)) + if (!grsec_netdev_blackhole || !(flg & TCP_FLAG_RST)) req->rsk_ops->send_reset(sk, skb); #endif diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 9058401..d0eaeba 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -100,6 +100,8 @@ #include #include #include +#include + #include #include #include @@ -1353,7 +1355,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); #ifdef CONFIG_GRKERNSEC_BLACKHOLE - if (skb->dev->flags & IFF_LOOPBACK) + if (!grsec_netdev_blackhole || skb->dev->flags & IFF_LOOPBACK) #endif icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 23d9228..8f9d67e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1579,7 +1580,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) reset: #ifdef CONFIG_GRKERNSEC_BLACKHOLE - if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK)) + if (!grsec_netdev_blackhole || !skb->dev || (skb->dev->flags & IFF_LOOPBACK)) #endif tcp_v6_send_reset(sk, skb); discard: @@ -1704,7 +1705,7 @@ bad_packet: TCP_INC_STATS_BH(net, TCP_MIB_INERRS); } else { #ifdef CONFIG_GRKERNSEC_BLACKHOLE - if (skb->dev->flags & IFF_LOOPBACK) + if (!grsec_netdev_blackhole || skb->dev->flags & IFF_LOOPBACK) #endif tcp_v6_send_reset(NULL, skb); } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b289d93..81a8d5d 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -34,6 +34,8 @@ #include #include #include +#include + #include #include @@ -588,7 +590,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, proto == IPPROTO_UDPLITE); #ifdef CONFIG_GRKERNSEC_BLACKHOLE - if (skb->dev->flags & IFF_LOOPBACK) + if (!grsec_netdev_blackhole || skb->dev->flags & IFF_LOOPBACK) #endif icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);