Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from David Miller:

 1) Fix memory leak in vti6, from Torsten Hilbrich.

 2) Fix double free in xfrm_policy_timer, from YueHaibing.

 3) NL80211_ATTR_CHANNEL_WIDTH attribute is put with wrong type, from
    Johannes Berg.

 4) Wrong allocation failure check in qlcnic driver, from Xu Wang.

 5) Get ks8851-ml IO operations right, for real this time, from Marek
    Vasut.

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (22 commits)
  r8169: fix PHY driver check on platforms w/o module softdeps
  net: ks8851-ml: Fix IO operations, again
  mlxsw: spectrum_mr: Fix list iteration in error path
  qlcnic: Fix bad kzalloc null test
  mac80211: set IEEE80211_TX_CTRL_PORT_CTRL_PROTO for nl80211 TX
  mac80211: mark station unauthorized before key removal
  mac80211: Check port authorization in the ieee80211_tx_dequeue() case
  cfg80211: Do not warn on same channel at the end of CSA
  mac80211: drop data frames without key on encrypted links
  ieee80211: fix HE SPR size calculation
  nl80211: fix NL80211_ATTR_CHANNEL_WIDTH attribute type
  xfrm: policy: Fix doulbe free in xfrm_policy_timer
  bpf: Explicitly memset some bpf info structures declared on the stack
  bpf: Explicitly memset the bpf_attr structure
  bpf: Sanitize the bpf_struct_ops tcp-cc name
  vti6: Fix memory leak of skb if input policy check fails
  esp: remove the skb from the chain when it's enqueued in cryptd_wq
  ipv6: xfrm6_tunnel.c: Use built-in RCU list checking
  xfrm: add the missing verify_sec_ctx_len check in xfrm_add_acquire
  xfrm: fix uctx len check in verify_sec_ctx_len
  ...
This commit is contained in:
Linus Torvalds 2020-03-28 18:55:15 -07:00
commit e595dd9451
23 changed files with 220 additions and 79 deletions

View File

