lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1003104a-56ea-4a44-4524-ddabaecd35e6@lwfinger.net>
Date:   Tue, 10 Jan 2017 19:53:50 -0600
From:   Larry Finger <Larry.Finger@...inger.net>
To:     Dmitry Osipenko <digetx@...il.com>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:     linux-kernel@...r.kernel.org, stable@...r.kernel.org,
        Ping-Ke Shih <pkshih@...ltek.com>,
        Kalle Valo <kvalo@...eaurora.org>
Subject: Re: [PATCH 4.9 003/116] rtlwifi: Fix enter/exit power_save

On 01/10/2017 11:40 AM, Dmitry Osipenko wrote:
> Hello, this patch causes a kernel panic with the rtl8192cu driver.
>
> <6>[   20.847025] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
> <1>[   21.699551] BUG: unable to handle kernel NULL pointer dereference at
> 0000000000000048
> <1>[   21.699626] IP: [<ffffffffc037de33>] rtl_lps_leave+0x13/0x40 [rtlwifi]
> <4>[   21.699681] PGD 20cf47067
> <4>[   21.699702] PUD 20cf42067
> <4>[   21.699725] PMD 0
> <4>[   21.699732]
> <4>[   21.699759] Oops: 0000 [#1] PREEMPT SMP
> <4>[   21.699794] Modules linked in: rtl8192cu rtl_usb rtl8192c_common rtlwifi
> snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec
> snd_hwdep snd_hda_core dm_mod thermal
> <4>[   21.699985] CPU: 0 PID: 2656 Comm: ntpdate Not tainted 4.9.2 #1
> <4>[   21.700036] Hardware name: Gigabyte Technology Co., Ltd. To be filled by
> O.E.M./Z77-DS3H, BIOS F11a 11/13/2013
> <4>[   21.700118] task: ffff9ce2509ca4c0 task.stack: ffffa41003eac000
> <4>[   21.700168] RIP: 0010:[<ffffffffc037de33>]  [<ffffffffc037de33>]
> rtl_lps_leave+0x13/0x40 [rtlwifi]
> <4>[   21.700250] RSP: 0018:ffffa41003eaf520  EFLAGS: 00010206
> <4>[   21.700296] RAX: 0000000080000802 RBX: ffff9ce251371420 RCX: ffff9ce254ff4640
> <4>[   21.700356] RDX: 0000000000000806 RSI: ffff9ce25137afb8 RDI: 0000000000000000
> <4>[   21.700416] RBP: ffff9ce25137afb8 R08: ffffffffc0382d00 R09: ffff9ce254e38c31
> <4>[   21.700475] R10: 0000000000000000 R11: ffff9ce251370700 R12: 0000000000000000
> <4>[   21.700535] R13: 0000000000000000 R14: ffff9ce251371420 R15: ffff9ce254e38c00
> <4>[   21.700595] FS:  00007f22f6da8700(0000) GS:ffff9ce25f200000(0000)
> knlGS:0000000000000000
> <4>[   21.700662] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> <4>[   21.700711] CR2: 0000000000000048 CR3: 000000020cf65000 CR4: 00000000001406f0
> <4>[   21.700770] Stack:
> <4>[   21.700790]  ffffffffc0375088 0000000000000008 ffff9ce251370700
> 0000000000000001
> <4>[   21.700867]  ffffffffc03751c7 0100000000000000 ffffa41003eaf618
> ffff9ce252b5a800
> <4>[   21.700944]  0000000000000000 ffff9ce251371420 0000000000000000
> ffff9ce254e38c00
> <4>[   21.701021] Call Trace:
> <4>[   21.701048]  [<ffffffffc0375088>] ? setup_arp_tx.isra.20+0x48/0x60 [rtlwifi]
> <4>[   21.701110]  [<ffffffffc03751c7>] ? rtl_is_special_data+0x127/0x210 [rtlwifi]
> <4>[   21.701171]  [<ffffffffc037e8c7>] ? rtl_get_rate+0x97/0x210 [rtlwifi]
> <4>[   21.701228]  [<ffffffff9a87deb6>] ? rate_control_get_rate+0xb6/0x140
> <4>[   21.701283]  [<ffffffff9a88cf30>] ? ieee80211_tx_h_rate_ctrl+0x1e0/0x3f0
> <4>[   21.701340]  [<ffffffff9a88fcc2>] ? invoke_tx_handlers_early+0x222/0x5a0
> <4>[   21.701397]  [<ffffffff9a89186e>] ? ieee80211_tx+0x6e/0x130
> <4>[   21.701446]  [<ffffffff9a892661>] ? __ieee80211_subif_start_xmit+0x4d1/0x9d0
> <4>[   21.701506]  [<ffffffff9a741874>] ? nf_conntrack_tuple_taken+0x1c4/0x1d0
> <4>[   21.701565]  [<ffffffff9a749779>] ? get_unique_tuple+0xe9/0x510
> <4>[   21.701617]  [<ffffffff9a892b6c>] ? ieee80211_subif_start_xmit+0xc/0x10
> <4>[   21.701675]  [<ffffffff9a6e606a>] ? dev_hard_start_xmit+0x9a/0x210
> <4>[   21.701729]  [<ffffffff9a708a46>] ? sch_direct_xmit+0xd6/0x1a0
> <4>[   21.701780]  [<ffffffff9a6e66d2>] ? __dev_queue_xmit+0x422/0x620
> <4>[   21.701832]  [<ffffffff9a79859f>] ? arp_xmit+0x9f/0xb0
> <4>[   21.701878]  [<ffffffff9a798220>] ? arp_create+0x250/0x250
> <4>[   21.701926]  [<ffffffff9a7986ee>] ? arp_solicit+0xee/0x240
> <4>[   21.701974]  [<ffffffff9a1335cd>] ? mod_timer+0x1ad/0x360
> <4>[   21.702022]  [<ffffffff9a6edf12>] ? neigh_probe+0x42/0x60
> <4>[   21.702071]  [<ffffffff9a6ef2f2>] ? __neigh_event_send+0x1e2/0x230
> <4>[   21.702124]  [<ffffffff9a6ef520>] ? neigh_resolve_output+0x120/0x1b0
> <4>[   21.702179]  [<ffffffff9a76ac37>] ? ip_finish_output2+0x127/0x300
> <4>[   21.702231]  [<ffffffff9a76c524>] ? ip_output+0x64/0x100
> <4>[   21.702277]  [<ffffffff9a76b9b0>] ?
> __ip_flush_pending_frames.isra.46+0x80/0x80
> <4>[   21.702339]  [<ffffffff9a76ceb5>] ? ip_send_skb+0x15/0x40
> <4>[   21.702386]  [<ffffffff9a79308f>] ? udp_send_skb+0x15f/0x240
> <4>[   21.702436]  [<ffffffff9a7944e6>] ? udp_sendmsg+0x2b6/0x840
> <4>[   21.702485]  [<ffffffff9a0e10ba>] ? __local_bh_enable_ip+0x8a/0x90
> <4>[   21.702538]  [<ffffffff9a76ac4a>] ? ip_finish_output2+0x13a/0x300
> <4>[   21.702592]  [<ffffffff9a1fda33>] ? rw_copy_check_uvector+0x53/0x110
> <4>[   21.702648]  [<ffffffff9a382b37>] ? import_iovec+0x27/0xc0
> <4>[   21.702698]  [<ffffffff9a6c8d01>] ? ___sys_sendmsg+0x111/0x2a0
> <4>[   21.702749]  [<ffffffff9a20fa50>] ? poll_select_copy_remaining+0x130/0x130
> <4>[   21.702808]  [<ffffffff9a7944f5>] ? udp_sendmsg+0x2c5/0x840
> <4>[   21.702857]  [<ffffffff9a79b2b1>] ? __ip_dev_find+0x111/0x130
> <4>[   21.702908]  [<ffffffff9a764885>] ? __ip_route_output_key_hash+0x2c5/0x870
> <4>[   21.702968]  [<ffffffff9a6c94e9>] ? __sys_sendmmsg+0x89/0x160
> <4>[   21.703018]  [<ffffffff9a6c8490>] ? SYSC_connect+0x50/0xa0
> <4>[   21.703066]  [<ffffffff9a6c626a>] ? sock_alloc_file+0x9a/0x110
> <4>[   21.703119]  [<ffffffff9a6c95ce>] ? SyS_sendmmsg+0xe/0x20
> <4>[   21.703166]  [<ffffffff9a8c8837>] ? entry_SYSCALL_64_fastpath+0x1a/0xa9
> <4>[   21.703222] Code: 05 e9 32 ff ff ff e9 2d fe ff ff 0f 1f 00 66 2e 0f 1f 84
> 00 00 00 00 00 0f 1f 44 00 00 65 8b 05 24 f4 c8 3f a9 00 ff 1f 00 74 23 <48> 8b
> 57 48 bf 40 00 00 00 48 8b 35 3d ba b7 da c6 82 ad a2 00
> <1>[   21.709488] RIP  [<ffffffffc037de33>] rtl_lps_leave+0x13/0x40 [rtlwifi]
> <4>[   21.712533]  RSP <ffffa41003eaf520>
> <4>[   21.715589] CR2: 0000000000000048
> <4>[   21.735721] ---[ end trace f6ce402401b0b86a ]---
>
>> 4.9-stable review patch.  If anyone has any objections, please let me know.
>>
>> ------------------
>>
>> From: Larry Finger <Larry.Finger@...inger.net>
>>
>> commit ba9f93f82abafe2552eac942ebb11c2df4f8dd7f upstream.
>>
>> In commit a5ffbe0a1993 ("rtlwifi: Fix scheduling while atomic bug") and
>> commit a269913c52ad ("rtlwifi: Rework rtl_lps_leave() and rtl_lps_enter()
>> to use work queue"), an error was introduced in the power-save routines
>> due to the fact that leaving PS was delayed by the use of a work queue.
>>
>> This problem is fixed by detecting if the enter or leave routines are
>> in interrupt mode. If so, the workqueue is used to place the request.
>> If in normal mode, the enter or leave routines are called directly.
>>
>> Fixes: a269913c52ad ("rtlwifi: Rework rtl_lps_leave() and rtl_lps_enter() to use work queue")
>> Reported-by: Ping-Ke Shih <pkshih@...ltek.com>
>> Signed-off-by: Larry Finger <Larry.Finger@...inger.net>
>> Signed-off-by: Kalle Valo <kvalo@...eaurora.org>
>> Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
>>
>> ---
>>  drivers/net/wireless/realtek/rtlwifi/base.c |    8 +++---
>>  drivers/net/wireless/realtek/rtlwifi/core.c |    9 ++-----
>>  drivers/net/wireless/realtek/rtlwifi/pci.c  |   14 +++-------
>>  drivers/net/wireless/realtek/rtlwifi/ps.c   |   36 +++++++++++++++++++++-------
>>  4 files changed, 40 insertions(+), 27 deletions(-)
>>
>> --- a/drivers/net/wireless/realtek/rtlwifi/base.c
>> +++ b/drivers/net/wireless/realtek/rtlwifi/base.c
>> @@ -1303,12 +1303,13 @@ EXPORT_SYMBOL_GPL(rtl_action_proc);
>>
>>  static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc)
>>  {
>> +	struct ieee80211_hw *hw = rtlpriv->hw;
>> +
>>  	rtlpriv->ra.is_special_data = true;
>>  	if (rtlpriv->cfg->ops->get_btc_status())
>>  		rtlpriv->btcoexist.btc_ops->btc_special_packet_notify(
>>  					rtlpriv, 1);
>> -	rtlpriv->enter_ps = false;
>> -	schedule_work(&rtlpriv->works.lps_change_work);
>> +	rtl_lps_leave(hw);
>>  	ppsc->last_delaylps_stamp_jiffies = jiffies;
>>  }
>>
>> @@ -1381,8 +1382,7 @@ u8 rtl_is_special_data(struct ieee80211_
>>
>>  		if (is_tx) {
>>  			rtlpriv->ra.is_special_data = true;
>> -			rtlpriv->enter_ps = false;
>> -			schedule_work(&rtlpriv->works.lps_change_work);
>> +			rtl_lps_leave(hw);
>>  			ppsc->last_delaylps_stamp_jiffies = jiffies;
>>  		}
>>
>> --- a/drivers/net/wireless/realtek/rtlwifi/core.c
>> +++ b/drivers/net/wireless/realtek/rtlwifi/core.c
>> @@ -1150,10 +1150,8 @@ static void rtl_op_bss_info_changed(stru
>>  		} else {
>>  			mstatus = RT_MEDIA_DISCONNECT;
>>
>> -			if (mac->link_state == MAC80211_LINKED) {
>> -				rtlpriv->enter_ps = false;
>> -				schedule_work(&rtlpriv->works.lps_change_work);
>> -			}
>> +			if (mac->link_state == MAC80211_LINKED)
>> +				rtl_lps_leave(hw);
>>  			if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
>>  				rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
>>  			mac->link_state = MAC80211_NOLINK;
>> @@ -1431,8 +1429,7 @@ static void rtl_op_sw_scan_start(struct
>>  	}
>>
>>  	if (mac->link_state == MAC80211_LINKED) {
>> -		rtlpriv->enter_ps = false;
>> -		schedule_work(&rtlpriv->works.lps_change_work);
>> +		rtl_lps_leave(hw);
>>  		mac->link_state = MAC80211_LINKED_SCANNING;
>>  	} else {
>>  		rtl_ips_nic_on(hw);
>> --- a/drivers/net/wireless/realtek/rtlwifi/pci.c
>> +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
>> @@ -663,11 +663,9 @@ tx_status_ok:
>>  	}
>>
>>  	if (((rtlpriv->link_info.num_rx_inperiod +
>> -		rtlpriv->link_info.num_tx_inperiod) > 8) ||
>> -		(rtlpriv->link_info.num_rx_inperiod > 2)) {
>> -		rtlpriv->enter_ps = false;
>> -		schedule_work(&rtlpriv->works.lps_change_work);
>> -	}
>> +	      rtlpriv->link_info.num_tx_inperiod) > 8) ||
>> +	      (rtlpriv->link_info.num_rx_inperiod > 2))
>> +		rtl_lps_leave(hw);
>>  }
>>
>>  static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
>> @@ -918,10 +916,8 @@ new_trx_end:
>>  		}
>>  		if (((rtlpriv->link_info.num_rx_inperiod +
>>  		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
>> -		      (rtlpriv->link_info.num_rx_inperiod > 2)) {
>> -			rtlpriv->enter_ps = false;
>> -			schedule_work(&rtlpriv->works.lps_change_work);
>> -		}
>> +		      (rtlpriv->link_info.num_rx_inperiod > 2))
>> +			rtl_lps_leave(hw);
>>  		skb = new_skb;
>>  no_new:
>>  		if (rtlpriv->use_new_trx_flow) {
>> --- a/drivers/net/wireless/realtek/rtlwifi/ps.c
>> +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
>> @@ -407,8 +407,8 @@ void rtl_lps_set_psmode(struct ieee80211
>>  	}
>>  }
>>
>> -/*Enter the leisure power save mode.*/
>> -void rtl_lps_enter(struct ieee80211_hw *hw)
>> +/* Interrupt safe routine to enter the leisure power save mode.*/
>> +static void rtl_lps_enter_core(struct ieee80211_hw *hw)
>>  {
>>  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
>>  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
>> @@ -444,10 +444,9 @@ void rtl_lps_enter(struct ieee80211_hw *
>>
>>  	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
>>  }
>> -EXPORT_SYMBOL(rtl_lps_enter);
>>
>> -/*Leave the leisure power save mode.*/
>> -void rtl_lps_leave(struct ieee80211_hw *hw)
>> +/* Interrupt safe routine to leave the leisure power save mode.*/
>> +static void rtl_lps_leave_core(struct ieee80211_hw *hw)
>>  {
>>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>>  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
>> @@ -477,7 +476,6 @@ void rtl_lps_leave(struct ieee80211_hw *
>>  	}
>>  	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
>>  }
>> -EXPORT_SYMBOL(rtl_lps_leave);
>>
>>  /* For sw LPS*/
>>  void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
>> @@ -670,12 +668,34 @@ void rtl_lps_change_work_callback(struct
>>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>>
>>  	if (rtlpriv->enter_ps)
>> -		rtl_lps_enter(hw);
>> +		rtl_lps_enter_core(hw);
>>  	else
>> -		rtl_lps_leave(hw);
>> +		rtl_lps_leave_core(hw);
>>  }
>>  EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
>>
>> +void rtl_lps_enter(struct ieee80211_hw *hw)
>> +{
>> +	struct rtl_priv *rtlpriv = rtl_priv(hw);
>> +
>> +	if (!in_interrupt())
>> +		return rtl_lps_enter_core(hw);
>> +	rtlpriv->enter_ps = true;
>> +	schedule_work(&rtlpriv->works.lps_change_work);
>> +}
>> +EXPORT_SYMBOL_GPL(rtl_lps_enter);
>> +
>> +void rtl_lps_leave(struct ieee80211_hw *hw)
>> +{
>> +	struct rtl_priv *rtlpriv = rtl_priv(hw);
>> +
>> +	if (!in_interrupt())
>> +		return rtl_lps_leave_core(hw);
>> +	rtlpriv->enter_ps = false;
>> +	schedule_work(&rtlpriv->works.lps_change_work);
>> +}
>> +EXPORT_SYMBOL_GPL(rtl_lps_leave);
>> +
>>  void rtl_swlps_wq_callback(void *data)
>>  {
>>  	struct rtl_works *rtlworks = container_of_dwork_rtl(data,

The fix is being merged into mainline. The reference is 
http://marc.info/?l=linux-wireless&m=148234081512703&w=2.

Larry


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