#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

Reply via email to