@ -637,12 +637,12 @@ static int mlxsw_sp_mr_vif_resolve(struct mlxsw_sp_mr_table *mr_table,
return 0;
err_erif_unresolve:
list_for_each_entry_from_reverse(erve, &mr_vif->route_evif_list,
vif_node)
list_for_each_entry_continue_reverse(erve, &mr_vif->route_evif_list,
vif_node)
mlxsw_sp_mr_route_evif_unresolve(mr_table, erve);
err_irif_unresolve:
list_for_each_entry_from_reverse(irve, &mr_vif->route_ivif_list,
vif_node)
list_for_each_entry_continue_reverse(irve, &mr_vif->route_ivif_list,
vif_node)
mlxsw_sp_mr_route_ivif_unresolve(mr_table, irve);
mr_vif->rif = NULL;
return err;

View File

@ -156,6 +156,50 @@ static int msg_enable;
* chip is busy transferring packet data (RX/TX FIFO accesses).
*/
/**
* ks_check_endian - Check whether endianness of the bus is correct
* @ks : The chip information
*
* The KS8851-16MLL EESK pin allows selecting the endianness of the 16bit
* bus. To maintain optimum performance, the bus endianness should be set
* such that it matches the endianness of the CPU.
*/
static int ks_check_endian(struct ks_net *ks)
{
u16 cider;
/*
* Read CIDER register first, however read it the "wrong" way around.
* If the endian strap on the KS8851-16MLL in incorrect and the chip
* is operating in different endianness than the CPU, then the meaning
* of BE[3:0] byte-enable bits is also swapped such that:
* BE[3,2,1,0] becomes BE[1,0,3,2]
*
* Luckily for us, the byte-enable bits are the top four MSbits of
* the address register and the CIDER register is at offset 0xc0.
* Hence, by reading address 0xc0c0, which is not impacted by endian
* swapping, we assert either BE[3:2] or BE[1:0] while reading the
* CIDER register.
*
* If the bus configuration is correct, reading 0xc0c0 asserts
* BE[3:2] and this read returns 0x0000, because to read register
* with bottom two LSbits of address set to 0, BE[1:0] must be
* asserted.
*
* If the bus configuration is NOT correct, reading 0xc0c0 asserts
* BE[1:0] and this read returns non-zero 0x8872 value.
*/
iowrite16(BE3 | BE2 | KS_CIDER, ks->hw_addr_cmd);
cider = ioread16(ks->hw_addr);
if (!cider)
return 0;
netdev_err(ks->netdev, "incorrect EESK endian strap setting\n");
return -EINVAL;
}
/**
* ks_rdreg16 - read 16 bit register from device
* @ks : The chip information
@ -166,7 +210,7 @@ static int msg_enable;
static u16 ks_rdreg16(struct ks_net *ks, int offset)
{
ks->cmd_reg_cache = (u16)offset | ((BE3 | BE2) >> (offset & 0x02));
ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
return ioread16(ks->hw_addr);
}
@ -181,7 +225,7 @@ static u16 ks_rdreg16(struct ks_net *ks, int offset)
static void ks_wrreg16(struct ks_net *ks, int offset, u16 value)
{
ks->cmd_reg_cache = (u16)offset | ((BE3 | BE2) >> (offset & 0x02));
ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
iowrite16(value, ks->hw_addr);
}
@ -197,7 +241,7 @@ static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len)
{
len >>= 1;
while (len--)
*wptr++ = be16_to_cpu(ioread16(ks->hw_addr));
*wptr++ = (u16)ioread16(ks->hw_addr);
}
/**
@ -211,7 +255,7 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
{
len >>= 1;
while (len--)
iowrite16(cpu_to_be16(*wptr++), ks->hw_addr);
iowrite16(*wptr++, ks->hw_addr);
}
static void ks_disable_int(struct ks_net *ks)
@ -1218,6 +1262,10 @@ static int ks8851_probe(struct platform_device *pdev)
goto err_free;
}
err = ks_check_endian(ks);
if (err)
goto err_free;
netdev->irq = platform_get_irq(pdev, 0);
if ((int)netdev->irq < 0) {

View File

@ -1720,7 +1720,7 @@ static int qlcnic_83xx_get_reset_instruction_template(struct qlcnic_adapter *p_d
ahw->reset.seq_error = 0;
ahw->reset.buff = kzalloc(QLC_83XX_RESTART_TEMPLATE_SIZE, GFP_KERNEL);
if (p_dev->ahw->reset.buff == NULL)
if (ahw->reset.buff == NULL)
return -ENOMEM;
p_buff = p_dev->ahw->reset.buff;

View File

@ -5285,6 +5285,13 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
if (!tp->phydev) {
mdiobus_unregister(new_bus);
return -ENODEV;
} else if (!tp->phydev->drv) {
/* Most chip versions fail with the genphy driver.
* Therefore ensure that the dedicated PHY driver is loaded.
*/
dev_err(&pdev->dev, "realtek.ko not loaded, maybe it needs to be added to initramfs?\n");
mdiobus_unregister(new_bus);
return -EUNATCH;
}
/* PHY will be woken up in rtl_open() */
@ -5446,15 +5453,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
int chipset, region;
int jumbo_max, rc;
/* Some tools for creating an initramfs don't consider softdeps, then
* r8169.ko may be in initramfs, but realtek.ko not. Then the generic
* PHY driver is used that doesn't work with most chip versions.
*/
if (!driver_find("RTL8201CP Ethernet", &mdio_bus_type)) {
dev_err(&pdev->dev, "realtek.ko not loaded, maybe it needs to be added to initramfs?\n");
return -ENOENT;
}
dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
if (!dev)
return -ENOMEM;

View File

