From: Greg Kroah-Hartman Date: Thu, 23 Feb 2023 09:11:37 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v6.2.1~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=236ea28bfa71ae3d7a9d0622058f28da1706baf5;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: drm-i915-gvt-fix-double-free-bug-in-split_2mb_gtt_entry.patch mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch --- diff --git a/queue-5.10/drm-i915-gvt-fix-double-free-bug-in-split_2mb_gtt_entry.patch b/queue-5.10/drm-i915-gvt-fix-double-free-bug-in-split_2mb_gtt_entry.patch new file mode 100644 index 00000000000..3eb44afac69 --- /dev/null +++ b/queue-5.10/drm-i915-gvt-fix-double-free-bug-in-split_2mb_gtt_entry.patch @@ -0,0 +1,63 @@ +From 4a61648af68f5ba4884f0e3b494ee1cabc4b6620 Mon Sep 17 00:00:00 2001 +From: Zheng Wang +Date: Fri, 30 Dec 2022 00:56:41 +0800 +Subject: drm/i915/gvt: fix double free bug in split_2MB_gtt_entry + +From: Zheng Wang + +commit 4a61648af68f5ba4884f0e3b494ee1cabc4b6620 upstream. + +If intel_gvt_dma_map_guest_page failed, it will call +ppgtt_invalidate_spt, which will finally free the spt. +But the caller function ppgtt_populate_spt_by_guest_entry +does not notice that, it will free spt again in its error +path. + +Fix this by canceling the mapping of DMA address and freeing sub_spt. +Besides, leave the handle of spt destroy to caller function instead +of callee function when error occurs. + +Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") +Signed-off-by: Zheng Wang +Reviewed-by: Zhenyu Wang +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20221229165641.1192455-1-zyytlz.wz@163.com +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/gvt/gtt.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/gvt/gtt.c ++++ b/drivers/gpu/drm/i915/gvt/gtt.c +@@ -1192,10 +1192,8 @@ static int split_2MB_gtt_entry(struct in + for_each_shadow_entry(sub_spt, &sub_se, sub_index) { + ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, + start_gfn + sub_index, PAGE_SIZE, &dma_addr); +- if (ret) { +- ppgtt_invalidate_spt(spt); +- return ret; +- } ++ if (ret) ++ goto err; + sub_se.val64 = se->val64; + + /* Copy the PAT field from PDE. */ +@@ -1214,6 +1212,17 @@ static int split_2MB_gtt_entry(struct in + ops->set_pfn(se, sub_spt->shadow_page.mfn); + ppgtt_set_shadow_entry(spt, se, index); + return 0; ++err: ++ /* Cancel the existing addess mappings of DMA addr. */ ++ for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { ++ gvt_vdbg_mm("invalidate 4K entry\n"); ++ ppgtt_invalidate_pte(sub_spt, &sub_se); ++ } ++ /* Release the new allocated spt. */ ++ trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, ++ sub_spt->guest_page.gfn, sub_spt->shadow_page.type); ++ ppgtt_free_spt(sub_spt); ++ return ret; + } + + static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, diff --git a/queue-5.10/mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch b/queue-5.10/mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch new file mode 100644 index 00000000000..7621cc1177e --- /dev/null +++ b/queue-5.10/mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch @@ -0,0 +1,328 @@ +From 8b5cb7e41d9d77ffca036b0239177de123394a55 Mon Sep 17 00:00:00 2001 +From: Pavel Skripkin +Date: Thu, 30 Dec 2021 22:55:47 +0300 +Subject: mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh + +From: Pavel Skripkin + +commit 8b5cb7e41d9d77ffca036b0239177de123394a55 upstream. + +Syzbot hit NULL deref in rhashtable_free_and_destroy(). The problem was +in mesh_paths and mpp_paths being NULL. + +mesh_pathtbl_init() could fail in case of memory allocation failure, but +nobody cared, since ieee80211_mesh_init_sdata() returns void. It led to +leaving 2 pointers as NULL. Syzbot has found null deref on exit path, +but it could happen anywhere else, because code assumes these pointers are +valid. + +Since all ieee80211_*_setup_sdata functions are void and do not fail, +let's embedd mesh_paths and mpp_paths into parent struct to avoid +adding error handling on higher levels and follow the pattern of others +setup_sdata functions + +Fixes: 60854fd94573 ("mac80211: mesh: convert path table to rhashtable") +Reported-and-tested-by: syzbot+860268315ba86ea6b96b@syzkaller.appspotmail.com +Signed-off-by: Pavel Skripkin +Link: https://lore.kernel.org/r/20211230195547.23977-1-paskripkin@gmail.com +Signed-off-by: Johannes Berg +[pchelkin@ispras.ru: adapt a comment spell fixing issue] +Signed-off-by: Fedor Pchelkin +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/ieee80211_i.h | 24 ++++++++++- + net/mac80211/mesh.h | 22 ---------- + net/mac80211/mesh_pathtbl.c | 91 +++++++++++++++----------------------------- + 3 files changed, 55 insertions(+), 82 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -644,6 +644,26 @@ struct mesh_csa_settings { + struct cfg80211_csa_settings settings; + }; + ++/** ++ * struct mesh_table ++ * ++ * @known_gates: list of known mesh gates and their mpaths by the station. The ++ * gate's mpath may or may not be resolved and active. ++ * @gates_lock: protects updates to known_gates ++ * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr ++ * @walk_head: linked list containing all mesh_path objects ++ * @walk_lock: lock protecting walk_head ++ * @entries: number of entries in the table ++ */ ++struct mesh_table { ++ struct hlist_head known_gates; ++ spinlock_t gates_lock; ++ struct rhashtable rhead; ++ struct hlist_head walk_head; ++ spinlock_t walk_lock; ++ atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ ++}; ++ + struct ieee80211_if_mesh { + struct timer_list housekeeping_timer; + struct timer_list mesh_path_timer; +@@ -718,8 +738,8 @@ struct ieee80211_if_mesh { + /* offset from skb->data while building IE */ + int meshconf_offset; + +- struct mesh_table *mesh_paths; +- struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ ++ struct mesh_table mesh_paths; ++ struct mesh_table mpp_paths; /* Store paths for MPP&MAP */ + int mesh_paths_generation; + int mpp_paths_generation; + }; +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -127,26 +127,6 @@ struct mesh_path { + u32 path_change_count; + }; + +-/** +- * struct mesh_table +- * +- * @known_gates: list of known mesh gates and their mpaths by the station. The +- * gate's mpath may or may not be resolved and active. +- * @gates_lock: protects updates to known_gates +- * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr +- * @walk_head: linked list containging all mesh_path objects +- * @walk_lock: lock protecting walk_head +- * @entries: number of entries in the table +- */ +-struct mesh_table { +- struct hlist_head known_gates; +- spinlock_t gates_lock; +- struct rhashtable rhead; +- struct hlist_head walk_head; +- spinlock_t walk_lock; +- atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ +-}; +- + /* Recent multicast cache */ + /* RMC_BUCKETS must be a power of 2, maximum 256 */ + #define RMC_BUCKETS 256 +@@ -308,7 +288,7 @@ int mesh_path_error_tx(struct ieee80211_ + void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); + void mesh_path_flush_pending(struct mesh_path *mpath); + void mesh_path_tx_pending(struct mesh_path *mpath); +-int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata); ++void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata); + void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata); + int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr); + void mesh_path_timer(struct timer_list *t); +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -47,32 +47,24 @@ static void mesh_path_rht_free(void *ptr + mesh_path_free_rcu(tbl, mpath); + } + +-static struct mesh_table *mesh_table_alloc(void) ++static void mesh_table_init(struct mesh_table *tbl) + { +- struct mesh_table *newtbl; +- +- newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC); +- if (!newtbl) +- return NULL; +- +- INIT_HLIST_HEAD(&newtbl->known_gates); +- INIT_HLIST_HEAD(&newtbl->walk_head); +- atomic_set(&newtbl->entries, 0); +- spin_lock_init(&newtbl->gates_lock); +- spin_lock_init(&newtbl->walk_lock); +- if (rhashtable_init(&newtbl->rhead, &mesh_rht_params)) { +- kfree(newtbl); +- return NULL; +- } +- +- return newtbl; ++ INIT_HLIST_HEAD(&tbl->known_gates); ++ INIT_HLIST_HEAD(&tbl->walk_head); ++ atomic_set(&tbl->entries, 0); ++ spin_lock_init(&tbl->gates_lock); ++ spin_lock_init(&tbl->walk_lock); ++ ++ /* rhashtable_init() may fail only in case of wrong ++ * mesh_rht_params ++ */ ++ WARN_ON(rhashtable_init(&tbl->rhead, &mesh_rht_params)); + } + + static void mesh_table_free(struct mesh_table *tbl) + { + rhashtable_free_and_destroy(&tbl->rhead, + mesh_path_rht_free, tbl); +- kfree(tbl); + } + + /** +@@ -238,13 +230,13 @@ static struct mesh_path *mpath_lookup(st + struct mesh_path * + mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) + { +- return mpath_lookup(sdata->u.mesh.mesh_paths, dst, sdata); ++ return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata); + } + + struct mesh_path * + mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) + { +- return mpath_lookup(sdata->u.mesh.mpp_paths, dst, sdata); ++ return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata); + } + + static struct mesh_path * +@@ -281,7 +273,7 @@ __mesh_path_lookup_by_idx(struct mesh_ta + struct mesh_path * + mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) + { +- return __mesh_path_lookup_by_idx(sdata->u.mesh.mesh_paths, idx); ++ return __mesh_path_lookup_by_idx(&sdata->u.mesh.mesh_paths, idx); + } + + /** +@@ -296,7 +288,7 @@ mesh_path_lookup_by_idx(struct ieee80211 + struct mesh_path * + mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) + { +- return __mesh_path_lookup_by_idx(sdata->u.mesh.mpp_paths, idx); ++ return __mesh_path_lookup_by_idx(&sdata->u.mesh.mpp_paths, idx); + } + + /** +@@ -309,7 +301,7 @@ int mesh_path_add_gate(struct mesh_path + int err; + + rcu_read_lock(); +- tbl = mpath->sdata->u.mesh.mesh_paths; ++ tbl = &mpath->sdata->u.mesh.mesh_paths; + + spin_lock_bh(&mpath->state_lock); + if (mpath->is_gate) { +@@ -418,7 +410,7 @@ struct mesh_path *mesh_path_add(struct i + if (!new_mpath) + return ERR_PTR(-ENOMEM); + +- tbl = sdata->u.mesh.mesh_paths; ++ tbl = &sdata->u.mesh.mesh_paths; + spin_lock_bh(&tbl->walk_lock); + mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead, + &new_mpath->rhash, +@@ -460,7 +452,7 @@ int mpp_path_add(struct ieee80211_sub_if + return -ENOMEM; + + memcpy(new_mpath->mpp, mpp, ETH_ALEN); +- tbl = sdata->u.mesh.mpp_paths; ++ tbl = &sdata->u.mesh.mpp_paths; + + spin_lock_bh(&tbl->walk_lock); + ret = rhashtable_lookup_insert_fast(&tbl->rhead, +@@ -489,7 +481,7 @@ int mpp_path_add(struct ieee80211_sub_if + void mesh_plink_broken(struct sta_info *sta) + { + struct ieee80211_sub_if_data *sdata = sta->sdata; +- struct mesh_table *tbl = sdata->u.mesh.mesh_paths; ++ struct mesh_table *tbl = &sdata->u.mesh.mesh_paths; + static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + struct mesh_path *mpath; + +@@ -548,7 +540,7 @@ static void __mesh_path_del(struct mesh_ + void mesh_path_flush_by_nexthop(struct sta_info *sta) + { + struct ieee80211_sub_if_data *sdata = sta->sdata; +- struct mesh_table *tbl = sdata->u.mesh.mesh_paths; ++ struct mesh_table *tbl = &sdata->u.mesh.mesh_paths; + struct mesh_path *mpath; + struct hlist_node *n; + +@@ -563,7 +555,7 @@ void mesh_path_flush_by_nexthop(struct s + static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata, + const u8 *proxy) + { +- struct mesh_table *tbl = sdata->u.mesh.mpp_paths; ++ struct mesh_table *tbl = &sdata->u.mesh.mpp_paths; + struct mesh_path *mpath; + struct hlist_node *n; + +@@ -597,8 +589,8 @@ static void table_flush_by_iface(struct + */ + void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) + { +- table_flush_by_iface(sdata->u.mesh.mesh_paths); +- table_flush_by_iface(sdata->u.mesh.mpp_paths); ++ table_flush_by_iface(&sdata->u.mesh.mesh_paths); ++ table_flush_by_iface(&sdata->u.mesh.mpp_paths); + } + + /** +@@ -644,7 +636,7 @@ int mesh_path_del(struct ieee80211_sub_i + /* flush relevant mpp entries first */ + mpp_flush_by_proxy(sdata, addr); + +- err = table_path_del(sdata->u.mesh.mesh_paths, sdata, addr); ++ err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr); + sdata->u.mesh.mesh_paths_generation++; + return err; + } +@@ -682,7 +674,7 @@ int mesh_path_send_to_gates(struct mesh_ + struct mesh_path *gate; + bool copy = false; + +- tbl = sdata->u.mesh.mesh_paths; ++ tbl = &sdata->u.mesh.mesh_paths; + + rcu_read_lock(); + hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) { +@@ -762,29 +754,10 @@ void mesh_path_fix_nexthop(struct mesh_p + mesh_path_tx_pending(mpath); + } + +-int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) ++void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) + { +- struct mesh_table *tbl_path, *tbl_mpp; +- int ret; +- +- tbl_path = mesh_table_alloc(); +- if (!tbl_path) +- return -ENOMEM; +- +- tbl_mpp = mesh_table_alloc(); +- if (!tbl_mpp) { +- ret = -ENOMEM; +- goto free_path; +- } +- +- sdata->u.mesh.mesh_paths = tbl_path; +- sdata->u.mesh.mpp_paths = tbl_mpp; +- +- return 0; +- +-free_path: +- mesh_table_free(tbl_path); +- return ret; ++ mesh_table_init(&sdata->u.mesh.mesh_paths); ++ mesh_table_init(&sdata->u.mesh.mpp_paths); + } + + static +@@ -806,12 +779,12 @@ void mesh_path_tbl_expire(struct ieee802 + + void mesh_path_expire(struct ieee80211_sub_if_data *sdata) + { +- mesh_path_tbl_expire(sdata, sdata->u.mesh.mesh_paths); +- mesh_path_tbl_expire(sdata, sdata->u.mesh.mpp_paths); ++ mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths); ++ mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths); + } + + void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) + { +- mesh_table_free(sdata->u.mesh.mesh_paths); +- mesh_table_free(sdata->u.mesh.mpp_paths); ++ mesh_table_free(&sdata->u.mesh.mesh_paths); ++ mesh_table_free(&sdata->u.mesh.mpp_paths); + } diff --git a/queue-5.10/series b/queue-5.10/series index fa85fa75119..cb0c99363a7 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -12,3 +12,5 @@ kvm-svm-skip-wrmsr-fastpath-on-vm-exit-if-next-rip-i.patch kvm-vmx-execute-ibpb-on-emulated-vm-exit-when-guest-.patch can-kvaser_usb-hydra-help-gcc-13-to-figure-out-cmd_l.patch powerpc-dts-t208x-disable-10g-on-mac1-and-mac2.patch +drm-i915-gvt-fix-double-free-bug-in-split_2mb_gtt_entry.patch +mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch