#22265: DoS: Memory corruption when receiving packet on disabled port with
nf_call_iptables enabled
-----------------------+------------------------
Reporter: anonymous | Owner: developers
Type: defect | Status: new
Priority: normal | Milestone:
Component: packages | Version: Trunk
Keywords: |
-----------------------+------------------------
The patch 120-bridge_allow_receiption_on_disabled_port.patch (by Stephen
Hemminger, applied by Felix Fietkau) causes memory corruptions when the
bridge has nf_call_iptables enabled. This can be forced by submitting a
lot of IP(v4) packets from a client and switching the link speed on the
client (which disables the link for a short period of time).
I have a QCA955x node with two ports (eth0+eth1 use AR803x;
eth1/GMAC1+SGMII is connected here to the "client"). I am manually
changing the configuration of the device (not really important but just
wanted to document it here so everyone knows that eth1 is in an active
bridge) via:
{{{
ifconfig eth0 down
ifconfig br-lan down
brctl delif br-lan eth0
brctl delbr br-lan
ifconfig eth1 up
brctl addbr br-ssid1
ifconfig br-ssid1 up
brctl addif br-ssid1 eth1
}}}
Then the nf_call_iptables is enabled for the device. So either
CONFIG_BRIDGE_NETFILTER was enabled manually for the kernel build or just
ebtables was selected before the build. This setting here is the important
one.
{{{
echo 1 > /sys/devices/virtual/net/br-ssid1/bridge/nf_call_iptables
echo 1 > /sys/devices/virtual/net/br-ssid1/bridge/nf_call_ip6tables
}}}
The "client" (PC with Debian Jessie without any kind of network manager)
connected to the eth1 port was running following mini script to send
traffic + causing link down/up events:
{{{
#!/bin/bash
IN_TIME=5
ETH_DEV=eth4
ifconfig "${ETH_DEV}" 192.168.5.1
ping -b -f 192.168.5.255 &
while true
do
#100h
ethtool -s "${ETH_DEV}" speed 100 duplex half
sleep $IN_TIME
#100a
ethtool -s "${ETH_DEV}" speed 100 duplex full autoneg on
sleep $IN_TIME
#100h
ethtool -s "${ETH_DEV}" speed 100 duplex half
sleep $IN_TIME
#100a
ethtool -s "${ETH_DEV}" speed 100 duplex full autoneg on
sleep $IN_TIME
#100f
ethtool -s "${ETH_DEV}" speed 100 duplex full
sleep $IN_TIME
#100a
ethtool -s "${ETH_DEV}" speed 100 duplex full autoneg on
sleep $IN_TIME
#100f
ethtool -s "${ETH_DEV}" speed 100 duplex full
sleep $IN_TIME
#1000a
ethtool -s "${ETH_DEV}" speed 1000 duplex full autoneg on
sleep $IN_TIME
#100f
ethtool -s "${ETH_DEV}" speed 100 duplex full
sleep $IN_TIME
#1000a
ethtool -s "${ETH_DEV}" speed 1000 duplex full autoneg on
sleep $IN_TIME
#100h
ethtool -s "${ETH_DEV}" speed 100 duplex half
sleep $IN_TIME
#1000a
ethtool -s "${ETH_DEV}" speed 1000 duplex full autoneg on
sleep $IN_TIME
#100h
ethtool -s "${ETH_DEV}" speed 100 duplex half
sleep $IN_TIME
#1000f
ethtool -s "${ETH_DEV}" speed 1000 duplex full
sleep $IN_TIME
#100f
ethtool -s "${ETH_DEV}" speed 100 duplex full
sleep $IN_TIME
#1000f
ethtool -s "${ETH_DEV}" speed 1000 duplex full
sleep $IN_TIME
#100f
ethtool -s "${ETH_DEV}" speed 100 duplex full
sleep $IN_TIME
#1000f
ethtool -s "${ETH_DEV}" speed 1000 duplex full
sleep $IN_TIME
#100h
ethtool -s "${ETH_DEV}" speed 100 duplex half
sleep $IN_TIME
#1000f
ethtool -s "${ETH_DEV}" speed 1000 duplex full
sleep $IN_TIME
#100h
ethtool -s "${ETH_DEV}" speed 100 duplex half
sleep $IN_TIME
#1000a
ethtool -s "${ETH_DEV}" speed 1000 duplex full autoneg on
sleep $IN_TIME
#100a
ethtool -s "${ETH_DEV}" speed 100 duplex full autoneg on
sleep $IN_TIME
#1000a
ethtool -s "${ETH_DEV}" speed 1000 duplex full autoneg on
sleep $IN_TIME
#100a
ethtool -s "${ETH_DEV}" speed 100 duplex full autoneg on
sleep $IN_TIME
done
}}}
This problem was discovered on ag71xx with Linux 3.18 (CC) and can still
be reproduced with trunk (49223). The stack trace of the crash will look
rather unrelated because the memory corruption itself is not catched as
pagefault and instead only causes "funny" side effects which will crash
the kernel:
{{{
eth1: link up (100Mbps/Half duplex)
eth1: link down
br-ssid1: port 1(eth1) entered disabled state
eth1: link up (100Mbps/Full duplex)
br-ssid1: port 1(eth1) entered forwarding state
br-ssid1: port 1(eth1) entered forwarding state
CPU 0 Unable to handle kernel paging request at virtual address 00000000,
epc == 80250a28, ra == 802878c4
Oops[#1]:
CPU: 0 PID: 107 Comm: kworker/0:1 Not tainted 4.4.7 #1
Workqueue: events linkwatch_event
task: 878b1e00 ti: 8793a000 task.ti: 8793a000
$ 0 : 00000000 00000001 00000001 00000000
$ 4 : 86e9347c 86f0d780 00000000 10000000
$ 8 : 00000004 c0000000 00000000 00000000
$12 : 00000001 00080010 00000000 00000004
$16 : 86e93400 86f0d780 00000120 86e93464
$20 : 00000000 00000000 00000001 00000000
$24 : 00000000 00000000
$28 : 8793a000 8793bc68 00000000 802878c4
Hi : 00000000
Lo : 00000000
epc : 80250a28 skb_queue_tail+0x18/0x44
ra : 802878c4 __netlink_sendskb+0x44/0x6c
Status: 1100fc02 KERNEL EXL
Cause : 0080000c (ExcCode 03)
BadVA : 00000000
PrId : 00019750 (MIPS 74Kc)
Modules linked in: pppoe ppp_async iptable_nat ath9k pppox ppp_generic
nf_nat_ipv4 nf_conntrack_ipv6 nf_conntrack_ipv4 ipt_REJECT ipt_MASQUERADE
ebtable_nat ebtable_filter ebtable_broute ath9k_common xt_time xt_tcpudp
xt_state xt_nat xt_multiport xt_mark xt_mac xt_limit xt_id xt_conntrack
xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_CT slhc nf_reject_ipv4
nf_nat_redirect nf_nat_masquerade_ipv4 nf_nat nf_log_ipv4 nf_defrag_ipv6
nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack iptable_raw
iptable_mangle iptable_filter ip_tables ebtables ebt_vlan ebt_stp
ebt_redirect ebt_pkttype ebt_mark_m ebt_mark ebt_limit ebt_among ebt_802_3
crc_ccitt ath9k_hw ath10k_pci batman_adv ath10k_core ath mac80211 cfg80211
compat libcrc32c ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 nf_log_common
ip6table_raw ip6table_mangle ip6table_filter ip6_tables x_tables
gpio_button_hotplug crc16 crc32c_generic crypto_hash
Process kworker/0:1 (pid: 107, threadinfo=8793a000, task=878b1e00,
tls=00000000)
Stack : 00000000 147f67b2 86f0d780 86e93400 86e93400 86f0d780 86f0d780
80287b60
80400000 80329140 80400000 803d2708 8793bc98 00000000 8041c0d8
00000000
00000001 804a0000 00000000 86f0d780 00000000 8784cc00 00000000
87a14800
80402c40 878aad18 00000008 80287cb4 8784cc00 87b5f050 00000000
8032a114
02080020 00000000 00000000 87802780 00000010 80289e34 80403406
803a40a8
...
Call Trace:
[<80250a28>] skb_queue_tail+0x18/0x44
[<802878c4>] __netlink_sendskb+0x44/0x6c
[<80287b60>] netlink_broadcast_filtered+0x274/0x3ac
[<80287cb4>] netlink_broadcast+0x1c/0x28
[<80289e34>] nlmsg_notify+0x6c/0xf4
[<8032a420>] br_ifinfo_notify+0xe0/0x138
[<803215a8>] br_device_event+0x214/0x240
[<80098664>] notifier_call_chain+0x58/0xa0
[<80098744>] raw_notifier_call_chain+0x14/0x20
[<80261450>] netdev_state_change+0x34/0x60
[<80276e44>] linkwatch_do_dev+0x70/0xac
[<802771d4>] __linkwatch_run_queue+0x120/0x16c
[<8027724c>] linkwatch_event+0x2c/0x38
[<80092a68>] process_one_work+0x1f8/0x334
[<80093864>] worker_thread+0x2b4/0x408
[<80097b9c>] kthread+0xdc/0xe8
[<80060878>] ret_from_kernel_thread+0x14/0x1c
}}}
Removing the patch makes the crash unreproducible.
--
Ticket URL: <https://dev.openwrt.org/ticket/22265>
OpenWrt <http://openwrt.org>
Opensource Wireless Router Technology
_______________________________________________
openwrt-tickets mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-tickets