Merge tag 'ASB-2023-03-05_11-5.4' of https://android.googlesource.com/kernel/common into android13-5.4-lahaina

https://source.android.com/docs/security/bulletin/2023-03-01
CVE-2021-33655

* tag 'ASB-2023-03-05_11-5.4' of https://android.googlesource.com/kernel/common:
  ANDROID: fs/f2fs: fixup __f2fs_cluster_blocks with F2FS_FS_COMPRESSION
  UPSTREAM: usb: gadget: f_fs: Ensure ep0req is dequeued before free_request
  UPSTREAM: KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS
  UPSTREAM: ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop
  UPSTREAM: net_sched: reject TCF_EM_SIMPLE case for complex ematch module
  UPSTREAM: ipv6: ensure sane device mtu in tunnels
  BACKPORT: iommu: Avoid races around device probe
  BACKPORT: mac80211_hwsim: notify wmediumd of used MAC addresses
  FROMGIT: mac80211_hwsim: add concurrent channels scanning support over virtio

Change-Id: I225e03054221dc7eae34b5e2b282265951cdcbee
This commit is contained in:
Michael Bestas 2023-03-07 18:48:55 +02:00
commit 284b0b076a
No known key found for this signature in database
GPG key ID: CC95044519BE6669
12 changed files with 162 additions and 28 deletions

View file

@ -4118,6 +4118,17 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
vmx_switch_vmcs(vcpu, &vmx->vmcs01);
/*
* If IBRS is advertised to the vCPU, KVM must flush the indirect
* branch predictors when transitioning from L2 to L1, as L1 expects
* hardware (KVM in this case) to provide separate predictor modes.
* Bare metal isolates VMX root (host) from VMX non-root (guest), but
* doesn't isolate different VMCSs, i.e. in this case, doesn't provide
* separate modes for L2 vs L1.
*/
if (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))
indirect_branch_prediction_barrier();
/* Update any VMCS fields that might have changed while L2 ran */
vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, vmx->msr_autoload.host.nr);
vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, vmx->msr_autoload.guest.nr);

View file

@ -1397,8 +1397,10 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu,
/*
* No indirect branch prediction barrier needed when switching
* the active VMCS within a guest, e.g. on nested VM-Enter.
* The L1 VMM can protect itself with retpolines, IBPB or IBRS.
* the active VMCS within a vCPU, unless IBRS is advertised to
* the vCPU. To minimize the number of IBPBs executed, KVM
* performs IBPB on nested VM-Exit (a single nested transition
* may switch the active VMCS multiple times).
*/
if (!buddy || WARN_ON_ONCE(buddy->vmcs != prev))
indirect_branch_prediction_barrier();

View file

