Dedy Lansky (1): cfg80211/mac80211: make ieee80211_send_layer2_update a public function
Jaegeuk Kim (1): f2fs: support swap file w/ DIO
Jouni Malinen (1): mac80211: Do not send Layer 2 Update frame before authorization
Keith Busch (1): PCI/AER: Refactor error injection fallbacks
Peng Wang (1): kernfs: fix potential null pointer dereference
Shmulik Ladkani (1): net/sched: act_mirred: Pull mac prior redir to non mac_header_xmit device
Wei Li (1): arm64: fix calling nmi_enter() repeatedly when IPI_CPU_CRASH_STOP
arch/arm64/kernel/smp.c | 7 ++- drivers/pci/pcie/aer_inject.c | 66 +++++++++++--------- fs/f2fs/data.c | 140 +++++++++++++++++++++++++++++++++++++++--- fs/f2fs/f2fs.h | 2 +- fs/kernfs/dir.c | 3 +- include/net/cfg80211.h | 11 ++++ include/trace/events/f2fs.h | 11 ++-- net/mac80211/cfg.c | 58 ++--------------- net/mac80211/sta_info.c | 4 ++ net/sched/act_mirred.c | 22 ++++--- net/wireless/util.c | 45 ++++++++++++++ 11 files changed, 259 insertions(+), 110 deletions(-)
From: Wei Li liwei391@huawei.com
hulk inclusion category: bugfix bugzilla: 28145 CVE: NA
-------------------------------------------------
The nmi_enter() may has been called in el1_irq. When processing IPI_CPU_CRASH_STOP in handle_IPI(), don't call nmi_enter() again if interrupt is disabled (already in NMI context).
Fixes: e753aae7e448 ("arm64: Fix interrupt tracing in the presence of NMIs") Signed-off-by: Wei Li liwei391@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/kernel/smp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 50c98ab..b13a2d2 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -924,9 +924,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
case IPI_CPU_CRASH_STOP: if (IS_ENABLED(CONFIG_KEXEC_CORE)) { - if (gic_supports_pseudo_nmis()) - nmi_enter(); - else + if (gic_supports_pseudo_nmis()) { + if (irqs_enabled) + nmi_enter(); + } else irq_enter(); ipi_cpu_crash_stop(cpu, regs);
From: Peng Wang rocking@whu.edu.cn
mainline inclusion from mainline-5.4-rc1 commit 2fd60da46da76948b8cc561ae8cc902209686253 category: bugfix bugzilla: 21637 CVE: NA
---------------------------
Get root safely after kn is ensureed to be not null.
Signed-off-by: Peng Wang rocking@whu.edu.cn Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20190708151611.13242-1-rocking@whu.edu.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: yu kuai yukuai3@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/kernfs/dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index a4a538a..7fa9403 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -431,7 +431,6 @@ struct kernfs_node *kernfs_get_active(struct kernfs_node *kn) */ void kernfs_put_active(struct kernfs_node *kn) { - struct kernfs_root *root = kernfs_root(kn); int v;
if (unlikely(!kn)) @@ -443,7 +442,7 @@ void kernfs_put_active(struct kernfs_node *kn) if (likely(v != KN_DEACTIVATED_BIAS)) return;
- wake_up_all(&root->deactivate_waitq); + wake_up_all(&kernfs_root(kn)->deactivate_waitq); }
/**
From: Shmulik Ladkani sladkani@proofpoint.com
mainline inclusion from mainline-v5.5 commit 70cf3dc73132 category: bugfix bugzilla: 28016 CVE: NA
-------------------------------------------------
There's no skb_pull performed when a mirred action is set at egress of a mac device, with a target device/action that expects skb->data to point at the network header.
As a result, either the target device is errornously given an skb with data pointing to the mac (egress case), or the net stack receives the skb with data pointing to the mac (ingress case).
E.g: # tc qdisc add dev eth9 root handle 1: prio # tc filter add dev eth9 parent 1: prio 9 protocol ip handle 9 basic \ action mirred egress redirect dev tun0
(tun0 is a tun device. result: tun0 errornously gets the eth header instead of the iph)
Revise the push/pull logic of tcf_mirred_act() to not rely on the skb_at_tc_ingress() vs tcf_mirred_act_wants_ingress() comparison, as it does not cover all "pull" cases.
Instead, calculate whether the required action on the target device requires the data to point at the network header, and compare this to whether skb->data points to network header - and make the push/pull adjustments as necessary.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Shmulik Ladkani sladkani@proofpoint.com Tested-by: Jamal Hadi Salim jhs@mojatatu.com Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: YueHaibing yuehaibing@huawei.com
Conflicts: net/sched/act_mirred.c Reviewed-by: Mao Wenan maowenan@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- net/sched/act_mirred.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 399e3be..bfe0d86 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -205,8 +205,10 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, bool use_reinsert; bool want_ingress; bool is_redirect; + bool expects_nh; int m_eaction; int mac_len; + bool at_nh;
tcf_lastuse_update(&m->tcf_tm); bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb); @@ -239,19 +241,19 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, goto out; }
- /* If action's target direction differs than filter's direction, - * and devices expect a mac header on xmit, then mac push/pull is - * needed. - */ want_ingress = tcf_mirred_act_wants_ingress(m_eaction); - if (skb_at_tc_ingress(skb) != want_ingress && m_mac_header_xmit) { - if (!skb_at_tc_ingress(skb)) { - /* caught at egress, act ingress: pull mac */ - mac_len = skb_network_header(skb) - skb_mac_header(skb); + + expects_nh = want_ingress || !m_mac_header_xmit; + at_nh = skb->data == skb_network_header(skb); + if (at_nh != expects_nh) { + mac_len = skb_at_tc_ingress(skb) ? skb->mac_len : + skb_network_header(skb) - skb_mac_header(skb); + if (expects_nh) { + /* target device/action expect data at nh */ skb_pull_rcsum(skb2, mac_len); } else { - /* caught at ingress, act egress: push mac */ - skb_push_rcsum(skb2, skb->mac_len); + /* target device/action expect data at mac */ + skb_push_rcsum(skb2, mac_len); } }
From: Keith Busch keith.busch@intel.com
mainline inclusion from mainline-v4.20-rc1 commit e51cd9ce5dd3b10f9e67a30a4dc00fc1fa80c673 category: bugfix bugzilla: NA CVE: NA
-------------------------------------------------
Move the bus ops fallback into separate functions. No functional change here.
[wangxiongfeng]
We came across the following Oops.
[ 7365.854051] Internal error: Oops: 96000004 [#1] SMP [ 7365.858907] Process bash (pid: 110038, stack limit = 0x00000000c3909a30) [ 7365.865580] CPU: 42 PID: 110038 Comm: bash Tainted: G O 4.19.36-vhulk1907.1.0.h628.eulerosv2r8.aarch64 #1 [ 7365.876398] Hardware name: Huawei TaiShan 2280 V2/BC82AMDD, BIOS 1.05 09/18/2019 [ 7365.883758] pstate: 60400089 (nZCv daIf +PAN -UAO) [ 7365.888529] pc : aer_inj_read_config+0xc4/0x1a0 [aer_inject] [ 7365.894163] lr : (null) [ 7365.897462] sp : ffff000036ad37c0 [ 7365.900761] x29: ffff000036ad37c0 x28: 0000000000000001 [ 7365.906049] x27: 0000000000000001 x26: 0000000000000004 [ 7365.911338] x25: ffff000000a29000 x24: ffff000036ad3864 [ 7365.916625] x23: 0000000000000000 x22: 0000000000000000 [ 7365.921912] x21: 0000000000000080 x20: ffffa02fd7c34800 [ 7365.927201] x19: ffff000000a29020 x18: ffffffffffffffff [ 7365.932488] x17: 0000000000000000 x16: 0000000000000000 [ 7365.937775] x15: ffff0000091d9708 x14: 6963702f302e3030 [ 7365.943064] x13: 0000000000000040 x12: 0000000000000228 [ 7365.948352] x11: 0000000000000000 x10: 0000000000000000 [ 7365.953639] x9 : 0000000000000000 x8 : ffff802fd8998000 [ 7365.958926] x7 : ffff8027df40f200 x6 : 0000000000000001 [ 7365.964213] x5 : ffff000000a26128 x4 : ffff000036ad3864 [ 7365.969501] x3 : 0000000000000004 x2 : 0000000000000000 [ 7365.974788] x1 : 0000000000000000 x0 : 0000000000000000 [ 7365.980076] Call trace: [ 7365.982514] aer_inj_read_config+0xc4/0x1a0 [aer_inject] [ 7365.987805] pci_bus_read_config_dword+0xb0/0x120 [ 7365.992488] pci_bus_generic_read_dev_vendor_id+0xcc/0x2e0 [ 7365.997949] pci_bus_read_dev_vendor_id+0x58/0x98 [ 7366.002631] pci_scan_single_device+0x8c/0x110 [ 7366.007054] pci_scan_slot+0x40/0x110 [ 7366.010700] pci_scan_child_bus_extend+0x60/0x358 [ 7366.015383] pci_scan_child_bus+0x24/0x30 [ 7366.019375] pci_scan_bridge_extend+0x278/0x518 [ 7366.023886] pci_scan_child_bus_extend+0x158/0x358 [ 7366.028654] pci_scan_child_bus+0x24/0x30 [ 7366.032646] pci_scan_bridge_extend+0x278/0x518 [ 7366.037155] pci_scan_child_bus_extend+0x158/0x358 [ 7366.041923] pci_rescan_bus+0x24/0x48 [ 7366.045568] bus_rescan_store+0x8c/0xb0 [ 7366.049389] bus_attr_store+0x40/0x58 [ 7366.053036] sysfs_kf_write+0x58/0x80 [ 7366.056682] kernfs_fop_write+0xe8/0x1f0 [ 7366.060588] __vfs_write+0x60/0x190 [ 7366.064061] vfs_write+0xac/0x1c0 [ 7366.067361] ksys_write+0x6c/0xd8 [ 7366.070661] __arm64_sys_write+0x24/0x30 [ 7366.074568] el0_svc_common+0x78/0x130 [ 7366.078301] el0_svc_handler+0x38/0x78 [ 7366.082033] el0_svc+0x8/0xc [ 7366.084902] Code: f9007280 2a1603e1 aa1803e4 2a1a03e3 (f9400c05)
When we use 'aer-inject' to inject AER error into a PCI device. The 'pci_ops' of the 'pci_bus' of the device is changed to 'aer_inj_pci_ops'. When we remove the device and rescan the PCI tree, the 'pci_ops' of the newly allocced 'pci_bus' is also assign as 'aer_inj_pci_ops'. When we access the configuration space under the newly allocced 'pci_bus' and the register we want to access is not an AER register, kernel will try to find the original 'pci_ops',rather than 'aer_inj_pci_ops, and call 'pci_ops->write/read'. For the newly allocced 'pci_bus', we can not find the original 'pci_ops', so an Oops happened. This patch add a check for 'pci_ops' before we access its member.
Signed-off-by: Keith Busch keith.busch@intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/pci/pcie/aer_inject.c | 66 +++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 28 deletions(-)
diff --git a/drivers/pci/pcie/aer_inject.c b/drivers/pci/pcie/aer_inject.c index 0eb2434..48024a8 100644 --- a/drivers/pci/pcie/aer_inject.c +++ b/drivers/pci/pcie/aer_inject.c @@ -175,14 +175,48 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where, return target; }
+static int aer_inj_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *val) +{ + struct pci_ops *ops, *my_ops; + int rv; + + ops = __find_pci_bus_ops(bus); + if (!ops) + return -1; + + my_ops = bus->ops; + bus->ops = ops; + rv = ops->read(bus, devfn, where, size, val); + bus->ops = my_ops; + + return rv; +} + +static int aer_inj_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + struct pci_ops *ops, *my_ops; + int rv; + + ops = __find_pci_bus_ops(bus); + if (!ops) + return -1; + + my_ops = bus->ops; + bus->ops = ops; + rv = ops->write(bus, devfn, where, size, val); + bus->ops = my_ops; + + return rv; +} + static int aer_inj_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { u32 *sim; struct aer_error *err; unsigned long flags; - struct pci_ops *ops; - struct pci_ops *my_ops; int domain; int rv;
@@ -203,18 +237,7 @@ static int aer_inj_read_config(struct pci_bus *bus, unsigned int devfn, return 0; } out: - ops = __find_pci_bus_ops(bus); - /* - * pci_lock must already be held, so we can directly - * manipulate bus->ops. Many config access functions, - * including pci_generic_config_read() require the original - * bus->ops be installed to function, so temporarily put them - * back. - */ - my_ops = bus->ops; - bus->ops = ops; - rv = ops->read(bus, devfn, where, size, val); - bus->ops = my_ops; + rv = aer_inj_read(bus, devfn, where, size, val); spin_unlock_irqrestore(&inject_lock, flags); return rv; } @@ -226,8 +249,6 @@ static int aer_inj_write_config(struct pci_bus *bus, unsigned int devfn, struct aer_error *err; unsigned long flags; int rw1cs; - struct pci_ops *ops; - struct pci_ops *my_ops; int domain; int rv;
@@ -251,18 +272,7 @@ static int aer_inj_write_config(struct pci_bus *bus, unsigned int devfn, return 0; } out: - ops = __find_pci_bus_ops(bus); - /* - * pci_lock must already be held, so we can directly - * manipulate bus->ops. Many config access functions, - * including pci_generic_config_write() require the original - * bus->ops be installed to function, so temporarily put them - * back. - */ - my_ops = bus->ops; - bus->ops = ops; - rv = ops->write(bus, devfn, where, size, val); - bus->ops = my_ops; + rv = aer_inj_write(bus, devfn, where, size, val); spin_unlock_irqrestore(&inject_lock, flags); return rv; }
From: Dedy Lansky dlansky@codeaurora.org
mainline inclusion from mainline-v4.20-rc1 commit 30ca1aa536211f5ac3de0173513a7a99a98a97f3 category: bugfix bugzilla: 13690 CVE: CVE-2019-5108
This patch is prepare for fixing CVE-2019-5108
-------------------------------------------------
Make ieee80211_send_layer2_update() a common function so other drivers can re-use it.
Signed-off-by: Dedy Lansky dlansky@codeaurora.org Signed-off-by: Johannes Berg johannes.berg@intel.com Conflicts: net/wireless/util.c [yyl: adjust context]
Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Wenan Mao maowenan@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/net/cfg80211.h | 11 +++++++++++ net/mac80211/cfg.c | 48 ++---------------------------------------------- net/wireless/util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 46 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 468deae..1fa2e72 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4734,6 +4734,17 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type, const u8 *ies, int len);
/** + * cfg80211_send_layer2_update - send layer 2 update frame + * + * @dev: network device + * @addr: STA MAC address + * + * Wireless drivers can use this function to update forwarding tables in bridge + * devices upon STA association. + */ +void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr); + +/** * DOC: Regulatory enforcement infrastructure * * TODO diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a48e83b..5ebca14 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1096,50 +1096,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) return 0; }
-/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ -struct iapp_layer2_update { - u8 da[ETH_ALEN]; /* broadcast */ - u8 sa[ETH_ALEN]; /* STA addr */ - __be16 len; /* 6 */ - u8 dsap; /* 0 */ - u8 ssap; /* 0 */ - u8 control; - u8 xid_info[3]; -} __packed; - -static void ieee80211_send_layer2_update(struct sta_info *sta) -{ - struct iapp_layer2_update *msg; - struct sk_buff *skb; - - /* Send Level 2 Update Frame to update forwarding tables in layer 2 - * bridge devices */ - - skb = dev_alloc_skb(sizeof(*msg)); - if (!skb) - return; - msg = skb_put(skb, sizeof(*msg)); - - /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) - * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ - - eth_broadcast_addr(msg->da); - memcpy(msg->sa, sta->sta.addr, ETH_ALEN); - msg->len = htons(6); - msg->dsap = 0; - msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ - msg->control = 0xaf; /* XID response lsb.1111F101. - * F=0 (no poll command; unsolicited frame) */ - msg->xid_info[0] = 0x81; /* XID format identifier */ - msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ - msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ - - skb->dev = sta->sdata->dev; - skb->protocol = eth_type_trans(skb, sta->sdata->dev); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx_ni(skb); -} - static int sta_apply_auth_flags(struct ieee80211_local *local, struct sta_info *sta, u32 mask, u32 set) @@ -1508,7 +1464,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, }
if (layer2_update) - ieee80211_send_layer2_update(sta); + cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
rcu_read_unlock();
@@ -1610,7 +1566,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) ieee80211_vif_inc_num_mcast(sta->sdata);
- ieee80211_send_layer2_update(sta); + cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr); }
err = sta_apply_parameters(local, sta, params); diff --git a/net/wireless/util.c b/net/wireless/util.c index d641d81..e5f7db2 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1897,6 +1897,51 @@ int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp) { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; EXPORT_SYMBOL(bridge_tunnel_header);
+/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ +struct iapp_layer2_update { + u8 da[ETH_ALEN]; /* broadcast */ + u8 sa[ETH_ALEN]; /* STA addr */ + __be16 len; /* 6 */ + u8 dsap; /* 0 */ + u8 ssap; /* 0 */ + u8 control; + u8 xid_info[3]; +} __packed; + +void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr) +{ + struct iapp_layer2_update *msg; + struct sk_buff *skb; + + /* Send Level 2 Update Frame to update forwarding tables in layer 2 + * bridge devices */ + + skb = dev_alloc_skb(sizeof(*msg)); + if (!skb) + return; + msg = skb_put(skb, sizeof(*msg)); + + /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) + * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ + + eth_broadcast_addr(msg->da); + ether_addr_copy(msg->sa, addr); + msg->len = htons(6); + msg->dsap = 0; + msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ + msg->control = 0xaf; /* XID response lsb.1111F101. + * F=0 (no poll command; unsolicited frame) */ + msg->xid_info[0] = 0x81; /* XID format identifier */ + msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ + msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ + + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx_ni(skb); +} +EXPORT_SYMBOL(cfg80211_send_layer2_update); + bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype, bool is_4addr, u8 check_swif)
From: Jouni Malinen jouni@codeaurora.org
mainline inclusion from mainline-v5.3 commit 3e493173b7841259a08c5c8e5cbe90adb349da7e category: bugfix bugzilla: 13690 CVE: CVE-2019-5108
-------------------------------------------------
The Layer 2 Update frame is used to update bridges when a station roams to another AP even if that STA does not transmit any frames after the reassociation. This behavior was described in IEEE Std 802.11F-2003 as something that would happen based on MLME-ASSOCIATE.indication, i.e., before completing 4-way handshake. However, this IEEE trial-use recommended practice document was published before RSN (IEEE Std 802.11i-2004) and as such, did not consider RSN use cases. Furthermore, IEEE Std 802.11F-2003 was withdrawn in 2006 and as such, has not been maintained amd should not be used anymore.
Sending out the Layer 2 Update frame immediately after association is fine for open networks (and also when using SAE, FT protocol, or FILS authentication when the station is actually authenticated by the time association completes). However, it is not appropriate for cases where RSN is used with PSK or EAP authentication since the station is actually fully authenticated only once the 4-way handshake completes after authentication and attackers might be able to use the unauthenticated triggering of Layer 2 Update frame transmission to disrupt bridge behavior.
Fix this by postponing transmission of the Layer 2 Update frame from station entry addition to the point when the station entry is marked authorized. Similarly, send out the VLAN binding update only if the STA entry has already been authorized.
Signed-off-by: Jouni Malinen jouni@codeaurora.org Reviewed-by: Johannes Berg johannes@sipsolutions.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Wenan Mao maowenan@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- net/mac80211/cfg.c | 14 ++++---------- net/mac80211/sta_info.c | 4 ++++ 2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5ebca14..e469445 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1410,7 +1410,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, struct sta_info *sta; struct ieee80211_sub_if_data *sdata; int err; - int layer2_update;
if (params->vlan) { sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); @@ -1454,18 +1453,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, test_sta_flag(sta, WLAN_STA_ASSOC)) rate_control_rate_init(sta);
- layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || - sdata->vif.type == NL80211_IFTYPE_AP; - err = sta_info_insert_rcu(sta); if (err) { rcu_read_unlock(); return err; }
- if (layer2_update) - cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr); - rcu_read_unlock();
return 0; @@ -1563,10 +1556,11 @@ static int ieee80211_change_station(struct wiphy *wiphy, sta->sdata = vlansdata; ieee80211_check_fast_xmit(sta);
- if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) + if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) { ieee80211_vif_inc_num_mcast(sta->sdata); - - cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr); + cfg80211_send_layer2_update(sta->sdata->dev, + sta->sta.addr); + } }
err = sta_apply_parameters(local, sta, params); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 507409e..0c80a59 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1906,6 +1906,10 @@ int sta_info_move_state(struct sta_info *sta, ieee80211_check_fast_xmit(sta); ieee80211_check_fast_rx(sta); } + if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN || + sta->sdata->vif.type == NL80211_IFTYPE_AP) + cfg80211_send_layer2_update(sta->sdata->dev, + sta->sta.addr); break; default: break;
From: Jaegeuk Kim jaegeuk@kernel.org
mainline inclusion from mainline-v5.3-rc1 commit 4969c06a0d83c9c3dc50b8efcdc8eeedfce896f6 category: bugfix bugzilla: 13690 CVE: CVE-2019-19815
-------------------------------------------------
Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Conflicts: fs/f2fs/f2fs.h fs/f2fs/data.c [yyl: adjust context]
Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Wei Fang fangwei1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/f2fs/data.c | 140 +++++++++++++++++++++++++++++++++++++++++--- fs/f2fs/f2fs.h | 2 +- include/trace/events/f2fs.h | 11 ++-- 3 files changed, 140 insertions(+), 13 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a7436ad..44e8355 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -17,6 +17,7 @@ #include <linux/pagevec.h> #include <linux/blkdev.h> #include <linux/bio.h> +#include <linux/swap.h> #include <linux/prefetch.h> #include <linux/uio.h> #include <linux/cleancache.h> @@ -1496,12 +1497,12 @@ static int f2fs_mpage_readpages(struct address_space *mapping, prefetchw(&page->flags); list_del(&page->lru); if (add_to_page_cache_lru(page, mapping, - page->index, + page_index(page), readahead_gfp_mask(mapping))) goto next_page; }
- block_in_file = (sector_t)page->index; + block_in_file = (sector_t)page_index(page); last_block = block_in_file + nr_pages; last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits; @@ -1535,7 +1536,8 @@ static int f2fs_mpage_readpages(struct address_space *mapping, block_nr = map.m_pblk + block_in_file - map.m_lblk; SetPageMappedToDisk(page);
- if (!PageUptodate(page) && !cleancache_get_page(page)) { + if (!PageUptodate(page) && (!PageSwapCache(page) && + !cleancache_get_page(page))) { SetPageUptodate(page); goto confused; } @@ -1605,7 +1607,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
static int f2fs_read_data_page(struct file *file, struct page *page) { - struct inode *inode = page->mapping->host; + struct inode *inode = page_file_mapping(page)->host; int ret = -EAGAIN;
trace_f2fs_readpage(page, DATA); @@ -1614,7 +1616,8 @@ static int f2fs_read_data_page(struct file *file, struct page *page) if (f2fs_has_inline_data(inode)) ret = f2fs_read_inline_data(inode, page); if (ret == -EAGAIN) - ret = f2fs_mpage_readpages(page->mapping, NULL, page, 1, false); + ret = f2fs_mpage_readpages(page_file_mapping(page), + NULL, page, 1, false); return ret; }
@@ -2604,13 +2607,14 @@ int f2fs_release_page(struct page *page, gfp_t wait)
static int f2fs_set_data_page_dirty(struct page *page) { - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; + struct inode *inode = page_file_mapping(page)->host;
trace_f2fs_set_page_dirty(page, DATA);
if (!PageUptodate(page)) SetPageUptodate(page); + if (PageSwapCache(page)) + return __set_page_dirty_nobuffers(page);
if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) { if (!IS_ATOMIC_WRITTEN_PAGE(page)) { @@ -2705,6 +2709,126 @@ int f2fs_migrate_page(struct address_space *mapping, } #endif
+#ifdef CONFIG_SWAP +/* Copied from generic_swapfile_activate() to check any holes */ +static int check_swap_activate(struct file *swap_file, unsigned int max) +{ + struct address_space *mapping = swap_file->f_mapping; + struct inode *inode = mapping->host; + unsigned blocks_per_page; + unsigned long page_no; + unsigned blkbits; + sector_t probe_block; + sector_t last_block; + sector_t lowest_block = -1; + sector_t highest_block = 0; + + blkbits = inode->i_blkbits; + blocks_per_page = PAGE_SIZE >> blkbits; + + /* + * Map all the blocks into the extent list. This code doesn't try + * to be very smart. + */ + probe_block = 0; + page_no = 0; + last_block = i_size_read(inode) >> blkbits; + while ((probe_block + blocks_per_page) <= last_block && page_no < max) { + unsigned block_in_page; + sector_t first_block; + + cond_resched(); + + first_block = bmap(inode, probe_block); + if (first_block == 0) + goto bad_bmap; + + /* + * It must be PAGE_SIZE aligned on-disk + */ + if (first_block & (blocks_per_page - 1)) { + probe_block++; + goto reprobe; + } + + for (block_in_page = 1; block_in_page < blocks_per_page; + block_in_page++) { + sector_t block; + + block = bmap(inode, probe_block + block_in_page); + if (block == 0) + goto bad_bmap; + if (block != first_block + block_in_page) { + /* Discontiguity */ + probe_block++; + goto reprobe; + } + } + + first_block >>= (PAGE_SHIFT - blkbits); + if (page_no) { /* exclude the header page */ + if (first_block < lowest_block) + lowest_block = first_block; + if (first_block > highest_block) + highest_block = first_block; + } + + page_no++; + probe_block += blocks_per_page; +reprobe: + continue; + } + return 0; + +bad_bmap: + pr_err("swapon: swapfile has holes\n"); + return -EINVAL; +} + +static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, + sector_t *span) +{ + struct inode *inode = file_inode(file); + int ret; + + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + if (f2fs_readonly(F2FS_I_SB(inode)->sb)) + return -EROFS; + + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; + + ret = check_swap_activate(file, sis->max); + if (ret) + return ret; + + set_inode_flag(inode, FI_PIN_FILE); + f2fs_precache_extents(inode); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); + return 0; +} + +static void f2fs_swap_deactivate(struct file *file) +{ + struct inode *inode = file_inode(file); + + clear_inode_flag(inode, FI_PIN_FILE); +} +#else +static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, + sector_t *span) +{ + return -EOPNOTSUPP; +} + +static void f2fs_swap_deactivate(struct file *file) +{ +} +#endif + const struct address_space_operations f2fs_dblock_aops = { .readpage = f2fs_read_data_page, .readpages = f2fs_read_data_pages, @@ -2717,6 +2841,8 @@ int f2fs_migrate_page(struct address_space *mapping, .releasepage = f2fs_release_page, .direct_IO = f2fs_direct_IO, .bmap = f2fs_bmap, + .swap_activate = f2fs_swap_activate, + .swap_deactivate = f2fs_swap_deactivate, #ifdef CONFIG_MIGRATION .migratepage = f2fs_migrate_page, #endif diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 72d154e71..8cbc9da 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1443,7 +1443,7 @@ static inline struct f2fs_sb_info *F2FS_M_SB(struct address_space *mapping)
static inline struct f2fs_sb_info *F2FS_P_SB(struct page *page) { - return F2FS_M_SB(page->mapping); + return F2FS_M_SB(page_file_mapping(page)); }
static inline struct f2fs_super_block *F2FS_RAW_SUPER(struct f2fs_sb_info *sbi) diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 7956989..347af84 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -977,8 +977,8 @@ ),
TP_fast_assign( - __entry->dev = page->mapping->host->i_sb->s_dev; - __entry->ino = page->mapping->host->i_ino; + __entry->dev = page_file_mapping(page)->host->i_sb->s_dev; + __entry->ino = page_file_mapping(page)->host->i_ino; __entry->index = page->index; __entry->old_blkaddr = fio->old_blkaddr; __entry->new_blkaddr = fio->new_blkaddr; @@ -1165,10 +1165,11 @@ ),
TP_fast_assign( - __entry->dev = page->mapping->host->i_sb->s_dev; - __entry->ino = page->mapping->host->i_ino; + __entry->dev = page_file_mapping(page)->host->i_sb->s_dev; + __entry->ino = page_file_mapping(page)->host->i_ino; __entry->type = type; - __entry->dir = S_ISDIR(page->mapping->host->i_mode); + __entry->dir = + S_ISDIR(page_file_mapping(page)->host->i_mode); __entry->index = page->index; __entry->dirty = PageDirty(page); __entry->uptodate = PageUptodate(page);