]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jun 2022 11:47:31 +0000 (13:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jun 2022 11:47:31 +0000 (13:47 +0200)
added patches:
iwlwifi-fw-init-sar-geo-table-only-if-data-is-present.patch
iwlwifi-mei-clear-the-sap-data-header-before-sending.patch
iwlwifi-mei-fix-potential-null-ptr-deref.patch
iwlwifi-mvm-fix-assert-1f04-upon-reconfig.patch
objtool-fix-objtool-regression-on-x32-systems.patch
objtool-fix-symbol-creation.patch
wifi-mac80211-fix-use-after-free-in-chanctx-code.patch

queue-5.17/iwlwifi-fw-init-sar-geo-table-only-if-data-is-present.patch [new file with mode: 0644]
queue-5.17/iwlwifi-mei-clear-the-sap-data-header-before-sending.patch [new file with mode: 0644]
queue-5.17/iwlwifi-mei-fix-potential-null-ptr-deref.patch [new file with mode: 0644]
queue-5.17/iwlwifi-mvm-fix-assert-1f04-upon-reconfig.patch [new file with mode: 0644]
queue-5.17/objtool-fix-objtool-regression-on-x32-systems.patch [new file with mode: 0644]
queue-5.17/objtool-fix-symbol-creation.patch [new file with mode: 0644]
queue-5.17/series
queue-5.17/wifi-mac80211-fix-use-after-free-in-chanctx-code.patch [new file with mode: 0644]

diff --git a/queue-5.17/iwlwifi-fw-init-sar-geo-table-only-if-data-is-present.patch b/queue-5.17/iwlwifi-fw-init-sar-geo-table-only-if-data-is-present.patch
new file mode 100644 (file)
index 0000000..0120751
--- /dev/null
@@ -0,0 +1,40 @@
+From d1f6530c3e373ddd7c76b05646052a27eead14ad Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 17 May 2022 12:05:08 +0300
+Subject: iwlwifi: fw: init SAR GEO table only if data is present
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit d1f6530c3e373ddd7c76b05646052a27eead14ad upstream.
+
+When no table data was read from ACPI, then filling the data
+and returning success here will fill zero values, which means
+transmit power will be limited to 0 dBm. This is clearly not
+intended.
+
+Return an error from iwl_sar_geo_init() if there's no data to
+fill into the command structure.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Fixes: 78a19d5285d9 ("iwlwifi: mvm: Read the PPAG and SAR tables at INIT stage")
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20220517120044.bc45923b74e9.Id2b4362234b7f8ced82c591b95d4075dd2ec12f4@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/fw/acpi.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+@@ -902,6 +902,9 @@ int iwl_sar_geo_init(struct iwl_fw_runti
+ {
+       int i, j;
++      if (!fwrt->geo_enabled)
++              return -ENODATA;
++
+       if (!iwl_sar_geo_support(fwrt))
+               return -EOPNOTSUPP;
diff --git a/queue-5.17/iwlwifi-mei-clear-the-sap-data-header-before-sending.patch b/queue-5.17/iwlwifi-mei-clear-the-sap-data-header-before-sending.patch
new file mode 100644 (file)
index 0000000..5ba78da
--- /dev/null
@@ -0,0 +1,33 @@
+From 55cf10488d7a9fa1b1b473a5e44a80666932e094 Mon Sep 17 00:00:00 2001
+From: Avraham Stern <avraham.stern@intel.com>
+Date: Tue, 17 May 2022 12:05:13 +0300
+Subject: iwlwifi: mei: clear the sap data header before sending
+
+From: Avraham Stern <avraham.stern@intel.com>
+
+commit 55cf10488d7a9fa1b1b473a5e44a80666932e094 upstream.
+
+The SAP data header has some fields that are marked as reserved
+but are actually in use by CSME. Clear those fields before sending
+the data to avoid having random values in those fields.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Avraham Stern <avraham.stern@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20220517120045.8dd3423cf683.I02976028eaa6aab395cb2e701fa7127212762eb7@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mei/main.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c
++++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c
+@@ -493,6 +493,7 @@ void iwl_mei_add_data_to_ring(struct sk_
+       if (cb_tx) {
+               struct iwl_sap_cb_data *cb_hdr = skb_push(skb, sizeof(*cb_hdr));
++              memset(cb_hdr, 0, sizeof(*cb_hdr));
+               cb_hdr->hdr.type = cpu_to_le16(SAP_MSG_CB_DATA_PACKET);
+               cb_hdr->hdr.len = cpu_to_le16(skb->len - sizeof(cb_hdr->hdr));
+               cb_hdr->hdr.seq_num = cpu_to_le32(atomic_inc_return(&mei->sap_seq_no));
diff --git a/queue-5.17/iwlwifi-mei-fix-potential-null-ptr-deref.patch b/queue-5.17/iwlwifi-mei-fix-potential-null-ptr-deref.patch
new file mode 100644 (file)
index 0000000..3e429b9
--- /dev/null
@@ -0,0 +1,36 @@
+From 78488a64aea94a3336ee97f345c1496e9bc5ebdf Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 17 May 2022 12:05:14 +0300
+Subject: iwlwifi: mei: fix potential NULL-ptr deref
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 78488a64aea94a3336ee97f345c1496e9bc5ebdf upstream.
+
+If SKB allocation fails, continue rather than using the NULL
+pointer.
+
+Coverity CID: 1497650
+
+Cc: stable@vger.kernel.org
+Fixes: 2da4366f9e2c ("iwlwifi: mei: add the driver to allow cooperation with CSME")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20220517120045.90c1b1fd534e.Ibb42463e74d0ec7d36ec81df22e171ae1f6268b0@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mei/main.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c
++++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c
+@@ -1020,6 +1020,8 @@ static void iwl_mei_handle_sap_data(stru
+               /* We need enough room for the WiFi header + SNAP + IV */
+               skb = netdev_alloc_skb(netdev, len + QOS_HDR_IV_SNAP_LEN);
++              if (!skb)
++                      continue;
+               skb_reserve(skb, QOS_HDR_IV_SNAP_LEN);
+               ethhdr = skb_push(skb, sizeof(*ethhdr));
diff --git a/queue-5.17/iwlwifi-mvm-fix-assert-1f04-upon-reconfig.patch b/queue-5.17/iwlwifi-mvm-fix-assert-1f04-upon-reconfig.patch
new file mode 100644 (file)
index 0000000..abbe532
--- /dev/null
@@ -0,0 +1,36 @@
+From 9d096e3d3061dbf4ee10e2b59fc2c06e05bdb997 Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Tue, 17 May 2022 12:05:09 +0300
+Subject: iwlwifi: mvm: fix assert 1F04 upon reconfig
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit 9d096e3d3061dbf4ee10e2b59fc2c06e05bdb997 upstream.
+
+When we reconfig we must not send the MAC_POWER command that relates to
+a MAC that was not yet added to the firmware.
+
+Ignore those in the iterator.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20220517120044.ed2ffc8ce732.If786e19512d0da4334a6382ea6148703422c7d7b@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/power.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
+@@ -563,6 +563,9 @@ static void iwl_mvm_power_get_vifs_itera
+       struct iwl_power_vifs *power_iterator = _data;
+       bool active = mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < NUM_PHY_CTX;
++      if (!mvmvif->uploaded)
++              return;
++
+       switch (ieee80211_vif_type_p2p(vif)) {
+       case NL80211_IFTYPE_P2P_DEVICE:
+               break;
diff --git a/queue-5.17/objtool-fix-objtool-regression-on-x32-systems.patch b/queue-5.17/objtool-fix-objtool-regression-on-x32-systems.patch
new file mode 100644 (file)
index 0000000..0221b9f
--- /dev/null
@@ -0,0 +1,101 @@
+From 22682a07acc308ef78681572e19502ce8893c4d4 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Mon, 16 May 2022 11:06:36 -0400
+Subject: objtool: Fix objtool regression on x32 systems
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 22682a07acc308ef78681572e19502ce8893c4d4 upstream.
+
+Commit c087c6e7b551 ("objtool: Fix type of reloc::addend") failed to
+appreciate cross building from ILP32 hosts, where 'int' == 'long' and
+the issue persists.
+
+As such, use s64/int64_t/Elf64_Sxword for this field and suffer the
+pain that is ISO C99 printf formats for it.
+
+Fixes: c087c6e7b551 ("objtool: Fix type of reloc::addend")
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+[peterz: reword changelog, s/long long/s64/]
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: <stable@vger.kernel.org>
+Link: https://lkml.kernel.org/r/alpine.LRH.2.02.2205161041260.11556@file01.intranet.prod.int.rdu2.redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/objtool/check.c               |    9 +++++----
+ tools/objtool/elf.c                 |    2 +-
+ tools/objtool/include/objtool/elf.h |    4 ++--
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -5,6 +5,7 @@
+ #include <string.h>
+ #include <stdlib.h>
++#include <inttypes.h>
+ #include <sys/mman.h>
+ #include <arch/elf.h>
+@@ -546,12 +547,12 @@ static int add_dead_ends(struct objtool_
+               else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
+                       insn = find_last_insn(file, reloc->sym->sec);
+                       if (!insn) {
+-                              WARN("can't find unreachable insn at %s+0x%lx",
++                              WARN("can't find unreachable insn at %s+0x%" PRIx64,
+                                    reloc->sym->sec->name, reloc->addend);
+                               return -1;
+                       }
+               } else {
+-                      WARN("can't find unreachable insn at %s+0x%lx",
++                      WARN("can't find unreachable insn at %s+0x%" PRIx64,
+                            reloc->sym->sec->name, reloc->addend);
+                       return -1;
+               }
+@@ -581,12 +582,12 @@ reachable:
+               else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
+                       insn = find_last_insn(file, reloc->sym->sec);
+                       if (!insn) {
+-                              WARN("can't find reachable insn at %s+0x%lx",
++                              WARN("can't find reachable insn at %s+0x%" PRIx64,
+                                    reloc->sym->sec->name, reloc->addend);
+                               return -1;
+                       }
+               } else {
+-                      WARN("can't find reachable insn at %s+0x%lx",
++                      WARN("can't find reachable insn at %s+0x%" PRIx64,
+                            reloc->sym->sec->name, reloc->addend);
+                       return -1;
+               }
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -486,7 +486,7 @@ static struct section *elf_create_reloc_
+                                               int reltype);
+ int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
+-                unsigned int type, struct symbol *sym, long addend)
++                unsigned int type, struct symbol *sym, s64 addend)
+ {
+       struct reloc *reloc;
+--- a/tools/objtool/include/objtool/elf.h
++++ b/tools/objtool/include/objtool/elf.h
+@@ -73,7 +73,7 @@ struct reloc {
+       struct symbol *sym;
+       unsigned long offset;
+       unsigned int type;
+-      long addend;
++      s64 addend;
+       int idx;
+       bool jump_table_start;
+ };
+@@ -135,7 +135,7 @@ struct elf *elf_open_read(const char *na
+ struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
+ int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
+-                unsigned int type, struct symbol *sym, long addend);
++                unsigned int type, struct symbol *sym, s64 addend);
+ int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
+                         unsigned long offset, unsigned int type,
+                         struct section *insn_sec, unsigned long insn_off);
diff --git a/queue-5.17/objtool-fix-symbol-creation.patch b/queue-5.17/objtool-fix-symbol-creation.patch
new file mode 100644 (file)
index 0000000..7297b2c
--- /dev/null
@@ -0,0 +1,348 @@
+From ead165fa1042247b033afad7be4be9b815d04ade Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Tue, 17 May 2022 17:42:04 +0200
+Subject: objtool: Fix symbol creation
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit ead165fa1042247b033afad7be4be9b815d04ade upstream.
+
+Nathan reported objtool failing with the following messages:
+
+  warning: objtool: no non-local symbols !?
+  warning: objtool: gelf_update_symshndx: invalid section index
+
+The problem is due to commit 4abff6d48dbc ("objtool: Fix code relocs
+vs weak symbols") failing to consider the case where an object would
+have no non-local symbols.
+
+The problem that commit tries to address is adding a STB_LOCAL symbol
+to the symbol table in light of the ELF spec's requirement that:
+
+  In each symbol table, all symbols with STB_LOCAL binding preced the
+  weak and global symbols.  As ``Sections'' above describes, a symbol
+  table section's sh_info section header member holds the symbol table
+  index for the first non-local symbol.
+
+The approach taken is to find this first non-local symbol, move that
+to the end and then re-use the freed spot to insert a new local symbol
+and increment sh_info.
+
+Except it never considered the case of object files without global
+symbols and got a whole bunch of details wrong -- so many in fact that
+it is a wonder it ever worked :/
+
+Specifically:
+
+ - It failed to re-hash the symbol on the new index, so a subsequent
+   find_symbol_by_index() would not find it at the new location and a
+   query for the old location would now return a non-deterministic
+   choice between the old and new symbol.
+
+ - It failed to appreciate that the GElf wrappers are not a valid disk
+   format (it works because GElf is basically Elf64 and we only
+   support x86_64 atm.)
+
+ - It failed to fully appreciate how horrible the libelf API really is
+   and got the gelf_update_symshndx() call pretty much completely
+   wrong; with the direct consequence that if inserting a second
+   STB_LOCAL symbol would require moving the same STB_GLOBAL symbol
+   again it would completely come unstuck.
+
+Write a new elf_update_symbol() function that wraps all the magic
+required to update or create a new symbol at a given index.
+
+Specifically, gelf_update_sym*() require an @ndx argument that is
+relative to the @data argument; this means you have to manually
+iterate the section data descriptor list and update @ndx.
+
+Fixes: 4abff6d48dbc ("objtool: Fix code relocs vs weak symbols")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Cc: <stable@vger.kernel.org>
+Link: https://lkml.kernel.org/r/YoPCTEYjoPqE4ZxB@hirez.programming.kicks-ass.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/objtool/elf.c |  198 +++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 129 insertions(+), 69 deletions(-)
+
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -314,6 +314,9 @@ static void elf_add_symbol(struct elf *e
+       struct list_head *entry;
+       struct rb_node *pnode;
++      INIT_LIST_HEAD(&sym->pv_target);
++      sym->alias = sym;
++
+       sym->type = GELF_ST_TYPE(sym->sym.st_info);
+       sym->bind = GELF_ST_BIND(sym->sym.st_info);
+@@ -375,8 +378,6 @@ static int read_symbols(struct elf *elf)
+                       return -1;
+               }
+               memset(sym, 0, sizeof(*sym));
+-              INIT_LIST_HEAD(&sym->pv_target);
+-              sym->alias = sym;
+               sym->idx = i;
+@@ -540,24 +541,21 @@ static void elf_dirty_reloc_sym(struct e
+ }
+ /*
+- * Move the first global symbol, as per sh_info, into a new, higher symbol
+- * index. This fees up the shndx for a new local symbol.
++ * The libelf API is terrible; gelf_update_sym*() takes a data block relative
++ * index value, *NOT* the symbol index. As such, iterate the data blocks and
++ * adjust index until it fits.
++ *
++ * If no data block is found, allow adding a new data block provided the index
++ * is only one past the end.
+  */
+-static int elf_move_global_symbol(struct elf *elf, struct section *symtab,
+-                                struct section *symtab_shndx)
++static int elf_update_symbol(struct elf *elf, struct section *symtab,
++                           struct section *symtab_shndx, struct symbol *sym)
+ {
+-      Elf_Data *data, *shndx_data = NULL;
+-      Elf32_Word first_non_local;
+-      struct symbol *sym;
+-      Elf_Scn *s;
+-
+-      first_non_local = symtab->sh.sh_info;
+-
+-      sym = find_symbol_by_index(elf, first_non_local);
+-      if (!sym) {
+-              WARN("no non-local symbols !?");
+-              return first_non_local;
+-      }
++      Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF;
++      Elf_Data *symtab_data = NULL, *shndx_data = NULL;
++      Elf64_Xword entsize = symtab->sh.sh_entsize;
++      int max_idx, idx = sym->idx;
++      Elf_Scn *s, *t = NULL;
+       s = elf_getscn(elf->elf, symtab->idx);
+       if (!s) {
+@@ -565,79 +563,124 @@ static int elf_move_global_symbol(struct
+               return -1;
+       }
+-      data = elf_newdata(s);
+-      if (!data) {
+-              WARN_ELF("elf_newdata");
+-              return -1;
++      if (symtab_shndx) {
++              t = elf_getscn(elf->elf, symtab_shndx->idx);
++              if (!t) {
++                      WARN_ELF("elf_getscn");
++                      return -1;
++              }
+       }
+-      data->d_buf = &sym->sym;
+-      data->d_size = sizeof(sym->sym);
+-      data->d_align = 1;
+-      data->d_type = ELF_T_SYM;
++      for (;;) {
++              /* get next data descriptor for the relevant sections */
++              symtab_data = elf_getdata(s, symtab_data);
++              if (t)
++                      shndx_data = elf_getdata(t, shndx_data);
++
++              /* end-of-list */
++              if (!symtab_data) {
++                      void *buf;
++
++                      if (idx) {
++                              /* we don't do holes in symbol tables */
++                              WARN("index out of range");
++                              return -1;
++                      }
+-      sym->idx = symtab->sh.sh_size / sizeof(sym->sym);
+-      elf_dirty_reloc_sym(elf, sym);
++                      /* if @idx == 0, it's the next contiguous entry, create it */
++                      symtab_data = elf_newdata(s);
++                      if (t)
++                              shndx_data = elf_newdata(t);
++
++                      buf = calloc(1, entsize);
++                      if (!buf) {
++                              WARN("malloc");
++                              return -1;
++                      }
+-      symtab->sh.sh_info += 1;
+-      symtab->sh.sh_size += data->d_size;
+-      symtab->changed = true;
++                      symtab_data->d_buf = buf;
++                      symtab_data->d_size = entsize;
++                      symtab_data->d_align = 1;
++                      symtab_data->d_type = ELF_T_SYM;
++
++                      symtab->sh.sh_size += entsize;
++                      symtab->changed = true;
++
++                      if (t) {
++                              shndx_data->d_buf = &sym->sec->idx;
++                              shndx_data->d_size = sizeof(Elf32_Word);
++                              shndx_data->d_align = sizeof(Elf32_Word);
++                              shndx_data->d_type = ELF_T_WORD;
+-      if (symtab_shndx) {
+-              s = elf_getscn(elf->elf, symtab_shndx->idx);
+-              if (!s) {
+-                      WARN_ELF("elf_getscn");
++                              symtab_shndx->sh.sh_size += sizeof(Elf32_Word);
++                              symtab_shndx->changed = true;
++                      }
++
++                      break;
++              }
++
++              /* empty blocks should not happen */
++              if (!symtab_data->d_size) {
++                      WARN("zero size data");
+                       return -1;
+               }
+-              shndx_data = elf_newdata(s);
++              /* is this the right block? */
++              max_idx = symtab_data->d_size / entsize;
++              if (idx < max_idx)
++                      break;
++
++              /* adjust index and try again */
++              idx -= max_idx;
++      }
++
++      /* something went side-ways */
++      if (idx < 0) {
++              WARN("negative index");
++              return -1;
++      }
++
++      /* setup extended section index magic and write the symbol */
++      if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) {
++              sym->sym.st_shndx = shndx;
++              if (!shndx_data)
++                      shndx = 0;
++      } else {
++              sym->sym.st_shndx = SHN_XINDEX;
+               if (!shndx_data) {
+-                      WARN_ELF("elf_newshndx_data");
++                      WARN("no .symtab_shndx");
+                       return -1;
+               }
++      }
+-              shndx_data->d_buf = &sym->sec->idx;
+-              shndx_data->d_size = sizeof(Elf32_Word);
+-              shndx_data->d_align = 4;
+-              shndx_data->d_type = ELF_T_WORD;
+-
+-              symtab_shndx->sh.sh_size += 4;
+-              symtab_shndx->changed = true;
++      if (!gelf_update_symshndx(symtab_data, shndx_data, idx, &sym->sym, shndx)) {
++              WARN_ELF("gelf_update_symshndx");
++              return -1;
+       }
+-      return first_non_local;
++      return 0;
+ }
+ static struct symbol *
+ elf_create_section_symbol(struct elf *elf, struct section *sec)
+ {
+       struct section *symtab, *symtab_shndx;
+-      Elf_Data *shndx_data = NULL;
+-      struct symbol *sym;
+-      Elf32_Word shndx;
++      Elf32_Word first_non_local, new_idx;
++      struct symbol *sym, *old;
+       symtab = find_section_by_name(elf, ".symtab");
+       if (symtab) {
+               symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
+-              if (symtab_shndx)
+-                      shndx_data = symtab_shndx->data;
+       } else {
+               WARN("no .symtab");
+               return NULL;
+       }
+-      sym = malloc(sizeof(*sym));
++      sym = calloc(1, sizeof(*sym));
+       if (!sym) {
+               perror("malloc");
+               return NULL;
+       }
+-      memset(sym, 0, sizeof(*sym));
+-
+-      sym->idx = elf_move_global_symbol(elf, symtab, symtab_shndx);
+-      if (sym->idx < 0) {
+-              WARN("elf_move_global_symbol");
+-              return NULL;
+-      }
+       sym->name = sec->name;
+       sym->sec = sec;
+@@ -647,24 +690,41 @@ elf_create_section_symbol(struct elf *el
+       // st_other 0
+       // st_value 0
+       // st_size 0
+-      shndx = sec->idx;
+-      if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) {
+-              sym->sym.st_shndx = shndx;
+-              if (!shndx_data)
+-                      shndx = 0;
+-      } else {
+-              sym->sym.st_shndx = SHN_XINDEX;
+-              if (!shndx_data) {
+-                      WARN("no .symtab_shndx");
++
++      /*
++       * Move the first global symbol, as per sh_info, into a new, higher
++       * symbol index. This fees up a spot for a new local symbol.
++       */
++      first_non_local = symtab->sh.sh_info;
++      new_idx = symtab->sh.sh_size / symtab->sh.sh_entsize;
++      old = find_symbol_by_index(elf, first_non_local);
++      if (old) {
++              old->idx = new_idx;
++
++              hlist_del(&old->hash);
++              elf_hash_add(symbol, &old->hash, old->idx);
++
++              elf_dirty_reloc_sym(elf, old);
++
++              if (elf_update_symbol(elf, symtab, symtab_shndx, old)) {
++                      WARN("elf_update_symbol move");
+                       return NULL;
+               }
++
++              new_idx = first_non_local;
+       }
+-      if (!gelf_update_symshndx(symtab->data, shndx_data, sym->idx, &sym->sym, shndx)) {
+-              WARN_ELF("gelf_update_symshndx");
++      sym->idx = new_idx;
++      if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) {
++              WARN("elf_update_symbol");
+               return NULL;
+       }
++      /*
++       * Either way, we added a LOCAL symbol.
++       */
++      symtab->sh.sh_info += 1;
++
+       elf_add_symbol(elf, sym);
+       return sym;
index d74ba791010be9cea40494aecda38cb9ac1185c2..687263130f5147c040090876988d367a0258e331 100644 (file)
@@ -616,3 +616,10 @@ f2fs-fix-to-do-sanity-check-on-total_data_blocks.patch
 f2fs-don-t-use-casefolded-comparison-for-.-and.patch
 f2fs-fix-fallocate-to-use-file_modified-to-update-permissions-consistently.patch
 f2fs-fix-to-do-sanity-check-for-inline-inode.patch
+objtool-fix-objtool-regression-on-x32-systems.patch
+objtool-fix-symbol-creation.patch
+wifi-mac80211-fix-use-after-free-in-chanctx-code.patch
+iwlwifi-fw-init-sar-geo-table-only-if-data-is-present.patch
+iwlwifi-mvm-fix-assert-1f04-upon-reconfig.patch
+iwlwifi-mei-clear-the-sap-data-header-before-sending.patch
+iwlwifi-mei-fix-potential-null-ptr-deref.patch
diff --git a/queue-5.17/wifi-mac80211-fix-use-after-free-in-chanctx-code.patch b/queue-5.17/wifi-mac80211-fix-use-after-free-in-chanctx-code.patch
new file mode 100644 (file)
index 0000000..1cc4935
--- /dev/null
@@ -0,0 +1,48 @@
+From 2965c4cdf7ad9ce0796fac5e57debb9519ea721e Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 1 Jun 2022 09:19:36 +0200
+Subject: wifi: mac80211: fix use-after-free in chanctx code
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 2965c4cdf7ad9ce0796fac5e57debb9519ea721e upstream.
+
+In ieee80211_vif_use_reserved_context(), when we have an
+old context and the new context's replace_state is set to
+IEEE80211_CHANCTX_REPLACE_NONE, we free the old context
+in ieee80211_vif_use_reserved_reassign(). Therefore, we
+cannot check the old_ctx anymore, so we should set it to
+NULL after this point.
+
+However, since the new_ctx replace state is clearly not
+IEEE80211_CHANCTX_REPLACES_OTHER, we're not going to do
+anything else in this function and can just return to
+avoid accessing the freed old_ctx.
+
+Cc: stable@vger.kernel.org
+Fixes: 5bcae31d9cb1 ("mac80211: implement multi-vif in-place reservations")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220601091926.df419d91b165.I17a9b3894ff0b8323ce2afdb153b101124c821e5@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/chan.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -1746,12 +1746,9 @@ int ieee80211_vif_use_reserved_context(s
+       if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
+               if (old_ctx)
+-                      err = ieee80211_vif_use_reserved_reassign(sdata);
+-              else
+-                      err = ieee80211_vif_use_reserved_assign(sdata);
++                      return ieee80211_vif_use_reserved_reassign(sdata);
+-              if (err)
+-                      return err;
++              return ieee80211_vif_use_reserved_assign(sdata);
+       }
+       /*