@ -177,14 +177,25 @@ static void iommu_free_dev_param(struct device *dev)
int iommu_probe_device(struct device *dev)
{
const struct iommu_ops *ops = dev->bus->iommu_ops;
static DEFINE_MUTEX(iommu_probe_device_lock);
int ret;
WARN_ON(dev->iommu_group);
if (!ops)
return -EINVAL;
if (!iommu_get_dev_param(dev))
return -ENOMEM;
/*
* Serialise to avoid races between IOMMU drivers registering in
* parallel and/or the "replay" calls from ACPI/OF code via client
* driver probe. Once the latter have been cleaned up we should
* probably be able to use device_lock() here to minimise the scope,
* but for now enforcing a simple global ordering is fine.
*/
mutex_lock(&iommu_probe_device_lock);
if (!iommu_get_dev_param(dev)) {
ret = -ENOMEM;
goto err_unlock;
}
if (!try_module_get(ops->owner)) {
ret = -EINVAL;
@ -195,12 +206,17 @@ int iommu_probe_device(struct device *dev)
if (ret)
goto err_module_put;
mutex_unlock(&iommu_probe_device_lock);
return 0;
err_module_put:
module_put(ops->owner);
err_free_dev_param:
iommu_free_dev_param(dev);
err_unlock:
mutex_unlock(&iommu_probe_device_lock);
return ret;
}

View file

@ -499,6 +499,7 @@ struct mac80211_hwsim_data {
u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
struct mac_address addresses[2];
struct ieee80211_chanctx_conf *chanctx;
int channels, idx;
bool use_chanctx;
bool destroy_on_close;
@ -1059,6 +1060,47 @@ static int hwsim_unicast_netgroup(struct mac80211_hwsim_data *data,
return res;
}
static void mac80211_hwsim_config_mac_nl(struct ieee80211_hw *hw,
const u8 *addr, bool add)
{
struct mac80211_hwsim_data *data = hw->priv;
u32 _portid = READ_ONCE(data->wmediumd);
struct sk_buff *skb;
void *msg_head;
if (!_portid && !hwsim_virtio_enabled)
return;
skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
if (!skb)
return;
msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
add ? HWSIM_CMD_ADD_MAC_ADDR :
HWSIM_CMD_DEL_MAC_ADDR);
if (!msg_head) {
pr_debug("mac80211_hwsim: problem with msg_head\n");
goto nla_put_failure;
}
if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
ETH_ALEN, data->addresses[1].addr))
goto nla_put_failure;
if (nla_put(skb, HWSIM_ATTR_ADDR_RECEIVER, ETH_ALEN, addr))
goto nla_put_failure;
genlmsg_end(skb, msg_head);
if (hwsim_virtio_enabled)
hwsim_tx_virtio(data, skb);
else
hwsim_unicast_netgroup(data, skb, _portid);
return;
nla_put_failure:
nlmsg_free(skb);
}
static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
{
u16 result = 0;
@ -1091,7 +1133,8 @@ static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
struct sk_buff *my_skb,
int dst_portid)
int dst_portid,
struct ieee80211_channel *channel)
{
struct sk_buff *skb;
struct mac80211_hwsim_data *data = hw->priv;
@ -1146,7 +1189,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
goto nla_put_failure;
if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq))
if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq))
goto nla_put_failure;
/* We get the tx control (rate and retries) info*/
@ -1487,7 +1530,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
_portid = READ_ONCE(data->wmediumd);
if (_portid || hwsim_virtio_enabled)
return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel);
/* NO wmediumd detected, perfect medium simulation */
data->tx_pkts++;
@ -1540,6 +1583,9 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
vif->addr);
hwsim_set_magic(vif);
if (vif->type != NL80211_IFTYPE_MONITOR)
mac80211_hwsim_config_mac_nl(hw, vif->addr, true);
vif->cab_queue = 0;
vif->hw_queue[IEEE80211_AC_VO] = 0;
vif->hw_queue[IEEE80211_AC_VI] = 1;
@ -1579,6 +1625,8 @@ static void mac80211_hwsim_remove_interface(
vif->addr);
hwsim_check_magic(vif);
hwsim_clear_magic(vif);
if (vif->type != NL80211_IFTYPE_MONITOR)
mac80211_hwsim_config_mac_nl(hw, vif->addr, false);
}
static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@ -1598,7 +1646,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
mac80211_hwsim_monitor_rx(hw, skb, chan);
if (_pid || hwsim_virtio_enabled)
return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan);
mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
dev_kfree_skb(skb);
@ -2092,6 +2140,8 @@ static void hw_scan_work(struct work_struct *work)
hwsim->hw_scan_vif = NULL;
hwsim->tmp_chan = NULL;
mutex_unlock(&hwsim->mutex);
mac80211_hwsim_config_mac_nl(hwsim->hw, hwsim->scan_addr,
false);
return;
}
@ -2177,6 +2227,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
mutex_unlock(&hwsim->mutex);
mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n");
ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
@ -2220,6 +2271,7 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw,
pr_debug("hwsim sw_scan request, prepping stuff\n");
memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
hwsim->scanning = true;
memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
@ -2236,6 +2288,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw,
pr_debug("hwsim sw_scan_complete\n");
hwsim->scanning = false;
mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, false);
eth_zero_addr(hwsim->scan_addr);
mutex_unlock(&hwsim->mutex);
@ -2316,6 +2369,11 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw,
static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct mac80211_hwsim_data *hwsim = hw->priv;
mutex_lock(&hwsim->mutex);
hwsim->chanctx = ctx;
mutex_unlock(&hwsim->mutex);
hwsim_set_chanctx_magic(ctx);
wiphy_dbg(hw->wiphy,
"add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
@ -2327,6 +2385,11 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct mac80211_hwsim_data *hwsim = hw->priv;
mutex_lock(&hwsim->mutex);
hwsim->chanctx = NULL;
mutex_unlock(&hwsim->mutex);
wiphy_dbg(hw->wiphy,
"remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
ctx->def.chan->center_freq, ctx->def.width,
@ -2339,6 +2402,11 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx,
u32 changed)
{
struct mac80211_hwsim_data *hwsim = hw->priv;
mutex_lock(&hwsim->mutex);
hwsim->chanctx = ctx;
mutex_unlock(&hwsim->mutex);
hwsim_check_chanctx_magic(ctx);
wiphy_dbg(hw->wiphy,
"change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
@ -2926,6 +2994,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
hw->wiphy->max_remain_on_channel_duration = 1000;
data->if_combination.radar_detect_widths = 0;
data->if_combination.num_different_channels = data->channels;
data->chanctx = NULL;
} else {
data->if_combination.num_different_channels = 1;
data->if_combination.radar_detect_widths =
@ -3420,6 +3489,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
int frame_data_len;
void *frame_data;
struct sk_buff *skb = NULL;
struct ieee80211_channel *channel = NULL;
if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
!info->attrs[HWSIM_ATTR_FRAME] ||
@ -3446,6 +3516,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
if (!data2)
goto out;
if (data2->use_chanctx) {
if (data2->tmp_chan)
channel = data2->tmp_chan;
else if (data2->chanctx)
channel = data2->chanctx->def.chan;
} else {
channel = data2->channel;
}
if (!channel)
goto out;
if (!hwsim_virtio_enabled) {
if (hwsim_net_get_netgroup(genl_info_net(info)) !=
data2->netgroup)
@ -3457,7 +3538,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
/* check if radio is configured properly */
if (data2->idle || !data2->started)
if ((data2->idle && !data2->tmp_chan) || !data2->started)
goto out;
/* A frame is received from user space */
@ -3470,18 +3551,16 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
mutex_lock(&data2->mutex);
rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
if (rx_status.freq != data2->channel->center_freq &&
(!data2->tmp_chan ||
rx_status.freq != data2->tmp_chan->center_freq)) {
if (rx_status.freq != channel->center_freq) {
mutex_unlock(&data2->mutex);
goto out;
}
mutex_unlock(&data2->mutex);
} else {
rx_status.freq = data2->channel->center_freq;
rx_status.freq = channel->center_freq;
}
rx_status.band = data2->channel->band;
rx_status.band = channel->band;
rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
goto out;

View file

@ -75,6 +75,12 @@ enum hwsim_tx_control_flags {
* @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted
* @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses:
* %HWSIM_ATTR_RADIO_ID
* @HWSIM_CMD_ADD_MAC_ADDR: add a receive MAC address (given in the
* %HWSIM_ATTR_ADDR_RECEIVER attribute) to a device identified by
* %HWSIM_ATTR_ADDR_TRANSMITTER. This lets wmediumd forward frames
* to this receiver address for a given station.
* @HWSIM_CMD_DEL_MAC_ADDR: remove the MAC address again, the attributes
* are the same as to @HWSIM_CMD_ADD_MAC_ADDR.
* @__HWSIM_CMD_MAX: enum limit
*/
enum {
@ -85,6 +91,8 @@ enum {
HWSIM_CMD_NEW_RADIO,
HWSIM_CMD_DEL_RADIO,
HWSIM_CMD_GET_RADIO,
HWSIM_CMD_ADD_MAC_ADDR,
HWSIM_CMD_DEL_MAC_ADDR,
__HWSIM_CMD_MAX,
};
#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)

View file

@ -2124,6 +2124,8 @@ static void functionfs_unbind(struct ffs_data *ffs)
ENTER();
if (!WARN_ON(!ffs->gadget)) {
/* dequeue before freeing ep0req */
usb_ep_dequeue(ffs->gadget->ep0, ffs->ep0req);
usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
ffs->ep0req = NULL;
ffs->gadget = NULL;

View file

@ -4706,9 +4706,17 @@ static int __ext4_get_inode_loc(struct inode *inode,
inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
inode_offset = ((inode->i_ino - 1) %
EXT4_INODES_PER_GROUP(sb));
block = ext4_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
block = ext4_inode_table(sb, gdp);
if ((block <= le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) ||
(block >= ext4_blocks_count(EXT4_SB(sb)->s_es))) {
ext4_error(sb, "Invalid inode table block %llu in "
"block_group %u", block, iloc->block_group);
return -EFSCORRUPTED;
}
block += (inode_offset / inodes_per_block);
bh = sb_getblk(sb, block);
if (unlikely(!bh))
return -ENOMEM;

View file

@ -810,7 +810,7 @@ static int __f2fs_cluster_blocks(struct compress_ctx *cc, bool compr)
}
}
f2fs_bug_on(F2FS_I_SB(inode),
f2fs_bug_on(F2FS_I_SB(cc->inode),
!compr && ret != cc->cluster_size &&
!is_inode_flag_set(cc->inode, FI_COMPRESS_RELEASED));
}

View file

@ -1137,14 +1137,16 @@ static void ip6gre_tnl_link_config_route(struct ip6_tnl *t, int set_mtu,
dev->needed_headroom = dst_len;
if (set_mtu) {
dev->mtu = rt->dst.dev->mtu - t_hlen;
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
dev->mtu -= 8;
if (dev->type == ARPHRD_ETHER)
dev->mtu -= ETH_HLEN;
int mtu = rt->dst.dev->mtu - t_hlen;
if (dev->mtu < IPV6_MIN_MTU)
dev->mtu = IPV6_MIN_MTU;
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
mtu -= 8;
if (dev->type == ARPHRD_ETHER)
mtu -= ETH_HLEN;
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
WRITE_ONCE(dev->mtu, mtu);
}
}
ip6_rt_put(rt);

View file

@ -1430,6 +1430,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
struct __ip6_tnl_parm *p = &t->parms;
struct flowi6 *fl6 = &t->fl.u.ip6;
int t_hlen;
int mtu;
memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@ -1472,12 +1473,13 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
dev->hard_header_len = rt->dst.dev->hard_header_len +
t_hlen;
dev->mtu = rt->dst.dev->mtu - t_hlen;
mtu = rt->dst.dev->mtu - t_hlen;
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
dev->mtu -= 8;
mtu -= 8;
if (dev->mtu < IPV6_MIN_MTU)
dev->mtu = IPV6_MIN_MTU;
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
WRITE_ONCE(dev->mtu, mtu);
}
ip6_rt_put(rt);
}

View file

@ -1083,10 +1083,12 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
if (tdev && !netif_is_l3_master(tdev)) {
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
int mtu;
dev->mtu = tdev->mtu - t_hlen;
if (dev->mtu < IPV6_MIN_MTU)
dev->mtu = IPV6_MIN_MTU;
mtu = tdev->mtu - t_hlen;
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
WRITE_ONCE(dev->mtu, mtu);
}
}

View file

@ -255,6 +255,8 @@ static int tcf_em_validate(struct tcf_proto *tp,
* the value carried.
*/
if (em_hdr->flags & TCF_EM_SIMPLE) {
if (em->ops->datalen > 0)
goto errout;
if (data_len < sizeof(u32))
goto errout;
em->data = *(u32 *) data;