@ -160,6 +160,7 @@ static inline void copy_map_value(struct bpf_map *map, void *dst, void *src)
}
void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
bool lock_src);
int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size);
struct bpf_offload_dev;
struct bpf_offloaded_map;

View File

@ -2102,14 +2102,14 @@ ieee80211_he_spr_size(const u8 *he_spr_ie)
{
struct ieee80211_he_spr *he_spr = (void *)he_spr_ie;
u8 spr_len = sizeof(struct ieee80211_he_spr);
u32 he_spr_params;
u8 he_spr_params;
/* Make sure the input is not NULL */
if (!he_spr_ie)
return 0;
/* Calc required length */
he_spr_params = le32_to_cpu(he_spr->he_sr_control);
he_spr_params = he_spr->he_sr_control;
if (he_spr_params & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
spr_len++;
if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT)

View File

@ -4564,7 +4564,7 @@ int btf_get_info_by_fd(const struct btf *btf,
union bpf_attr __user *uattr)
{
struct bpf_btf_info __user *uinfo;
struct bpf_btf_info info = {};
struct bpf_btf_info info;
u32 info_copy, btf_copy;
void __user *ubtf;
u32 uinfo_len;
@ -4573,6 +4573,7 @@ int btf_get_info_by_fd(const struct btf *btf,
uinfo_len = attr->info.info_len;
info_copy = min_t(u32, uinfo_len, sizeof(info));
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, uinfo, info_copy))
return -EFAULT;

View File

@ -696,14 +696,15 @@ int bpf_get_file_flag(int flags)
offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
sizeof(attr->CMD##_LAST_FIELD)) != NULL
/* dst and src must have at least BPF_OBJ_NAME_LEN number of bytes.
* Return 0 on success and < 0 on error.
/* dst and src must have at least "size" number of bytes.
* Return strlen on success and < 0 on error.
*/
static int bpf_obj_name_cpy(char *dst, const char *src)
int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size)
{
const char *end = src + BPF_OBJ_NAME_LEN;
const char *end = src + size;
const char *orig_src = src;
memset(dst, 0, BPF_OBJ_NAME_LEN);
memset(dst, 0, size);
/* Copy all isalnum(), '_' and '.' chars. */
while (src < end && *src) {
if (!isalnum(*src) &&
@ -712,11 +713,11 @@ static int bpf_obj_name_cpy(char *dst, const char *src)
*dst++ = *src++;
}
/* No '\0' found in BPF_OBJ_NAME_LEN number of bytes */
/* No '\0' found in "size" number of bytes */
if (src == end)
return -EINVAL;
return 0;
return src - orig_src;
}
int map_check_no_btf(const struct bpf_map *map,
@ -810,8 +811,9 @@ static int map_create(union bpf_attr *attr)
if (IS_ERR(map))
return PTR_ERR(map);
err = bpf_obj_name_cpy(map->name, attr->map_name);
if (err)
err = bpf_obj_name_cpy(map->name, attr->map_name,
sizeof(attr->map_name));
if (err < 0)
goto free_map;
atomic64_set(&map->refcnt, 1);
@ -2098,8 +2100,9 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
goto free_prog;
prog->aux->load_time = ktime_get_boottime_ns();
err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name);
if (err)
err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
sizeof(attr->prog_name));
if (err < 0)
goto free_prog;
/* run eBPF verifier */
@ -2792,7 +2795,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
union bpf_attr __user *uattr)
{
struct bpf_prog_info __user *uinfo = u64_to_user_ptr(attr->info.info);
struct bpf_prog_info info = {};
struct bpf_prog_info info;
u32 info_len = attr->info.info_len;
struct bpf_prog_stats stats;
char __user *uinsns;
@ -2804,6 +2807,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
return err;
info_len = min_t(u32, sizeof(info), info_len);
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, uinfo, info_len))
return -EFAULT;
@ -3067,7 +3071,7 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
union bpf_attr __user *uattr)
{
struct bpf_map_info __user *uinfo = u64_to_user_ptr(attr->info.info);
struct bpf_map_info info = {};
struct bpf_map_info info;
u32 info_len = attr->info.info_len;
int err;
@ -3076,6 +3080,7 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
return err;
info_len = min_t(u32, sizeof(info), info_len);
memset(&info, 0, sizeof(info));
info.type = map->map_type;
info.id = map->id;
info.key_size = map->key_size;
@ -3359,7 +3364,7 @@ err_put:
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
{
union bpf_attr attr = {};
union bpf_attr attr;
int err;
if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
@ -3371,6 +3376,7 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
size = min_t(u32, size, sizeof(attr));
/* copy attributes from user space, may be less than sizeof(bpf_attr) */
memset(&attr, 0, sizeof(attr));
if (copy_from_user(&attr, uattr, size) != 0)
return -EFAULT;

View File

@ -303,6 +303,7 @@ config SYN_COOKIES
config NET_IPVTI
tristate "Virtual (secure) IP: tunneling"
depends on IPV6 || IPV6=n
select INET_TUNNEL
select NET_IP_TUNNEL
select XFRM

View File

@ -184,7 +184,6 @@ static int bpf_tcp_ca_init_member(const struct btf_type *t,
{
const struct tcp_congestion_ops *utcp_ca;
struct tcp_congestion_ops *tcp_ca;
size_t tcp_ca_name_len;
int prog_fd;
u32 moff;
@ -199,13 +198,11 @@ static int bpf_tcp_ca_init_member(const struct btf_type *t,
tcp_ca->flags = utcp_ca->flags;
return 1;
case offsetof(struct tcp_congestion_ops, name):
tcp_ca_name_len = strnlen(utcp_ca->name, sizeof(utcp_ca->name));
if (!tcp_ca_name_len ||
tcp_ca_name_len == sizeof(utcp_ca->name))
if (bpf_obj_name_cpy(tcp_ca->name, utcp_ca->name,
sizeof(tcp_ca->name)) <= 0)
return -EINVAL;
if (tcp_ca_find(utcp_ca->name))
return -EEXIST;
memcpy(tcp_ca->name, utcp_ca->name, sizeof(tcp_ca->name));
return 1;
}

View File

@ -187,17 +187,39 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
int mtu;
if (!dst) {
struct rtable *rt;
switch (skb->protocol) {
case htons(ETH_P_IP): {
struct rtable *rt;
fl->u.ip4.flowi4_oif = dev->ifindex;
fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
if (IS_ERR(rt)) {
fl->u.ip4.flowi4_oif = dev->ifindex;
fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
if (IS_ERR(rt)) {
dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
dst = &rt->dst;
skb_dst_set(skb, dst);
break;
}
#if IS_ENABLED(CONFIG_IPV6)
case htons(ETH_P_IPV6):
fl->u.ip6.flowi6_oif = dev->ifindex;
fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
if (dst->error) {
dst_release(dst);
dst = NULL;
dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
skb_dst_set(skb, dst);
break;
#endif
default:
dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
dst = &rt->dst;
skb_dst_set(skb, dst);
}
dst_hold(dst);

View File

@ -311,7 +311,7 @@ static int vti6_rcv(struct sk_buff *skb)
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
rcu_read_unlock();
return 0;
goto discard;
}
ipv6h = ipv6_hdr(skb);
@ -450,15 +450,33 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
int mtu;
if (!dst) {
fl->u.ip6.flowi6_oif = dev->ifindex;
fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
if (dst->error) {
dst_release(dst);
dst = NULL;
switch (skb->protocol) {
case htons(ETH_P_IP): {
struct rtable *rt;
fl->u.ip4.flowi4_oif = dev->ifindex;
fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
if (IS_ERR(rt))
goto tx_err_link_failure;
dst = &rt->dst;
skb_dst_set(skb, dst);
break;
}
case htons(ETH_P_IPV6):
fl->u.ip6.flowi6_oif = dev->ifindex;
fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
if (dst->error) {
dst_release(dst);
dst = NULL;
goto tx_err_link_failure;
}
skb_dst_set(skb, dst);
break;
default:
goto tx_err_link_failure;
}
skb_dst_set(skb, dst);
}
dst_hold(dst);

View File

@ -78,7 +78,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, const
hlist_for_each_entry_rcu(x6spi,
&xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
list_byaddr) {
list_byaddr, lockdep_is_held(&xfrm6_tunnel_spi_lock)) {
if (xfrm6_addr_equal(&x6spi->addr, saddr))
return x6spi;
}

View File

@ -5,7 +5,7 @@
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
* Copyright (C) 2018 - 2019 Intel Corporation
* Copyright (C) 2018 - 2020 Intel Corporation
*/
#include <linux/debugfs.h>
@ -78,6 +78,7 @@ static const char * const sta_flag_names[] = {
FLAG(MPSP_OWNER),
FLAG(MPSP_RECIPIENT),
FLAG(PS_DELIVER),
FLAG(USES_ENCRYPTION),
#undef FLAG
};

View File

@ -6,7 +6,7 @@
* Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2015-2017 Intel Deutschland GmbH
* Copyright 2018-2019 Intel Corporation
* Copyright 2018-2020 Intel Corporation
*/
#include <linux/if_ether.h>
@ -262,22 +262,29 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
sta ? sta->sta.addr : bcast_addr, ret);
}
int ieee80211_set_tx_key(struct ieee80211_key *key)
static int _ieee80211_set_tx_key(struct ieee80211_key *key, bool force)
{
struct sta_info *sta = key->sta;
struct ieee80211_local *local = key->local;
assert_key_lock(local);
set_sta_flag(sta, WLAN_STA_USES_ENCRYPTION);
sta->ptk_idx = key->conf.keyidx;
if (!ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
if (force || !ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_check_fast_xmit(sta);
return 0;
}
int ieee80211_set_tx_key(struct ieee80211_key *key)
{
return _ieee80211_set_tx_key(key, false);
}
static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
struct ieee80211_key *new)
{
@ -441,11 +448,8 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
if (pairwise) {
rcu_assign_pointer(sta->ptk[idx], new);
if (new &&
!(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)) {
sta->ptk_idx = idx;
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_check_fast_xmit(sta);
}
!(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX))
_ieee80211_set_tx_key(new, true);
} else {
rcu_assign_pointer(sta->gtk[idx], new);
}

View File

@ -4,7 +4,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2019 Intel Corporation
* Copyright (C) 2018-2020 Intel Corporation
*/
#include <linux/module.h>
@ -1049,6 +1049,11 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
might_sleep();
lockdep_assert_held(&local->sta_mtx);
while (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
WARN_ON_ONCE(ret);
}
/* now keys can no longer be reached */
ieee80211_free_sta_keys(local, sta);

View File

@ -98,6 +98,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_MPSP_OWNER,
WLAN_STA_MPSP_RECIPIENT,
WLAN_STA_PS_DELIVER,
WLAN_STA_USES_ENCRYPTION,
NUM_WLAN_STA_FLAGS,
};

View File

@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018, 2020 Intel Corporation
*
* Transmit and frame generation functions.
*/
@ -590,10 +590,13 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
tx->key = NULL;
else if (tx->sta &&
(key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
return TX_CONTINUE;
}
if (tx->sta &&
(key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
tx->key = key;
else if (ieee80211_is_group_privacy_action(tx->skb) &&
(key = rcu_dereference(tx->sdata->default_multicast_key)))
@ -654,6 +657,9 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
if (!skip_hw && tx->key &&
tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
info->control.hw_key = &tx->key->conf;
} else if (!ieee80211_is_mgmt(hdr->frame_control) && tx->sta &&
test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) {
return TX_DROP;
}
return TX_CONTINUE;
@ -3598,8 +3604,25 @@ begin:
tx.skb = skb;
tx.sdata = vif_to_sdata(info->control.vif);
if (txq->sta)
if (txq->sta) {
tx.sta = container_of(txq->sta, struct sta_info, sta);
/*
* Drop unicast frames to unauthorised stations unless they are
* EAPOL frames from the local station.
*/
if (unlikely(!ieee80211_vif_is_mesh(&tx.sdata->vif) &&
tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
!is_multicast_ether_addr(hdr->addr1) &&
!test_sta_flag(tx.sta, WLAN_STA_AUTHORIZED) &&
(!(info->control.flags &
IEEE80211_TX_CTRL_PORT_CTRL_PROTO) ||
!ether_addr_equal(tx.sdata->vif.addr,
hdr->addr2)))) {
I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
ieee80211_free_txskb(&local->hw, skb);
goto begin;
}
}
/*
* The key can be removed while the packet was queued, so need to call
@ -5126,6 +5149,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ethhdr *ehdr;
u32 ctrl_flags = 0;
u32 flags;
/* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
@ -5135,6 +5159,9 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
proto != cpu_to_be16(ETH_P_PREAUTH))
return -EINVAL;
if (proto == sdata->control_port_protocol)
ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
if (unencrypted)
flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
else
@ -5160,7 +5187,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
skb_reset_mac_header(skb);
local_bh_disable();
__ieee80211_subif_start_xmit(skb, skb->dev, flags, 0);
__ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags);
local_bh_enable();
return 0;

View File

@ -16416,7 +16416,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
goto nla_put_failure;
if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
goto nla_put_failure;
if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&

View File

@ -2022,7 +2022,11 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
spin_lock_bh(&rdev->bss_lock);
if (WARN_ON(cbss->pub.channel == chan))
/*
* Some APs use CSA also for bandwidth changes, i.e., without actually
* changing the control channel, so no need to update in such a case.
*/
if (cbss->pub.channel == chan)
goto done;
/* use transmitting bss */

View File

@ -78,8 +78,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
int err;
unsigned long flags;
struct xfrm_state *x;
struct sk_buff *skb2, *nskb;
struct softnet_data *sd;
struct sk_buff *skb2, *nskb, *pskb = NULL;
netdev_features_t esp_features = features;
struct xfrm_offload *xo = xfrm_offload(skb);
struct sec_path *sp;
@ -168,14 +168,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
} else {
if (skb == skb2)
skb = nskb;
if (!skb)
return NULL;
else
pskb->next = nskb;
continue;
}
skb_push(skb2, skb2->data - skb_mac_header(skb2));
pskb = skb2;
}
return skb;
@ -383,6 +383,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
return xfrm_dev_feat_change(dev);
case NETDEV_DOWN:
case NETDEV_UNREGISTER:
return xfrm_dev_down(dev);
}
return NOTIFY_DONE;

View File

@ -434,7 +434,9 @@ EXPORT_SYMBOL(xfrm_policy_destroy);
static void xfrm_policy_kill(struct xfrm_policy *policy)
{
write_lock_bh(&policy->lock);
policy->walk.dead = 1;
write_unlock_bh(&policy->lock);
atomic_inc(&policy->genid);

View File

@ -110,7 +110,8 @@ static inline int verify_sec_ctx_len(struct nlattr **attrs)
return 0;
uctx = nla_data(rt);
if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
if (uctx->len > nla_len(rt) ||
uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
return -EINVAL;
return 0;
@ -2273,6 +2274,9 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
xfrm_mark_get(attrs, &mark);
err = verify_newpolicy_info(&ua->policy);
if (err)
goto free_state;
err = verify_sec_ctx_len(attrs);
if (err)
goto free_state;