]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 10 Apr 2021 13:28:54 +0000 (15:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 10 Apr 2021 13:28:54 +0000 (15:28 +0200)
added patches:
alsa-aloop-fix-initialization-of-controls.patch
alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch
alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch
asoc-intel-atom-stop-advertising-non-working-s24le-support.patch
nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch
nfc-fix-memory-leak-in-llcp_sock_connect.patch
nfc-fix-refcount-leak-in-llcp_sock_bind.patch
nfc-fix-refcount-leak-in-llcp_sock_connect.patch
selinux-fix-cond_list-corruption-when-changing-booleans.patch
selinux-fix-race-between-old-and-new-sidtab.patch
selinux-make-nslot-handling-in-avtab-more-robust.patch
xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch
xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch

14 files changed:
queue-5.10/alsa-aloop-fix-initialization-of-controls.patch [new file with mode: 0644]
queue-5.10/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch [new file with mode: 0644]
queue-5.10/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch [new file with mode: 0644]
queue-5.10/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch [new file with mode: 0644]
queue-5.10/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch [new file with mode: 0644]
queue-5.10/nfc-fix-memory-leak-in-llcp_sock_connect.patch [new file with mode: 0644]
queue-5.10/nfc-fix-refcount-leak-in-llcp_sock_bind.patch [new file with mode: 0644]
queue-5.10/nfc-fix-refcount-leak-in-llcp_sock_connect.patch [new file with mode: 0644]
queue-5.10/selinux-fix-cond_list-corruption-when-changing-booleans.patch [new file with mode: 0644]
queue-5.10/selinux-fix-race-between-old-and-new-sidtab.patch [new file with mode: 0644]
queue-5.10/selinux-make-nslot-handling-in-avtab-more-robust.patch [new file with mode: 0644]
queue-5.10/series [new file with mode: 0644]
queue-5.10/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch [new file with mode: 0644]
queue-5.10/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch [new file with mode: 0644]

diff --git a/queue-5.10/alsa-aloop-fix-initialization-of-controls.patch b/queue-5.10/alsa-aloop-fix-initialization-of-controls.patch
new file mode 100644 (file)
index 0000000..13fc57a
--- /dev/null
@@ -0,0 +1,51 @@
+From 168632a495f49f33a18c2d502fc249d7610375e9 Mon Sep 17 00:00:00 2001
+From: Jonas Holmberg <jonashg@axis.com>
+Date: Wed, 7 Apr 2021 09:54:28 +0200
+Subject: ALSA: aloop: Fix initialization of controls
+
+From: Jonas Holmberg <jonashg@axis.com>
+
+commit 168632a495f49f33a18c2d502fc249d7610375e9 upstream.
+
+Add a control to the card before copying the id so that the numid field
+is initialized in the copy. Otherwise the numid field of active_id,
+format_id, rate_id and channels_id will be the same (0) and
+snd_ctl_notify() will not queue the events properly.
+
+Signed-off-by: Jonas Holmberg <jonashg@axis.com>
+Reviewed-by: Jaroslav Kysela <perex@perex.cz>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210407075428.2666787-1-jonashg@axis.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/drivers/aloop.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -1572,6 +1572,14 @@ static int loopback_mixer_new(struct loo
+                                       return -ENOMEM;
+                               kctl->id.device = dev;
+                               kctl->id.subdevice = substr;
++
++                              /* Add the control before copying the id so that
++                               * the numid field of the id is set in the copy.
++                               */
++                              err = snd_ctl_add(card, kctl);
++                              if (err < 0)
++                                      return err;
++
+                               switch (idx) {
+                               case ACTIVE_IDX:
+                                       setup->active_id = kctl->id;
+@@ -1588,9 +1596,6 @@ static int loopback_mixer_new(struct loo
+                               default:
+                                       break;
+                               }
+-                              err = snd_ctl_add(card, kctl);
+-                              if (err < 0)
+-                                      return err;
+                       }
+               }
+       }
diff --git a/queue-5.10/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch b/queue-5.10/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch
new file mode 100644 (file)
index 0000000..879983f
--- /dev/null
@@ -0,0 +1,32 @@
+From c6423ed2da6214a68527446b5f8e09cf7162b2ce Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 1 Apr 2021 19:13:14 +0200
+Subject: ALSA: hda/conexant: Apply quirk for another HP ZBook G5 model
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit c6423ed2da6214a68527446b5f8e09cf7162b2ce upstream.
+
+There is another HP ZBook G5 model with the PCI SSID 103c:844f that
+requires the same quirk for controlling the mute LED.  Add the
+corresponding entry to the quirk table.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=212407
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210401171314.667-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_conexant.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -944,6 +944,7 @@ static const struct snd_pci_quirk cxt506
+       SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
+       SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
++      SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
+       SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x8456, "HP Z2 G4 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE),
diff --git a/queue-5.10/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch b/queue-5.10/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch
new file mode 100644 (file)
index 0000000..5581e40
--- /dev/null
@@ -0,0 +1,79 @@
+From c8426b2700b57d2760ff335840a02f66a64b6044 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 7 Apr 2021 11:57:30 +0200
+Subject: ALSA: hda/realtek: Fix speaker amp setup on Acer Aspire E1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit c8426b2700b57d2760ff335840a02f66a64b6044 upstream.
+
+We've got a report about Acer Aspire E1 (PCI SSID 1025:0840) that
+loses the speaker output after resume.  With the comparison of COEF
+dumps, it was identified that the COEF 0x0d bits 0x6000 corresponds to
+the speaker amp.
+
+This patch adds the specific quirk for the device to restore the COEF
+bits at the codec (re-)initialization.
+
+BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1183869
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210407095730.12560-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -3927,6 +3927,15 @@ static void alc271_fixup_dmic(struct hda
+               snd_hda_sequence_write(codec, verbs);
+ }
++/* Fix the speaker amp after resume, etc */
++static void alc269vb_fixup_aspire_e1_coef(struct hda_codec *codec,
++                                        const struct hda_fixup *fix,
++                                        int action)
++{
++      if (action == HDA_FIXUP_ACT_INIT)
++              alc_update_coef_idx(codec, 0x0d, 0x6000, 0x6000);
++}
++
+ static void alc269_fixup_pcm_44k(struct hda_codec *codec,
+                                const struct hda_fixup *fix, int action)
+ {
+@@ -6301,6 +6310,7 @@ enum {
+       ALC283_FIXUP_HEADSET_MIC,
+       ALC255_FIXUP_MIC_MUTE_LED,
+       ALC282_FIXUP_ASPIRE_V5_PINS,
++      ALC269VB_FIXUP_ASPIRE_E1_COEF,
+       ALC280_FIXUP_HP_GPIO4,
+       ALC286_FIXUP_HP_GPIO_LED,
+       ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
+@@ -6979,6 +6989,10 @@ static const struct hda_fixup alc269_fix
+                       { },
+               },
+       },
++      [ALC269VB_FIXUP_ASPIRE_E1_COEF] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc269vb_fixup_aspire_e1_coef,
++      },
+       [ALC280_FIXUP_HP_GPIO4] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc280_fixup_hp_gpio4,
+@@ -7901,6 +7915,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
+       SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
+       SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
++      SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF),
+       SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK),
+       SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC),
+@@ -8395,6 +8410,7 @@ static const struct hda_model_fixup alc2
+       {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
+       {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
+       {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
++      {.id = ALC269VB_FIXUP_ASPIRE_E1_COEF, .name = "aspire-e1-coef"},
+       {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
+       {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
+       {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
diff --git a/queue-5.10/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch b/queue-5.10/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch
new file mode 100644 (file)
index 0000000..283bf3f
--- /dev/null
@@ -0,0 +1,61 @@
+From aa65bacdb70e549a81de03ec72338e1047842883 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 24 Mar 2021 14:27:10 +0100
+Subject: ASoC: intel: atom: Stop advertising non working S24LE support
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit aa65bacdb70e549a81de03ec72338e1047842883 upstream.
+
+The SST firmware's media and deep-buffer inputs are hardcoded to
+S16LE, the corresponding DAIs don't have a hw_params callback and
+their prepare callback also does not take the format into account.
+
+So far the advertising of non working S24LE support has not caused
+issues because pulseaudio defaults to S16LE, but changing pulse-audio's
+config to use S24LE will result in broken sound.
+
+Pipewire is replacing pulse now and pipewire prefers S24LE over S16LE
+when available, causing the problem of the broken S24LE support to
+come to the surface now.
+
+Cc: stable@vger.kernel.org
+BugLink: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/866
+Fixes: 098c2cd281409 ("ASoC: Intel: Atom: add 24-bit support for media playback and capture")
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20210324132711.216152-2-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/intel/atom/sst-mfld-platform-pcm.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
++++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+@@ -488,14 +488,14 @@ static struct snd_soc_dai_driver sst_pla
+               .channels_min = SST_STEREO,
+               .channels_max = SST_STEREO,
+               .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+-              .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++              .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .capture = {
+               .stream_name = "Headset Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+-              .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++              .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+ },
+ {
+@@ -506,7 +506,7 @@ static struct snd_soc_dai_driver sst_pla
+               .channels_min = SST_STEREO,
+               .channels_max = SST_STEREO,
+               .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+-              .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++              .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+ },
+ {
diff --git a/queue-5.10/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch b/queue-5.10/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch
new file mode 100644 (file)
index 0000000..e57f55e
--- /dev/null
@@ -0,0 +1,44 @@
+From 4b5db93e7f2afbdfe3b78e37879a85290187e6f1 Mon Sep 17 00:00:00 2001
+From: Xiaoming Ni <nixiaoming@huawei.com>
+Date: Thu, 25 Mar 2021 11:51:13 +0800
+Subject: nfc: Avoid endless loops caused by repeated llcp_sock_connect()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiaoming Ni <nixiaoming@huawei.com>
+
+commit 4b5db93e7f2afbdfe3b78e37879a85290187e6f1 upstream.
+
+When sock_wait_state() returns -EINPROGRESS, "sk->sk_state" is
+ LLCP_CONNECTING. In this case, llcp_sock_connect() is repeatedly invoked,
+ nfc_llcp_sock_link() will add sk to local->connecting_sockets twice.
+ sk->sk_node->next will point to itself, that will make an endless loop
+ and hang-up the system.
+To fix it, check whether sk->sk_state is LLCP_CONNECTING in
+ llcp_sock_connect() to avoid repeated invoking.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Reported-by: "kiyin(尹亮)" <kiyin@tencent.com>
+Link: https://www.openwall.com/lists/oss-security/2020/11/01/1
+Cc: <stable@vger.kernel.org> #v3.11
+Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/nfc/llcp_sock.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -673,6 +673,10 @@ static int llcp_sock_connect(struct sock
+               ret = -EISCONN;
+               goto error;
+       }
++      if (sk->sk_state == LLCP_CONNECTING) {
++              ret = -EINPROGRESS;
++              goto error;
++      }
+       dev = nfc_get_device(addr->dev_idx);
+       if (dev == NULL) {
diff --git a/queue-5.10/nfc-fix-memory-leak-in-llcp_sock_connect.patch b/queue-5.10/nfc-fix-memory-leak-in-llcp_sock_connect.patch
new file mode 100644 (file)
index 0000000..ee0ad0d
--- /dev/null
@@ -0,0 +1,41 @@
+From 7574fcdbdcb335763b6b322f6928dc0fd5730451 Mon Sep 17 00:00:00 2001
+From: Xiaoming Ni <nixiaoming@huawei.com>
+Date: Thu, 25 Mar 2021 11:51:12 +0800
+Subject: nfc: fix memory leak in llcp_sock_connect()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiaoming Ni <nixiaoming@huawei.com>
+
+commit 7574fcdbdcb335763b6b322f6928dc0fd5730451 upstream.
+
+In llcp_sock_connect(), use kmemdup to allocate memory for
+ "llcp_sock->service_name". The memory is not released in the sock_unlink
+label of the subsequent failure branch.
+As a result, memory leakage occurs.
+
+fix CVE-2020-25672
+
+Fixes: d646960f7986 ("NFC: Initial LLCP support")
+Reported-by: "kiyin(尹亮)" <kiyin@tencent.com>
+Link: https://www.openwall.com/lists/oss-security/2020/11/01/1
+Cc: <stable@vger.kernel.org> #v3.3
+Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/nfc/llcp_sock.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -746,6 +746,8 @@ static int llcp_sock_connect(struct sock
+ sock_unlink:
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
++      kfree(llcp_sock->service_name);
++      llcp_sock->service_name = NULL;
+ sock_llcp_release:
+       nfc_llcp_put_ssap(local, llcp_sock->ssap);
diff --git a/queue-5.10/nfc-fix-refcount-leak-in-llcp_sock_bind.patch b/queue-5.10/nfc-fix-refcount-leak-in-llcp_sock_bind.patch
new file mode 100644 (file)
index 0000000..a25a885
--- /dev/null
@@ -0,0 +1,45 @@
+From c33b1cc62ac05c1dbb1cdafe2eb66da01c76ca8d Mon Sep 17 00:00:00 2001
+From: Xiaoming Ni <nixiaoming@huawei.com>
+Date: Thu, 25 Mar 2021 11:51:10 +0800
+Subject: nfc: fix refcount leak in llcp_sock_bind()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiaoming Ni <nixiaoming@huawei.com>
+
+commit c33b1cc62ac05c1dbb1cdafe2eb66da01c76ca8d upstream.
+
+nfc_llcp_local_get() is invoked in llcp_sock_bind(),
+but nfc_llcp_local_put() is not invoked in subsequent failure branches.
+As a result, refcount leakage occurs.
+To fix it, add calling nfc_llcp_local_put().
+
+fix CVE-2020-25670
+Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket")
+Reported-by: "kiyin(尹亮)" <kiyin@tencent.com>
+Link: https://www.openwall.com/lists/oss-security/2020/11/01/1
+Cc: <stable@vger.kernel.org> #v3.6
+Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/nfc/llcp_sock.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -108,11 +108,13 @@ static int llcp_sock_bind(struct socket
+                                         llcp_sock->service_name_len,
+                                         GFP_KERNEL);
+       if (!llcp_sock->service_name) {
++              nfc_llcp_local_put(llcp_sock->local);
+               ret = -ENOMEM;
+               goto put_dev;
+       }
+       llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
+       if (llcp_sock->ssap == LLCP_SAP_MAX) {
++              nfc_llcp_local_put(llcp_sock->local);
+               kfree(llcp_sock->service_name);
+               llcp_sock->service_name = NULL;
+               ret = -EADDRINUSE;
diff --git a/queue-5.10/nfc-fix-refcount-leak-in-llcp_sock_connect.patch b/queue-5.10/nfc-fix-refcount-leak-in-llcp_sock_connect.patch
new file mode 100644 (file)
index 0000000..7d5172b
--- /dev/null
@@ -0,0 +1,47 @@
+From 8a4cd82d62b5ec7e5482333a72b58a4eea4979f0 Mon Sep 17 00:00:00 2001
+From: Xiaoming Ni <nixiaoming@huawei.com>
+Date: Thu, 25 Mar 2021 11:51:11 +0800
+Subject: nfc: fix refcount leak in llcp_sock_connect()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiaoming Ni <nixiaoming@huawei.com>
+
+commit 8a4cd82d62b5ec7e5482333a72b58a4eea4979f0 upstream.
+
+nfc_llcp_local_get() is invoked in llcp_sock_connect(),
+but nfc_llcp_local_put() is not invoked in subsequent failure branches.
+As a result, refcount leakage occurs.
+To fix it, add calling nfc_llcp_local_put().
+
+fix CVE-2020-25671
+Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket")
+Reported-by: "kiyin(尹亮)" <kiyin@tencent.com>
+Link: https://www.openwall.com/lists/oss-security/2020/11/01/1
+Cc: <stable@vger.kernel.org> #v3.6
+Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/nfc/llcp_sock.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -704,6 +704,7 @@ static int llcp_sock_connect(struct sock
+       llcp_sock->local = nfc_llcp_local_get(local);
+       llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
+       if (llcp_sock->ssap == LLCP_SAP_MAX) {
++              nfc_llcp_local_put(llcp_sock->local);
+               ret = -ENOMEM;
+               goto put_dev;
+       }
+@@ -748,6 +749,7 @@ sock_unlink:
+ sock_llcp_release:
+       nfc_llcp_put_ssap(local, llcp_sock->ssap);
++      nfc_llcp_local_put(llcp_sock->local);
+ put_dev:
+       nfc_put_device(dev);
diff --git a/queue-5.10/selinux-fix-cond_list-corruption-when-changing-booleans.patch b/queue-5.10/selinux-fix-cond_list-corruption-when-changing-booleans.patch
new file mode 100644 (file)
index 0000000..2dca72b
--- /dev/null
@@ -0,0 +1,215 @@
+From d8f5f0ea5b86300390b026b6c6e7836b7150814a Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Fri, 2 Apr 2021 10:56:19 +0200
+Subject: selinux: fix cond_list corruption when changing booleans
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+commit d8f5f0ea5b86300390b026b6c6e7836b7150814a upstream.
+
+Currently, duplicate_policydb_cond_list() first copies the whole
+conditional avtab and then tries to link to the correct entries in
+cond_dup_av_list() using avtab_search(). However, since the conditional
+avtab may contain multiple entries with the same key, this approach
+often fails to find the right entry, potentially leading to wrong rules
+being activated/deactivated when booleans are changed.
+
+To fix this, instead start with an empty conditional avtab and add the
+individual entries one-by-one while building the new av_lists. This
+approach leads to the correct result, since each entry is present in the
+av_lists exactly once.
+
+The issue can be reproduced with Fedora policy as follows:
+
+    # sesearch -s ftpd_t -t public_content_rw_t -c dir -p create -A
+    allow ftpd_t non_security_file_type:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write }; [ ftpd_full_access ]:True
+    allow ftpd_t public_content_rw_t:dir { add_name create link remove_name rename reparent rmdir setattr unlink watch watch_reads write }; [ ftpd_anon_write ]:True
+    # setsebool ftpd_anon_write=off ftpd_connect_all_unreserved=off ftpd_connect_db=off ftpd_full_access=off
+
+On fixed kernels, the sesearch output is the same after the setsebool
+command:
+
+    # sesearch -s ftpd_t -t public_content_rw_t -c dir -p create -A
+    allow ftpd_t non_security_file_type:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write }; [ ftpd_full_access ]:True
+    allow ftpd_t public_content_rw_t:dir { add_name create link remove_name rename reparent rmdir setattr unlink watch watch_reads write }; [ ftpd_anon_write ]:True
+
+While on the broken kernels, it will be different:
+
+    # sesearch -s ftpd_t -t public_content_rw_t -c dir -p create -A
+    allow ftpd_t non_security_file_type:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write }; [ ftpd_full_access ]:True
+    allow ftpd_t non_security_file_type:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write }; [ ftpd_full_access ]:True
+    allow ftpd_t non_security_file_type:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink watch watch_reads write }; [ ftpd_full_access ]:True
+
+While there, also simplify the computation of nslots. This changes the
+nslots values for nrules 2 or 3 to just two slots instead of 4, which
+makes the sequence more consistent.
+
+Cc: stable@vger.kernel.org
+Fixes: c7c556f1e81b ("selinux: refactor changing booleans")
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ security/selinux/ss/avtab.c       |   86 +++++++++++---------------------------
+ security/selinux/ss/avtab.h       |    2 
+ security/selinux/ss/conditional.c |   12 ++---
+ 3 files changed, 32 insertions(+), 68 deletions(-)
+
+--- a/security/selinux/ss/avtab.c
++++ b/security/selinux/ss/avtab.c
+@@ -308,24 +308,10 @@ void avtab_init(struct avtab *h)
+       h->mask = 0;
+ }
+-int avtab_alloc(struct avtab *h, u32 nrules)
++static int avtab_alloc_common(struct avtab *h, u32 nslot)
+ {
+-      u32 shift = 0;
+-      u32 work = nrules;
+-      u32 nslot;
+-
+-      if (nrules == 0)
+-              goto avtab_alloc_out;
+-
+-      while (work) {
+-              work  = work >> 1;
+-              shift++;
+-      }
+-      if (shift > 2)
+-              shift = shift - 2;
+-      nslot = 1 << shift;
+-      if (nslot > MAX_AVTAB_HASH_BUCKETS)
+-              nslot = MAX_AVTAB_HASH_BUCKETS;
++      if (!nslot)
++              return 0;
+       h->htable = kvcalloc(nslot, sizeof(void *), GFP_KERNEL);
+       if (!h->htable)
+@@ -333,59 +319,37 @@ int avtab_alloc(struct avtab *h, u32 nru
+       h->nslot = nslot;
+       h->mask = nslot - 1;
+-
+-avtab_alloc_out:
+-      pr_debug("SELinux: %d avtab hash slots, %d rules.\n",
+-             h->nslot, nrules);
+       return 0;
+ }
+-int avtab_duplicate(struct avtab *new, struct avtab *orig)
++int avtab_alloc(struct avtab *h, u32 nrules)
+ {
+-      int i;
+-      struct avtab_node *node, *tmp, *tail;
+-
+-      memset(new, 0, sizeof(*new));
++      int rc;
++      u32 nslot = 0;
+-      new->htable = kvcalloc(orig->nslot, sizeof(void *), GFP_KERNEL);
+-      if (!new->htable)
+-              return -ENOMEM;
+-      new->nslot = orig->nslot;
+-      new->mask = orig->mask;
+-
+-      for (i = 0; i < orig->nslot; i++) {
+-              tail = NULL;
+-              for (node = orig->htable[i]; node; node = node->next) {
+-                      tmp = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL);
+-                      if (!tmp)
+-                              goto error;
+-                      tmp->key = node->key;
+-                      if (tmp->key.specified & AVTAB_XPERMS) {
+-                              tmp->datum.u.xperms =
+-                                      kmem_cache_zalloc(avtab_xperms_cachep,
+-                                                      GFP_KERNEL);
+-                              if (!tmp->datum.u.xperms) {
+-                                      kmem_cache_free(avtab_node_cachep, tmp);
+-                                      goto error;
+-                              }
+-                              tmp->datum.u.xperms = node->datum.u.xperms;
+-                      } else
+-                              tmp->datum.u.data = node->datum.u.data;
+-
+-                      if (tail)
+-                              tail->next = tmp;
+-                      else
+-                              new->htable[i] = tmp;
+-
+-                      tail = tmp;
+-                      new->nel++;
++      if (nrules != 0) {
++              u32 shift = 1;
++              u32 work = nrules >> 3;
++              while (work) {
++                      work >>= 1;
++                      shift++;
+               }
++              nslot = 1 << shift;
++              if (nslot > MAX_AVTAB_HASH_BUCKETS)
++                      nslot = MAX_AVTAB_HASH_BUCKETS;
++
++              rc = avtab_alloc_common(h, nslot);
++              if (rc)
++                      return rc;
+       }
++      pr_debug("SELinux: %d avtab hash slots, %d rules.\n", nslot, nrules);
+       return 0;
+-error:
+-      avtab_destroy(new);
+-      return -ENOMEM;
++}
++
++int avtab_alloc_dup(struct avtab *new, const struct avtab *orig)
++{
++      return avtab_alloc_common(new, orig->nslot);
+ }
+ void avtab_hash_eval(struct avtab *h, char *tag)
+--- a/security/selinux/ss/avtab.h
++++ b/security/selinux/ss/avtab.h
+@@ -89,7 +89,7 @@ struct avtab {
+ void avtab_init(struct avtab *h);
+ int avtab_alloc(struct avtab *, u32);
+-int avtab_duplicate(struct avtab *new, struct avtab *orig);
++int avtab_alloc_dup(struct avtab *new, const struct avtab *orig);
+ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
+ void avtab_destroy(struct avtab *h);
+ void avtab_hash_eval(struct avtab *h, char *tag);
+--- a/security/selinux/ss/conditional.c
++++ b/security/selinux/ss/conditional.c
+@@ -605,7 +605,6 @@ static int cond_dup_av_list(struct cond_
+                       struct cond_av_list *orig,
+                       struct avtab *avtab)
+ {
+-      struct avtab_node *avnode;
+       u32 i;
+       memset(new, 0, sizeof(*new));
+@@ -615,10 +614,11 @@ static int cond_dup_av_list(struct cond_
+               return -ENOMEM;
+       for (i = 0; i < orig->len; i++) {
+-              avnode = avtab_search_node(avtab, &orig->nodes[i]->key);
+-              if (WARN_ON(!avnode))
+-                      return -EINVAL;
+-              new->nodes[i] = avnode;
++              new->nodes[i] = avtab_insert_nonunique(avtab,
++                                                     &orig->nodes[i]->key,
++                                                     &orig->nodes[i]->datum);
++              if (!new->nodes[i])
++                      return -ENOMEM;
+               new->len++;
+       }
+@@ -630,7 +630,7 @@ static int duplicate_policydb_cond_list(
+ {
+       int rc, i, j;
+-      rc = avtab_duplicate(&newp->te_cond_avtab, &origp->te_cond_avtab);
++      rc = avtab_alloc_dup(&newp->te_cond_avtab, &origp->te_cond_avtab);
+       if (rc)
+               return rc;
diff --git a/queue-5.10/selinux-fix-race-between-old-and-new-sidtab.patch b/queue-5.10/selinux-fix-race-between-old-and-new-sidtab.patch
new file mode 100644 (file)
index 0000000..2d1943c
--- /dev/null
@@ -0,0 +1,554 @@
+From 9ad6e9cb39c66366bf7b9aece114aca277981a1f Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Wed, 7 Apr 2021 09:24:43 +0200
+Subject: selinux: fix race between old and new sidtab
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+commit 9ad6e9cb39c66366bf7b9aece114aca277981a1f upstream.
+
+Since commit 1b8b31a2e612 ("selinux: convert policy read-write lock to
+RCU"), there is a small window during policy load where the new policy
+pointer has already been installed, but some threads may still be
+holding the old policy pointer in their read-side RCU critical sections.
+This means that there may be conflicting attempts to add a new SID entry
+to both tables via sidtab_context_to_sid().
+
+See also (and the rest of the thread):
+https://lore.kernel.org/selinux/CAFqZXNvfux46_f8gnvVvRYMKoes24nwm2n3sPbMjrB8vKTW00g@mail.gmail.com/
+
+Fix this by installing the new policy pointer under the old sidtab's
+spinlock along with marking the old sidtab as "frozen". Then, if an
+attempt to add new entry to a "frozen" sidtab is detected, make
+sidtab_context_to_sid() return -ESTALE to indicate that a new policy
+has been installed and that the caller will have to abort the policy
+transaction and try again after re-taking the policy pointer (which is
+guaranteed to be a newer policy). This requires adding a retry-on-ESTALE
+logic to all callers of sidtab_context_to_sid(), but fortunately these
+are easy to determine and aren't that many.
+
+This seems to be the simplest solution for this problem, even if it
+looks somewhat ugly. Note that other places in the kernel (e.g.
+do_mknodat() in fs/namei.c) use similar stale-retry patterns, so I think
+it's reasonable.
+
+Cc: stable@vger.kernel.org
+Fixes: 1b8b31a2e612 ("selinux: convert policy read-write lock to RCU")
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ security/selinux/ss/services.c |  157 +++++++++++++++++++++++++++++++----------
+ security/selinux/ss/sidtab.c   |   21 +++++
+ security/selinux/ss/sidtab.h   |    4 +
+ 3 files changed, 145 insertions(+), 37 deletions(-)
+
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -1553,6 +1553,7 @@ static int security_context_to_sid_core(
+               if (!str)
+                       goto out;
+       }
++retry:
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -1566,6 +1567,15 @@ static int security_context_to_sid_core(
+       } else if (rc)
+               goto out_unlock;
+       rc = sidtab_context_to_sid(sidtab, &context, sid);
++      if (rc == -ESTALE) {
++              rcu_read_unlock();
++              if (context.str) {
++                      str = context.str;
++                      context.str = NULL;
++              }
++              context_destroy(&context);
++              goto retry;
++      }
+       context_destroy(&context);
+ out_unlock:
+       rcu_read_unlock();
+@@ -1715,7 +1725,7 @@ static int security_compute_sid(struct s
+       struct selinux_policy *policy;
+       struct policydb *policydb;
+       struct sidtab *sidtab;
+-      struct class_datum *cladatum = NULL;
++      struct class_datum *cladatum;
+       struct context *scontext, *tcontext, newcontext;
+       struct sidtab_entry *sentry, *tentry;
+       struct avtab_key avkey;
+@@ -1737,6 +1747,8 @@ static int security_compute_sid(struct s
+               goto out;
+       }
++retry:
++      cladatum = NULL;
+       context_init(&newcontext);
+       rcu_read_lock();
+@@ -1881,6 +1893,11 @@ static int security_compute_sid(struct s
+       }
+       /* Obtain the sid for the context. */
+       rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid);
++      if (rc == -ESTALE) {
++              rcu_read_unlock();
++              context_destroy(&newcontext);
++              goto retry;
++      }
+ out_unlock:
+       rcu_read_unlock();
+       context_destroy(&newcontext);
+@@ -2192,6 +2209,7 @@ void selinux_policy_commit(struct selinu
+                          struct selinux_load_state *load_state)
+ {
+       struct selinux_policy *oldpolicy, *newpolicy = load_state->policy;
++      unsigned long flags;
+       u32 seqno;
+       oldpolicy = rcu_dereference_protected(state->policy,
+@@ -2213,7 +2231,13 @@ void selinux_policy_commit(struct selinu
+       seqno = newpolicy->latest_granting;
+       /* Install the new policy. */
+-      rcu_assign_pointer(state->policy, newpolicy);
++      if (oldpolicy) {
++              sidtab_freeze_begin(oldpolicy->sidtab, &flags);
++              rcu_assign_pointer(state->policy, newpolicy);
++              sidtab_freeze_end(oldpolicy->sidtab, &flags);
++      } else {
++              rcu_assign_pointer(state->policy, newpolicy);
++      }
+       /* Load the policycaps from the new policy */
+       security_load_policycaps(state, newpolicy);
+@@ -2357,13 +2381,15 @@ int security_port_sid(struct selinux_sta
+       struct policydb *policydb;
+       struct sidtab *sidtab;
+       struct ocontext *c;
+-      int rc = 0;
++      int rc;
+       if (!selinux_initialized(state)) {
+               *out_sid = SECINITSID_PORT;
+               return 0;
+       }
++retry:
++      rc = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2382,6 +2408,10 @@ int security_port_sid(struct selinux_sta
+               if (!c->sid[0]) {
+                       rc = sidtab_context_to_sid(sidtab, &c->context[0],
+                                                  &c->sid[0]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+               }
+@@ -2408,13 +2438,15 @@ int security_ib_pkey_sid(struct selinux_
+       struct policydb *policydb;
+       struct sidtab *sidtab;
+       struct ocontext *c;
+-      int rc = 0;
++      int rc;
+       if (!selinux_initialized(state)) {
+               *out_sid = SECINITSID_UNLABELED;
+               return 0;
+       }
++retry:
++      rc = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2435,6 +2467,10 @@ int security_ib_pkey_sid(struct selinux_
+                       rc = sidtab_context_to_sid(sidtab,
+                                                  &c->context[0],
+                                                  &c->sid[0]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+               }
+@@ -2460,13 +2496,15 @@ int security_ib_endport_sid(struct selin
+       struct policydb *policydb;
+       struct sidtab *sidtab;
+       struct ocontext *c;
+-      int rc = 0;
++      int rc;
+       if (!selinux_initialized(state)) {
+               *out_sid = SECINITSID_UNLABELED;
+               return 0;
+       }
++retry:
++      rc = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2487,6 +2525,10 @@ int security_ib_endport_sid(struct selin
+               if (!c->sid[0]) {
+                       rc = sidtab_context_to_sid(sidtab, &c->context[0],
+                                                  &c->sid[0]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+               }
+@@ -2510,7 +2552,7 @@ int security_netif_sid(struct selinux_st
+       struct selinux_policy *policy;
+       struct policydb *policydb;
+       struct sidtab *sidtab;
+-      int rc = 0;
++      int rc;
+       struct ocontext *c;
+       if (!selinux_initialized(state)) {
+@@ -2518,6 +2560,8 @@ int security_netif_sid(struct selinux_st
+               return 0;
+       }
++retry:
++      rc = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2534,10 +2578,18 @@ int security_netif_sid(struct selinux_st
+               if (!c->sid[0] || !c->sid[1]) {
+                       rc = sidtab_context_to_sid(sidtab, &c->context[0],
+                                                  &c->sid[0]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+                       rc = sidtab_context_to_sid(sidtab, &c->context[1],
+                                                  &c->sid[1]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+               }
+@@ -2587,6 +2639,7 @@ int security_node_sid(struct selinux_sta
+               return 0;
+       }
++retry:
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2635,6 +2688,10 @@ int security_node_sid(struct selinux_sta
+                       rc = sidtab_context_to_sid(sidtab,
+                                                  &c->context[0],
+                                                  &c->sid[0]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+               }
+@@ -2676,18 +2733,24 @@ int security_get_user_sids(struct selinu
+       struct sidtab *sidtab;
+       struct context *fromcon, usercon;
+       u32 *mysids = NULL, *mysids2, sid;
+-      u32 mynel = 0, maxnel = SIDS_NEL;
++      u32 i, j, mynel, maxnel = SIDS_NEL;
+       struct user_datum *user;
+       struct role_datum *role;
+       struct ebitmap_node *rnode, *tnode;
+-      int rc = 0, i, j;
++      int rc;
+       *sids = NULL;
+       *nel = 0;
+       if (!selinux_initialized(state))
+-              goto out;
++              return 0;
++
++      mysids = kcalloc(maxnel, sizeof(*mysids), GFP_KERNEL);
++      if (!mysids)
++              return -ENOMEM;
++retry:
++      mynel = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2707,11 +2770,6 @@ int security_get_user_sids(struct selinu
+       usercon.user = user->value;
+-      rc = -ENOMEM;
+-      mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
+-      if (!mysids)
+-              goto out_unlock;
+-
+       ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
+               role = policydb->role_val_to_struct[i];
+               usercon.role = i + 1;
+@@ -2723,6 +2781,10 @@ int security_get_user_sids(struct selinu
+                               continue;
+                       rc = sidtab_context_to_sid(sidtab, &usercon, &sid);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out_unlock;
+                       if (mynel < maxnel) {
+@@ -2745,14 +2807,14 @@ out_unlock:
+       rcu_read_unlock();
+       if (rc || !mynel) {
+               kfree(mysids);
+-              goto out;
++              return rc;
+       }
+       rc = -ENOMEM;
+       mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
+       if (!mysids2) {
+               kfree(mysids);
+-              goto out;
++              return rc;
+       }
+       for (i = 0, j = 0; i < mynel; i++) {
+               struct av_decision dummy_avd;
+@@ -2765,12 +2827,10 @@ out_unlock:
+                       mysids2[j++] = mysids[i];
+               cond_resched();
+       }
+-      rc = 0;
+       kfree(mysids);
+       *sids = mysids2;
+       *nel = j;
+-out:
+-      return rc;
++      return 0;
+ }
+ /**
+@@ -2783,6 +2843,9 @@ out:
+  * Obtain a SID to use for a file in a filesystem that
+  * cannot support xattr or use a fixed labeling behavior like
+  * transition SIDs or task SIDs.
++ *
++ * WARNING: This function may return -ESTALE, indicating that the caller
++ * must retry the operation after re-acquiring the policy pointer!
+  */
+ static inline int __security_genfs_sid(struct selinux_policy *policy,
+                                      const char *fstype,
+@@ -2861,11 +2924,13 @@ int security_genfs_sid(struct selinux_st
+               return 0;
+       }
+-      rcu_read_lock();
+-      policy = rcu_dereference(state->policy);
+-      retval = __security_genfs_sid(policy,
+-                              fstype, path, orig_sclass, sid);
+-      rcu_read_unlock();
++      do {
++              rcu_read_lock();
++              policy = rcu_dereference(state->policy);
++              retval = __security_genfs_sid(policy, fstype, path,
++                                            orig_sclass, sid);
++              rcu_read_unlock();
++      } while (retval == -ESTALE);
+       return retval;
+ }
+@@ -2888,7 +2953,7 @@ int security_fs_use(struct selinux_state
+       struct selinux_policy *policy;
+       struct policydb *policydb;
+       struct sidtab *sidtab;
+-      int rc = 0;
++      int rc;
+       struct ocontext *c;
+       struct superblock_security_struct *sbsec = sb->s_security;
+       const char *fstype = sb->s_type->name;
+@@ -2899,6 +2964,8 @@ int security_fs_use(struct selinux_state
+               return 0;
+       }
++retry:
++      rc = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -2916,6 +2983,10 @@ int security_fs_use(struct selinux_state
+               if (!c->sid[0]) {
+                       rc = sidtab_context_to_sid(sidtab, &c->context[0],
+                                                  &c->sid[0]);
++                      if (rc == -ESTALE) {
++                              rcu_read_unlock();
++                              goto retry;
++                      }
+                       if (rc)
+                               goto out;
+               }
+@@ -2923,6 +2994,10 @@ int security_fs_use(struct selinux_state
+       } else {
+               rc = __security_genfs_sid(policy, fstype, "/",
+                                       SECCLASS_DIR, &sbsec->sid);
++              if (rc == -ESTALE) {
++                      rcu_read_unlock();
++                      goto retry;
++              }
+               if (rc) {
+                       sbsec->behavior = SECURITY_FS_USE_NONE;
+                       rc = 0;
+@@ -3132,12 +3207,13 @@ int security_sid_mls_copy(struct selinux
+       u32 len;
+       int rc;
+-      rc = 0;
+       if (!selinux_initialized(state)) {
+               *new_sid = sid;
+-              goto out;
++              return 0;
+       }
++retry:
++      rc = 0;
+       context_init(&newcon);
+       rcu_read_lock();
+@@ -3196,10 +3272,14 @@ int security_sid_mls_copy(struct selinux
+               }
+       }
+       rc = sidtab_context_to_sid(sidtab, &newcon, new_sid);
++      if (rc == -ESTALE) {
++              rcu_read_unlock();
++              context_destroy(&newcon);
++              goto retry;
++      }
+ out_unlock:
+       rcu_read_unlock();
+       context_destroy(&newcon);
+-out:
+       return rc;
+ }
+@@ -3796,6 +3876,8 @@ int security_netlbl_secattr_to_sid(struc
+               return 0;
+       }
++retry:
++      rc = 0;
+       rcu_read_lock();
+       policy = rcu_dereference(state->policy);
+       policydb = &policy->policydb;
+@@ -3822,23 +3904,24 @@ int security_netlbl_secattr_to_sid(struc
+                               goto out;
+               }
+               rc = -EIDRM;
+-              if (!mls_context_isvalid(policydb, &ctx_new))
+-                      goto out_free;
++              if (!mls_context_isvalid(policydb, &ctx_new)) {
++                      ebitmap_destroy(&ctx_new.range.level[0].cat);
++                      goto out;
++              }
+               rc = sidtab_context_to_sid(sidtab, &ctx_new, sid);
++              ebitmap_destroy(&ctx_new.range.level[0].cat);
++              if (rc == -ESTALE) {
++                      rcu_read_unlock();
++                      goto retry;
++              }
+               if (rc)
+-                      goto out_free;
++                      goto out;
+               security_netlbl_cache_add(secattr, *sid);
+-
+-              ebitmap_destroy(&ctx_new.range.level[0].cat);
+       } else
+               *sid = SECSID_NULL;
+-      rcu_read_unlock();
+-      return 0;
+-out_free:
+-      ebitmap_destroy(&ctx_new.range.level[0].cat);
+ out:
+       rcu_read_unlock();
+       return rc;
+--- a/security/selinux/ss/sidtab.c
++++ b/security/selinux/ss/sidtab.c
+@@ -39,6 +39,7 @@ int sidtab_init(struct sidtab *s)
+       for (i = 0; i < SECINITSID_NUM; i++)
+               s->isids[i].set = 0;
++      s->frozen = false;
+       s->count = 0;
+       s->convert = NULL;
+       hash_init(s->context_to_sid);
+@@ -281,6 +282,15 @@ int sidtab_context_to_sid(struct sidtab
+       if (*sid)
+               goto out_unlock;
++      if (unlikely(s->frozen)) {
++              /*
++               * This sidtab is now frozen - tell the caller to abort and
++               * get the new one.
++               */
++              rc = -ESTALE;
++              goto out_unlock;
++      }
++
+       count = s->count;
+       convert = s->convert;
+@@ -474,6 +484,17 @@ void sidtab_cancel_convert(struct sidtab
+       spin_unlock_irqrestore(&s->lock, flags);
+ }
++void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock)
++{
++      spin_lock_irqsave(&s->lock, *flags);
++      s->frozen = true;
++      s->convert = NULL;
++}
++void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock)
++{
++      spin_unlock_irqrestore(&s->lock, *flags);
++}
++
+ static void sidtab_destroy_entry(struct sidtab_entry *entry)
+ {
+       context_destroy(&entry->context);
+--- a/security/selinux/ss/sidtab.h
++++ b/security/selinux/ss/sidtab.h
+@@ -86,6 +86,7 @@ struct sidtab {
+       u32 count;
+       /* access only under spinlock */
+       struct sidtab_convert_params *convert;
++      bool frozen;
+       spinlock_t lock;
+ #if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0
+@@ -125,6 +126,9 @@ int sidtab_convert(struct sidtab *s, str
+ void sidtab_cancel_convert(struct sidtab *s);
++void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock);
++void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock);
++
+ int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid);
+ void sidtab_destroy(struct sidtab *s);
diff --git a/queue-5.10/selinux-make-nslot-handling-in-avtab-more-robust.patch b/queue-5.10/selinux-make-nslot-handling-in-avtab-more-robust.patch
new file mode 100644 (file)
index 0000000..b8188b6
--- /dev/null
@@ -0,0 +1,106 @@
+From 442dc00f82a9727dc0c48c44f792c168f593c6df Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Fri, 2 Apr 2021 10:56:18 +0200
+Subject: selinux: make nslot handling in avtab more robust
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+commit 442dc00f82a9727dc0c48c44f792c168f593c6df upstream.
+
+1. Make sure all fileds are initialized in avtab_init().
+2. Slightly refactor avtab_alloc() to use the above fact.
+3. Use h->nslot == 0 as a sentinel in the access functions to prevent
+   dereferencing h->htable when it's not allocated.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ security/selinux/ss/avtab.c |   21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/security/selinux/ss/avtab.c
++++ b/security/selinux/ss/avtab.c
+@@ -109,7 +109,7 @@ static int avtab_insert(struct avtab *h,
+       struct avtab_node *prev, *cur, *newnode;
+       u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+-      if (!h)
++      if (!h || !h->nslot)
+               return -EINVAL;
+       hvalue = avtab_hash(key, h->mask);
+@@ -154,7 +154,7 @@ avtab_insert_nonunique(struct avtab *h,
+       struct avtab_node *prev, *cur;
+       u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+-      if (!h)
++      if (!h || !h->nslot)
+               return NULL;
+       hvalue = avtab_hash(key, h->mask);
+       for (prev = NULL, cur = h->htable[hvalue];
+@@ -184,7 +184,7 @@ struct avtab_datum *avtab_search(struct
+       struct avtab_node *cur;
+       u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+-      if (!h)
++      if (!h || !h->nslot)
+               return NULL;
+       hvalue = avtab_hash(key, h->mask);
+@@ -220,7 +220,7 @@ avtab_search_node(struct avtab *h, struc
+       struct avtab_node *cur;
+       u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+-      if (!h)
++      if (!h || !h->nslot)
+               return NULL;
+       hvalue = avtab_hash(key, h->mask);
+@@ -295,6 +295,7 @@ void avtab_destroy(struct avtab *h)
+       }
+       kvfree(h->htable);
+       h->htable = NULL;
++      h->nel = 0;
+       h->nslot = 0;
+       h->mask = 0;
+ }
+@@ -303,14 +304,15 @@ void avtab_init(struct avtab *h)
+ {
+       h->htable = NULL;
+       h->nel = 0;
++      h->nslot = 0;
++      h->mask = 0;
+ }
+ int avtab_alloc(struct avtab *h, u32 nrules)
+ {
+-      u32 mask = 0;
+       u32 shift = 0;
+       u32 work = nrules;
+-      u32 nslot = 0;
++      u32 nslot;
+       if (nrules == 0)
+               goto avtab_alloc_out;
+@@ -324,16 +326,15 @@ int avtab_alloc(struct avtab *h, u32 nru
+       nslot = 1 << shift;
+       if (nslot > MAX_AVTAB_HASH_BUCKETS)
+               nslot = MAX_AVTAB_HASH_BUCKETS;
+-      mask = nslot - 1;
+       h->htable = kvcalloc(nslot, sizeof(void *), GFP_KERNEL);
+       if (!h->htable)
+               return -ENOMEM;
+- avtab_alloc_out:
+-      h->nel = 0;
+       h->nslot = nslot;
+-      h->mask = mask;
++      h->mask = nslot - 1;
++
++avtab_alloc_out:
+       pr_debug("SELinux: %d avtab hash slots, %d rules.\n",
+              h->nslot, nrules);
+       return 0;
diff --git a/queue-5.10/series b/queue-5.10/series
new file mode 100644 (file)
index 0000000..60bbbe5
--- /dev/null
@@ -0,0 +1,13 @@
+xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch
+alsa-aloop-fix-initialization-of-controls.patch
+alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch
+alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch
+asoc-intel-atom-stop-advertising-non-working-s24le-support.patch
+nfc-fix-refcount-leak-in-llcp_sock_bind.patch
+nfc-fix-refcount-leak-in-llcp_sock_connect.patch
+nfc-fix-memory-leak-in-llcp_sock_connect.patch
+nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch
+selinux-make-nslot-handling-in-avtab-more-robust.patch
+selinux-fix-cond_list-corruption-when-changing-booleans.patch
+selinux-fix-race-between-old-and-new-sidtab.patch
+xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch
diff --git a/queue-5.10/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch b/queue-5.10/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch
new file mode 100644 (file)
index 0000000..7862565
--- /dev/null
@@ -0,0 +1,80 @@
+From d120198bd5ff1d41808b6914e1eb89aff937415c Mon Sep 17 00:00:00 2001
+From: Luca Fancellu <luca.fancellu@arm.com>
+Date: Tue, 6 Apr 2021 11:51:04 +0100
+Subject: xen/evtchn: Change irq_info lock to raw_spinlock_t
+
+From: Luca Fancellu <luca.fancellu@arm.com>
+
+commit d120198bd5ff1d41808b6914e1eb89aff937415c upstream.
+
+Unmask operation must be called with interrupt disabled,
+on preempt_rt spin_lock_irqsave/spin_unlock_irqrestore
+don't disable/enable interrupts, so use raw_* implementation
+and change lock variable in struct irq_info from spinlock_t
+to raw_spinlock_t
+
+Cc: stable@vger.kernel.org
+Fixes: 25da4618af24 ("xen/events: don't unmask an event channel when an eoi is pending")
+Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
+Reviewed-by: Julien Grall <jgrall@amazon.com>
+Reviewed-by: Wei Liu <wei.liu@kernel.org>
+Link: https://lore.kernel.org/r/20210406105105.10141-1-luca.fancellu@arm.com
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/events/events_base.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -108,7 +108,7 @@ struct irq_info {
+       unsigned short eoi_cpu; /* EOI must happen on this cpu-1 */
+       unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */
+       u64 eoi_time;           /* Time in jiffies when to EOI. */
+-      spinlock_t lock;
++      raw_spinlock_t lock;
+       union {
+               unsigned short virq;
+@@ -280,7 +280,7 @@ static int xen_irq_info_common_setup(str
+       info->evtchn = evtchn;
+       info->cpu = cpu;
+       info->mask_reason = EVT_MASK_REASON_EXPLICIT;
+-      spin_lock_init(&info->lock);
++      raw_spin_lock_init(&info->lock);
+       ret = set_evtchn_to_irq(evtchn, irq);
+       if (ret < 0)
+@@ -432,28 +432,28 @@ static void do_mask(struct irq_info *inf
+ {
+       unsigned long flags;
+-      spin_lock_irqsave(&info->lock, flags);
++      raw_spin_lock_irqsave(&info->lock, flags);
+       if (!info->mask_reason)
+               mask_evtchn(info->evtchn);
+       info->mask_reason |= reason;
+-      spin_unlock_irqrestore(&info->lock, flags);
++      raw_spin_unlock_irqrestore(&info->lock, flags);
+ }
+ static void do_unmask(struct irq_info *info, u8 reason)
+ {
+       unsigned long flags;
+-      spin_lock_irqsave(&info->lock, flags);
++      raw_spin_lock_irqsave(&info->lock, flags);
+       info->mask_reason &= ~reason;
+       if (!info->mask_reason)
+               unmask_evtchn(info->evtchn);
+-      spin_unlock_irqrestore(&info->lock, flags);
++      raw_spin_unlock_irqrestore(&info->lock, flags);
+ }
+ #ifdef CONFIG_X86
diff --git a/queue-5.10/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch b/queue-5.10/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch
new file mode 100644 (file)
index 0000000..93eb497
--- /dev/null
@@ -0,0 +1,79 @@
+From ef19e111337f6c3dca7019a8bad5fbc6fb18d635 Mon Sep 17 00:00:00 2001
+From: Dmitry Safonov <dima@arista.com>
+Date: Tue, 30 Mar 2021 00:25:06 +0100
+Subject: xfrm/compat: Cleanup WARN()s that can be user-triggered
+
+From: Dmitry Safonov <dima@arista.com>
+
+commit ef19e111337f6c3dca7019a8bad5fbc6fb18d635 upstream.
+
+Replace WARN_ONCE() that can be triggered from userspace with
+pr_warn_once(). Those still give user a hint what's the issue.
+
+I've left WARN()s that are not possible to trigger with current
+code-base and that would mean that the code has issues:
+- relying on current compat_msg_min[type] <= xfrm_msg_min[type]
+- expected 4-byte padding size difference between
+  compat_msg_min[type] and xfrm_msg_min[type]
+- compat_policy[type].len <= xfrma_policy[type].len
+(for every type)
+
+Reported-by: syzbot+834ffd1afc7212eb8147@syzkaller.appspotmail.com
+Fixes: 5f3eea6b7e8f ("xfrm/compat: Attach xfrm dumps to 64=>32 bit translator")
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: netdev@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Safonov <dima@arista.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_compat.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/net/xfrm/xfrm_compat.c
++++ b/net/xfrm/xfrm_compat.c
+@@ -216,7 +216,7 @@ static struct nlmsghdr *xfrm_nlmsg_put_c
+       case XFRM_MSG_GETSADINFO:
+       case XFRM_MSG_GETSPDINFO:
+       default:
+-              WARN_ONCE(1, "unsupported nlmsg_type %d", nlh_src->nlmsg_type);
++              pr_warn_once("unsupported nlmsg_type %d\n", nlh_src->nlmsg_type);
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+@@ -277,7 +277,7 @@ static int xfrm_xlate64_attr(struct sk_b
+               return xfrm_nla_cpy(dst, src, nla_len(src));
+       default:
+               BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID);
+-              WARN_ONCE(1, "unsupported nla_type %d", src->nla_type);
++              pr_warn_once("unsupported nla_type %d\n", src->nla_type);
+               return -EOPNOTSUPP;
+       }
+ }
+@@ -315,8 +315,10 @@ static int xfrm_alloc_compat(struct sk_b
+       struct sk_buff *new = NULL;
+       int err;
+-      if (WARN_ON_ONCE(type >= ARRAY_SIZE(xfrm_msg_min)))
++      if (type >= ARRAY_SIZE(xfrm_msg_min)) {
++              pr_warn_once("unsupported nlmsg_type %d\n", nlh_src->nlmsg_type);
+               return -EOPNOTSUPP;
++      }
+       if (skb_shinfo(skb)->frag_list == NULL) {
+               new = alloc_skb(skb->len + skb_tailroom(skb), GFP_ATOMIC);
+@@ -378,6 +380,10 @@ static int xfrm_attr_cpy32(void *dst, si
+       struct nlmsghdr *nlmsg = dst;
+       struct nlattr *nla;
++      /* xfrm_user_rcv_msg_compat() relies on fact that 32-bit messages
++       * have the same len or shorted than 64-bit ones.
++       * 32-bit translation that is bigger than 64-bit original is unexpected.
++       */
+       if (WARN_ON_ONCE(copy_len > payload))
+               copy_len = payload;