From e55bdca2cb6bd108cffac890722955888d4e8478 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 31 Oct 2022 11:02:45 +0100 Subject: [PATCH 1/8] UPSTREAM: media: dvb-core: Fix UAF due to refcount races at releasing commit fd3d91ab1c6ab0628fe642dd570b56302c30a792 upstream. The dvb-core tries to sync the releases of opened files at dvb_dmxdev_release() with two refcounts: dvbdev->users and dvr_dvbdev->users. A problem is present in those two syncs: when yet another dvb_demux_open() is called during those sync waits, dvb_demux_open() continues to process even if the device is being closed. This includes the increment of the former refcount, resulting in the leftover refcount after the sync of the latter refcount at dvb_dmxdev_release(). It ends up with use-after-free, since the function believes that all usages were gone and releases the resources. This patch addresses the problem by adding the check of dmxdev->exit flag at dvb_demux_open(), just like dvb_dvr_open() already does. With the exit flag check, the second call of dvb_demux_open() fails, hence the further corruption can be avoided. Also for avoiding the races of the dmxdev->exit flag reference, this patch serializes the dmxdev->exit set up and the sync waits with the dmxdev->mutex lock at dvb_dmxdev_release(). Without the mutex lock, dvb_demux_open() (or dvb_dvr_open()) may run concurrently with dvb_dmxdev_release(), which allows to skip the exit flag check and continue the open process that is being closed. CVE-2022-41218 is assigned to those bugs above. Bug: 248356119 Reported-by: Hyunwoo Kim Cc: Link: https://lore.kernel.org/20220908132754.30532-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Signed-off-by: Lee Jones Change-Id: I5a0dd4444ca25d07a050dcb07609c7c7ccf658af --- drivers/media/dvb-core/dmxdev.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index e58cb8434daf..12b7f698f562 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -800,6 +800,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file) if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; + if (dmxdev->exit) { + mutex_unlock(&dmxdev->mutex); + return -ENODEV; + } + for (i = 0; i < dmxdev->filternum; i++) if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) break; @@ -1458,7 +1463,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init); void dvb_dmxdev_release(struct dmxdev *dmxdev) { + mutex_lock(&dmxdev->mutex); dmxdev->exit = 1; + mutex_unlock(&dmxdev->mutex); + if (dmxdev->dvbdev->users > 1) { wait_event(dmxdev->dvbdev->wait_queue, dmxdev->dvbdev->users == 1); From 1866ee1a9025bfa9391b71f962e4d2099fc85ed7 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Wed, 1 Feb 2023 08:44:28 -0800 Subject: [PATCH 2/8] ANDROID: ABI: Cuttlefish Symbol update The cuttlefish symbol list has bitrotted preventing this kernel's startup. Updating it with the following steps. $ BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh $ BUILD_CONFIG=common-modules/virtual-\ device/build.config.cuttlefish.aarch64 build/build.sh $ build/abi/extract_symbols out/android11-5.4/dist/ --whitelist \ common/android/abi_gki_aarch64_cuttlefish --additions-only $ BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh \ --update --print-report Bug: 267474419 Bug: 254392308 Test: Local boot on cuttlefish arm64 android11-gsi Signed-off-by: Ram Muthiah Change-Id: I45b54bed9584c8669d1e277a0ffbed2e5026eeb8 --- android/abi_gki_aarch64.xml | 923 +++++++++++++++++++---------- android/abi_gki_aarch64_cuttlefish | 113 +++- 2 files changed, 700 insertions(+), 336 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index cf6642ccf4ba..e2ca86c05577 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -2075,6 +2075,7 @@ + @@ -17861,7 +17862,7 @@ - + @@ -26713,7 +26714,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -28598,7 +28624,7 @@ - + @@ -28981,6 +29007,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -29339,7 +29466,7 @@ - + @@ -30019,7 +30146,7 @@ - + @@ -30061,7 +30188,22 @@ - + + + + + + + + + + + + + + + + @@ -30266,6 +30408,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -30301,6 +30498,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -30929,13 +31154,27 @@ - + + + + + + + + + + + + + + + @@ -30956,6 +31195,12 @@ + + + + + + @@ -31225,26 +31470,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -31271,6 +31496,20 @@ + + + + + + + + + + + + + + @@ -31328,12 +31567,18 @@ - + - + + + + - + + + + @@ -31769,6 +32014,15 @@ + + + + + + + + + @@ -31796,6 +32050,7 @@ + @@ -31809,6 +32064,9 @@ + + + @@ -31824,6 +32082,14 @@ + + + + + + + + @@ -31890,6 +32156,14 @@ + + + + + + + + @@ -32037,20 +32311,6 @@ - - - - - - - - - - - - - - @@ -32079,20 +32339,6 @@ - - - - - - - - - - - - - - @@ -32299,7 +32545,7 @@ - + @@ -32372,6 +32618,9 @@ + + + @@ -32404,14 +32653,6 @@ - - - - - - - - @@ -32677,9 +32918,6 @@ - - - @@ -61583,7 +61821,7 @@ - + @@ -61765,7 +62003,7 @@ - + @@ -63737,7 +63975,7 @@ - + @@ -63794,7 +64032,7 @@ - + @@ -70798,7 +71036,7 @@ - + @@ -72287,7 +72525,7 @@ - + @@ -73244,7 +73482,7 @@ - + @@ -75754,7 +75992,7 @@ - + @@ -76188,7 +76426,7 @@ - + @@ -77402,7 +77640,7 @@ - + @@ -84230,11 +84468,11 @@ - + - + @@ -84334,13 +84572,13 @@ - + - + @@ -84423,7 +84661,7 @@ - + @@ -84821,7 +85059,7 @@ - + @@ -107810,7 +108048,7 @@ - + @@ -107834,7 +108072,7 @@ - + @@ -114327,8 +114565,8 @@ - - + + @@ -166888,9 +167126,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -167026,7 +167464,18 @@ + + + + + + + + + + + @@ -167215,6 +167664,13 @@ + + + + + + + @@ -167222,6 +167678,10 @@ + + + + @@ -174933,7 +175393,7 @@ - + @@ -175311,6 +175771,15 @@ + + + + + + + + + @@ -177966,224 +178435,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -178278,17 +178536,6 @@ - - - - - - - - - - - @@ -178352,7 +178599,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -179698,7 +179970,7 @@ - + @@ -179727,7 +179999,7 @@ - + @@ -180319,7 +180591,7 @@ - + @@ -181279,7 +181551,7 @@ - + @@ -184237,6 +184509,21 @@ + + + + + + + + + + + + + + + diff --git a/android/abi_gki_aarch64_cuttlefish b/android/abi_gki_aarch64_cuttlefish index 12eb7ce410d0..c2732aa7dba0 100644 --- a/android/abi_gki_aarch64_cuttlefish +++ b/android/abi_gki_aarch64_cuttlefish @@ -10,6 +10,7 @@ arm64_const_caps_ready bcmp cancel_delayed_work_sync + cancel_work_sync capable cfg80211_inform_bss_data cfg80211_put_bss @@ -28,6 +29,7 @@ delayed_work_timer_fn destroy_workqueue _dev_err + device_create device_register device_unregister _dev_info @@ -39,6 +41,7 @@ dma_set_coherent_mask dma_set_mask down_write + ether_setup ethtool_op_get_link eth_validate_addr event_triggers_call @@ -60,6 +63,7 @@ init_wait_entry __init_waitqueue_head jiffies + jiffies_to_msecs kfree kfree_skb __kmalloc @@ -72,6 +76,8 @@ kmemdup kstrdup ktime_get + ktime_get_with_offset + kvfree __list_add_valid __list_del_entry_valid __local_bh_enable_ip @@ -83,6 +89,7 @@ __module_get module_layout module_put + __msecs_to_jiffies msleep __mutex_init mutex_lock @@ -98,6 +105,7 @@ netif_device_detach netif_tx_stop_all_queues netif_tx_wake_queue + nf_conntrack_destroy no_llseek nonseekable_open noop_llseek @@ -141,9 +149,8 @@ _raw_spin_unlock_irqrestore __rcu_read_lock __rcu_read_unlock - refcount_dec_and_test_checked - refcount_inc_checked - register_netdev + refcount_warn_saturate + register_netdevice register_netdevice_notifier register_virtio_device register_virtio_driver @@ -158,9 +165,12 @@ seq_printf sg_init_one sg_init_table + skb_add_rx_frag skb_clone skb_dequeue + skb_push skb_put + skb_queue_tail sk_free snd_device_new snd_pcm_alt_chmaps @@ -195,8 +205,11 @@ unregister_virtio_device unregister_virtio_driver up_write + virtio_break_device virtio_check_driver_offered_feature virtio_config_changed + virtio_device_freeze + virtio_device_restore virtio_max_dma_size virtqueue_add_inbuf virtqueue_add_outbuf @@ -270,10 +283,8 @@ hci_register_dev hci_unregister_dev skb_pull - skb_push skb_queue_head skb_queue_purge - skb_queue_tail # required by incrementalfs.ko bin2hex @@ -303,7 +314,6 @@ generic_file_read_iter generic_file_splice_read generic_read_dir - generic_shutdown_super __get_free_pages get_zeroed_page iget5_locked @@ -315,6 +325,7 @@ kernel_read kernel_write kern_path + kill_anon_super kobject_create_and_add kobject_put lockref_get @@ -323,7 +334,6 @@ LZ4_decompress_safe match_int match_token - __msecs_to_jiffies mutex_is_locked notify_change override_creds @@ -357,6 +367,76 @@ vfs_setxattr vfs_unlink +# required by mac80211_hwsim.ko + alloc_netdev_mqs + __cfg80211_alloc_event_skb + __cfg80211_alloc_reply_skb + __cfg80211_send_event_skb + cfg80211_vendor_cmd_reply + dev_alloc_name + device_bind_driver + device_release_driver + dst_release + eth_mac_addr + genlmsg_put + genl_notify + genl_register_family + genl_unregister_family + hrtimer_cancel + hrtimer_forward + hrtimer_init + hrtimer_start_range_ns + ieee80211_alloc_hw_nm + ieee80211_beacon_get_tim + ieee80211_csa_finish + ieee80211_csa_is_complete + ieee80211_free_hw + ieee80211_free_txskb + ieee80211_get_tx_rates + ieee80211_iterate_active_interfaces_atomic + ieee80211_probereq_get + ieee80211_queue_delayed_work + ieee80211_ready_on_channel + ieee80211_register_hw + ieee80211_remain_on_channel_expired + ieee80211_rx_irqsafe + ieee80211_scan_completed + ieee80211_start_tx_ba_cb_irqsafe + ieee80211_stop_tx_ba_cb_irqsafe + ieee80211_tx_prepare_skb + ieee80211_tx_status_irqsafe + ieee80211_unregister_hw + init_net + kstrndup + __netdev_alloc_skb + netif_rx + netlink_broadcast + netlink_register_notifier + netlink_unicast + netlink_unregister_notifier + net_namespace_list + nla_memcpy + __nla_parse + nla_put_64bit + nla_put + param_ops_ushort + ___ratelimit + register_pernet_device + regulatory_hint + rhashtable_destroy + rhashtable_init + rhashtable_insert_slow + __rht_bucket_nested + rht_bucket_nested + rht_bucket_nested_insert + schedule_timeout_interruptible + skb_copy + skb_copy_expand + __skb_ext_put + skb_trim + unregister_pernet_device + wiphy_apply_custom_regulatory + # required by nd_virtio.ko bio_alloc_bioset bio_chain @@ -380,6 +460,7 @@ netdev_lower_state_changed netdev_pick_tx pci_bus_type + register_netdev # required by rtc-test.ko add_timer @@ -466,7 +547,6 @@ idr_remove idr_replace __init_rwsem - jiffies_to_msecs jiffies_to_usecs krealloc memchr_inv @@ -501,11 +581,8 @@ cfg80211_scan_done __dev_get_by_index dev_printk - ether_setup - ktime_get_with_offset netdev_upper_dev_link netif_stacked_transfer_operstate - register_netdevice rtnl_link_register rtnl_link_unregister unregister_netdevice_many @@ -612,7 +689,6 @@ drm_universal_plane_init __get_task_comm kmalloc_order_trace - kvfree kvmalloc_node memdup_user mutex_trylock @@ -701,11 +777,9 @@ unregister_blkdev # required by virtio_console.ko - cancel_work_sync cdev_add cdev_alloc cdev_del - device_create device_destroy dma_alloc_attrs dma_free_attrs @@ -789,12 +863,10 @@ netif_set_real_num_tx_queues __netif_set_xps_queue net_ratelimit - nf_conntrack_destroy __num_online_cpus __pskb_pull_tail _raw_spin_trylock sched_clock - skb_add_rx_frag skb_coalesce_rx_frag __skb_flow_dissect skb_page_frag_refill @@ -820,6 +892,7 @@ # required by virtio_pci.ko irq_set_affinity_hint pci_alloc_irq_vectors_affinity + pci_device_is_present pci_find_capability pci_find_ext_capability pci_find_next_capability @@ -831,8 +904,6 @@ pci_release_region pci_release_selected_regions pci_request_selected_regions - virtio_device_freeze - virtio_device_restore # required by virtio_pmem.ko nvdimm_bus_register @@ -852,6 +923,7 @@ # required by vsock.ko autoremove_wake_function init_user_ns + mod_delayed_work_on ns_capable_noaudit prandom_u32 prepare_to_wait @@ -882,3 +954,8 @@ sock_diag_save_cookie sock_diag_unregister sock_i_ino + +# preserved by --additions-only + generic_shutdown_super + refcount_dec_and_test_checked + refcount_inc_checked From b6a441d6342081205712d5b0c0097e382d9d26d0 Mon Sep 17 00:00:00 2001 From: Weilun Du Date: Thu, 6 May 2021 11:05:29 -0700 Subject: [PATCH 3/8] FROMGIT: mac80211_hwsim: add concurrent channels scanning support over virtio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixed the crash when setting channels to 2 or more when communicating over virtio. Signed-off-by: Weilun Du Link: https://lore.kernel.org/r/20210506180530.3418576-1-wdu@google.com Signed-off-by: Johannes Berg (cherry picked from commit 626c30f9e77354301ff9162c3bdddaf92d9b5cf3 https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=626c30f9e77354301ff9162c3bdddaf92d9b5cf3) Bug: 182576217 Signed-off-by: Weilun Du Signed-off-by: Maciej Żenczykowski Change-Id: Ia9be6c1d962b941a92f4e1be41e874dbe08024e5 (cherry picked from commit 2e289f3641a9c37ad054f9e84398533ccd930c8f) (cherry picked from commit 085ebe864e396d3df82d06761bb1ddb97d8ce4d9) --- drivers/net/wireless/mac80211_hwsim.c | 48 +++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 9b7fb81fab52..091a4d0b6957 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -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; @@ -1091,7 +1092,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 +1148,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 +1489,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++; @@ -1598,7 +1600,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); @@ -2316,6 +2318,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 +2334,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 +2351,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 +2943,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 +3438,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 +3465,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 +3487,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 +3500,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; From 3daec397eecd02a6e84ba4a2f2376f165fcc5460 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Mar 2020 16:24:00 +0100 Subject: [PATCH 4/8] BACKPORT: mac80211_hwsim: notify wmediumd of used MAC addresses Currently, wmediumd requires each used MAC address to be configured as a station in the virtual air, but that doesn't make sense as any station could have multiple MAC addresses, and even have randomized ones in scanning, etc. Add some code here to tell wmediumd of used MAC addresses, binding them to the hardware address. Combined with a wmediumd patch that makes it track the addresses this allows configuring just the radio address (42:00:00:00:nn:00 unless the radio was manually created) in wmediumd as a station, and all addresses that the station uses are added/removed dynamically. Tested with random scan, which without this and the corresponding wmediumd change doesn't get anything through as the sender doesn't exist as far as wmediumd is concerned (it's random). Link: https://lore.kernel.org/r/20200323162358.b397b1a1acef.Ice0536e34e5d96c51f97c374ea8af9551347c7e8@changeid Signed-off-by: Johannes Berg (cherry picked from commit 5cc58a9ecfa1bbf5fb587ec65e42f15dd5051238) Signed-off-by: Jeongik Cha Bug: 238124637 Change-Id: I973948f65a6303ffff7aa8998b68cc8e6ce98930 (cherry picked from commit cc9d67ff745c7e47893a9724824882c1e7b25764) --- drivers/net/wireless/mac80211_hwsim.c | 51 +++++++++++++++++++++++++++ drivers/net/wireless/mac80211_hwsim.h | 8 +++++ 2 files changed, 59 insertions(+) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 091a4d0b6957..f8abb3fa1f8f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1060,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; @@ -1542,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; @@ -1581,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, @@ -2094,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; } @@ -2179,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); @@ -2222,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)); @@ -2238,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); diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 28ade92adcb4..9dceed77c5d6 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -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) From 2490e55ff47d6cfbc061e7573bcae04e12569d5b Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Fri, 4 Nov 2022 19:51:43 +0000 Subject: [PATCH 5/8] BACKPORT: iommu: Avoid races around device probe We currently have 3 different ways that __iommu_probe_device() may be called, but no real guarantee that multiple callers can't tread on each other, especially once asynchronous driver probe gets involved. It would likely have taken a fair bit of luck to hit this previously, but commit 57365a04c921 ("iommu: Move bus setup to IOMMU device registration") ups the odds since now it's not just omap-iommu that may trigger multiple bus_iommu_probe() calls in parallel if probing asynchronously. Add a lock to ensure we can't try to double-probe a device, and also close some possible race windows to make sure we're truly robust against trying to double-initialise a group via two different member devices. Reported-by: Brian Norris Signed-off-by: Robin Murphy Tested-by: Brian Norris Fixes: 57365a04c921 ("iommu: Move bus setup to IOMMU device registration") Link: https://lore.kernel.org/r/1946ef9f774851732eed78760a78ec40dbc6d178.1667591503.git.robin.murphy@arm.com Signed-off-by: Joerg Roedel Bug: 269232600 (cherry picked from commit 01657bc14a3990c665375f77978631fee77b1fce) Change-Id: Ie87f8f7a7b90431c3a2682923961885ce7b239f3 Signed-off-by: Zhenhua Huang Signed-off-by: Srinivasarao Pathipati --- drivers/iommu/iommu.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index e5dab1d93132..7b48cbc582c3 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -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; } From 5a1412b39b1b3cbb29d9bae0a133b0788499e4c3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 23 Oct 2022 19:01:24 -0700 Subject: [PATCH 6/8] UPSTREAM: ipv6: ensure sane device mtu in tunnels commit d89d7ff01235f218dad37de84457717f699dee79 upstream. Another syzbot report [1] with no reproducer hints at a bug in ip6_gre tunnel (dev:ip6gretap0) Since ipv6 mcast code makes sure to read dev->mtu once and applies a sanity check on it (see commit b9b312a7a451 "ipv6: mcast: better catch silly mtu values"), a remaining possibility is that a layer is able to set dev->mtu to an underflowed value (high order bit set). This could happen indeed in ip6gre_tnl_link_config_route(), ip6_tnl_link_config() and ipip6_tunnel_bind_dev() Make sure to sanitize mtu value in a local variable before it is written once on dev->mtu, as lockless readers could catch wrong temporary value. [1] skbuff: skb_over_panic: text:ffff80000b7a2f38 len:40 put:40 head:ffff000149dcf200 data:ffff000149dcf2b0 tail:0xd8 end:0xc0 dev:ip6gretap0 ------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:120 Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP Modules linked in: CPU: 1 PID: 10241 Comm: kworker/1:1 Not tainted 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/30/2022 Workqueue: mld mld_ifc_work pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : skb_panic+0x4c/0x50 net/core/skbuff.c:116 lr : skb_panic+0x4c/0x50 net/core/skbuff.c:116 sp : ffff800020dd3b60 x29: ffff800020dd3b70 x28: 0000000000000000 x27: ffff00010df2a800 x26: 00000000000000c0 x25: 00000000000000b0 x24: ffff000149dcf200 x23: 00000000000000c0 x22: 00000000000000d8 x21: ffff80000b7a2f38 x20: ffff00014c2f7800 x19: 0000000000000028 x18: 00000000000001a9 x17: 0000000000000000 x16: ffff80000db49158 x15: ffff000113bf1a80 x14: 0000000000000000 x13: 00000000ffffffff x12: ffff000113bf1a80 x11: ff808000081c0d5c x10: 0000000000000000 x9 : 73f125dc5c63ba00 x8 : 73f125dc5c63ba00 x7 : ffff800008161d1c x6 : 0000000000000000 x5 : 0000000000000080 x4 : 0000000000000001 x3 : 0000000000000000 x2 : ffff0001fefddcd0 x1 : 0000000100000000 x0 : 0000000000000089 Call trace: skb_panic+0x4c/0x50 net/core/skbuff.c:116 skb_over_panic net/core/skbuff.c:125 [inline] skb_put+0xd4/0xdc net/core/skbuff.c:2049 ip6_mc_hdr net/ipv6/mcast.c:1714 [inline] mld_newpack+0x14c/0x270 net/ipv6/mcast.c:1765 add_grhead net/ipv6/mcast.c:1851 [inline] add_grec+0xa20/0xae0 net/ipv6/mcast.c:1989 mld_send_cr+0x438/0x5a8 net/ipv6/mcast.c:2115 mld_ifc_work+0x38/0x290 net/ipv6/mcast.c:2653 process_one_work+0x2d8/0x504 kernel/workqueue.c:2289 worker_thread+0x340/0x610 kernel/workqueue.c:2436 kthread+0x12c/0x158 kernel/kthread.c:376 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860 Code: 91011400 aa0803e1 a90027ea 94373093 (d4210000) Fixes: c12b395a4664 ("gre: Support GRE over IPv6") Reported-by: syzbot Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/r/20221024020124.3756833-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski [ta: Backport patch for stable kernels < 5.10.y. Fix conflict in net/ipv6/ip6_tunnel.c, mtu initialized with: mtu = rt->dst.dev->mtu - t_hlen;] Cc: # 4.14.y, 4.19.y, 5.4.y Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman Bug: 260121436 Bug: 260229720 Change-Id: If643139236a5c015fc87cc0fbb3426d2da902f50 Signed-off-by: Tudor Ambarus --- net/ipv6/ip6_gre.c | 16 +++++++++------- net/ipv6/ip6_tunnel.c | 10 ++++++---- net/ipv6/sit.c | 8 +++++--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 4a6396d574a0..fd4da1019e44 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -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); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 878a08c40fff..acc75975edde 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -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); } diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 117d374695fe..1179608955f5 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -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); } } From 9adb062d06e1cbb1369d460e7c66a98b519273f4 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Sat, 17 Dec 2022 14:17:07 -0800 Subject: [PATCH 7/8] UPSTREAM: net_sched: reject TCF_EM_SIMPLE case for complex ematch module [ Upstream commit 9cd3fd2054c3b3055163accbf2f31a4426f10317 ] When TCF_EM_SIMPLE was introduced, it is supposed to be convenient for ematch implementation: https://lore.kernel.org/all/20050105110048.GO26856@postel.suug.ch/ "You don't have to, providing a 32bit data chunk without TCF_EM_SIMPLE set will simply result in allocating & copy. It's an optimization, nothing more." So if an ematch module provides ops->datalen that means it wants a complex data structure (saved in its em->data) instead of a simple u32 value. We should simply reject such a combination, otherwise this u32 could be misinterpreted as a pointer. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-and-tested-by: syzbot+4caeae4c7103813598ae@syzkaller.appspotmail.com Reported-by: Jun Nie Cc: Jamal Hadi Salim Cc: Paolo Abeni Signed-off-by: Cong Wang Acked-by: Paolo Abeni Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Bug: 262113355 Bug: 262114215 Change-Id: I03be57351f76f699d4635cf31178e0f3a19e61a5 Signed-off-by: Tudor Ambarus --- net/sched/ematch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sched/ematch.c b/net/sched/ematch.c index dd3b8c11a2e0..43bfb33629e9 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c @@ -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; From 2af3bdf293305aca549992916d10a20701a6324e Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Wed, 17 Aug 2022 21:27:01 +0800 Subject: [PATCH 8/8] UPSTREAM: ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop commit eee22187b53611e173161e38f61de1c7ecbeb876 upstream. In do_writepages, if the value returned by ext4_writepages is "-ENOMEM" and "wbc->sync_mode == WB_SYNC_ALL", retry until the condition is not met. In __ext4_get_inode_loc, if the bh returned by sb_getblk is NULL, the function returns -ENOMEM. In __getblk_slow, if the return value of grow_buffers is less than 0, the function returns NULL. When the three processes are connected in series like the following stack, an infinite loop may occur: do_writepages <--- keep retrying ext4_writepages mpage_map_and_submit_extent mpage_map_one_extent ext4_map_blocks ext4_ext_map_blocks ext4_ext_handle_unwritten_extents ext4_ext_convert_to_initialized ext4_split_extent ext4_split_extent_at __ext4_ext_dirty __ext4_mark_inode_dirty ext4_reserve_inode_write ext4_get_inode_loc __ext4_get_inode_loc <--- return -ENOMEM sb_getblk __getblk_gfp __getblk_slow <--- return NULL grow_buffers grow_dev_page <--- return -ENXIO ret = (block < end_block) ? 1 : -ENXIO; In this issue, bg_inode_table_hi is overwritten as an incorrect value. As a result, `block < end_block` cannot be met in grow_dev_page. Therefore, __ext4_get_inode_loc always returns '-ENOMEM' and do_writepages keeps retrying. As a result, the writeback process is in the D state due to an infinite loop. Add a check on inode table block in the __ext4_get_inode_loc function by referring to ext4_read_inode_bitmap to avoid this infinite loop. Cc: stable@kernel.org Signed-off-by: Baokun Li Reviewed-by: Ritesh Harjani (IBM) Link: https://lore.kernel.org/r/20220817132701.3015912-3-libaokun1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman Bug: 264629802 Bug: 264632463 Change-Id: Id3bb71336059cac33f16fca383e783add3a01295 Signed-off-by: Tudor Ambarus --- fs/ext4/inode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a6a31e624dcb..f94f44fcd311 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -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;