From f66c262ed98a9884565378f3690d03492224ce46 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 10 Apr 2021 15:25:08 +0200 Subject: [PATCH] 5.11-stable patches 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 file-fix-close_range-for-unshare-cloexec.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 --- ...aloop-fix-initialization-of-controls.patch | 51 ++ ...-quirk-for-another-hp-zbook-g5-model.patch | 32 + ...-speaker-amp-setup-on-acer-aspire-e1.patch | 79 +++ ...dvertising-non-working-s24le-support.patch | 61 ++ ...-fix-close_range-for-unshare-cloexec.patch | 73 +++ ...caused-by-repeated-llcp_sock_connect.patch | 44 ++ ...fix-memory-leak-in-llcp_sock_connect.patch | 41 ++ ...-fix-refcount-leak-in-llcp_sock_bind.patch | 45 ++ ...x-refcount-leak-in-llcp_sock_connect.patch | 47 ++ ...st-corruption-when-changing-booleans.patch | 215 +++++++ ...-fix-race-between-old-and-new-sidtab.patch | 554 ++++++++++++++++++ ...-nslot-handling-in-avtab-more-robust.patch | 106 ++++ queue-5.11/series | 14 + ...ange-irq_info-lock-to-raw_spinlock_t.patch | 80 +++ ...up-warn-s-that-can-be-user-triggered.patch | 79 +++ 15 files changed, 1521 insertions(+) create mode 100644 queue-5.11/alsa-aloop-fix-initialization-of-controls.patch create mode 100644 queue-5.11/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch create mode 100644 queue-5.11/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch create mode 100644 queue-5.11/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch create mode 100644 queue-5.11/file-fix-close_range-for-unshare-cloexec.patch create mode 100644 queue-5.11/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch create mode 100644 queue-5.11/nfc-fix-memory-leak-in-llcp_sock_connect.patch create mode 100644 queue-5.11/nfc-fix-refcount-leak-in-llcp_sock_bind.patch create mode 100644 queue-5.11/nfc-fix-refcount-leak-in-llcp_sock_connect.patch create mode 100644 queue-5.11/selinux-fix-cond_list-corruption-when-changing-booleans.patch create mode 100644 queue-5.11/selinux-fix-race-between-old-and-new-sidtab.patch create mode 100644 queue-5.11/selinux-make-nslot-handling-in-avtab-more-robust.patch create mode 100644 queue-5.11/series create mode 100644 queue-5.11/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch create mode 100644 queue-5.11/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch diff --git a/queue-5.11/alsa-aloop-fix-initialization-of-controls.patch b/queue-5.11/alsa-aloop-fix-initialization-of-controls.patch new file mode 100644 index 00000000000..13fc57a421d --- /dev/null +++ b/queue-5.11/alsa-aloop-fix-initialization-of-controls.patch @@ -0,0 +1,51 @@ +From 168632a495f49f33a18c2d502fc249d7610375e9 Mon Sep 17 00:00:00 2001 +From: Jonas Holmberg +Date: Wed, 7 Apr 2021 09:54:28 +0200 +Subject: ALSA: aloop: Fix initialization of controls + +From: Jonas Holmberg + +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 +Reviewed-by: Jaroslav Kysela +Cc: +Link: https://lore.kernel.org/r/20210407075428.2666787-1-jonashg@axis.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch b/queue-5.11/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch new file mode 100644 index 00000000000..879983f8419 --- /dev/null +++ b/queue-5.11/alsa-hda-conexant-apply-quirk-for-another-hp-zbook-g5-model.patch @@ -0,0 +1,32 @@ +From c6423ed2da6214a68527446b5f8e09cf7162b2ce Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 1 Apr 2021 19:13:14 +0200 +Subject: ALSA: hda/conexant: Apply quirk for another HP ZBook G5 model + +From: Takashi Iwai + +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: +Link: https://lore.kernel.org/r/20210401171314.667-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch b/queue-5.11/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch new file mode 100644 index 00000000000..5581e408bc6 --- /dev/null +++ b/queue-5.11/alsa-hda-realtek-fix-speaker-amp-setup-on-acer-aspire-e1.patch @@ -0,0 +1,79 @@ +From c8426b2700b57d2760ff335840a02f66a64b6044 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 7 Apr 2021 11:57:30 +0200 +Subject: ALSA: hda/realtek: Fix speaker amp setup on Acer Aspire E1 + +From: Takashi Iwai + +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: +Link: https://lore.kernel.org/r/20210407095730.12560-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch b/queue-5.11/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch new file mode 100644 index 00000000000..283bf3f6d77 --- /dev/null +++ b/queue-5.11/asoc-intel-atom-stop-advertising-non-working-s24le-support.patch @@ -0,0 +1,61 @@ +From aa65bacdb70e549a81de03ec72338e1047842883 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 24 Mar 2021 14:27:10 +0100 +Subject: ASoC: intel: atom: Stop advertising non working S24LE support + +From: Hans de Goede + +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 +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20210324132711.216152-2-hdegoede@redhat.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/file-fix-close_range-for-unshare-cloexec.patch b/queue-5.11/file-fix-close_range-for-unshare-cloexec.patch new file mode 100644 index 00000000000..e2cd4d068fe --- /dev/null +++ b/queue-5.11/file-fix-close_range-for-unshare-cloexec.patch @@ -0,0 +1,73 @@ +From 9b5b872215fe6d1ca6a1ef411f130bd58e269012 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Fri, 2 Apr 2021 10:29:36 +0200 +Subject: file: fix close_range() for unshare+cloexec + +From: Christian Brauner + +commit 9b5b872215fe6d1ca6a1ef411f130bd58e269012 upstream. + +syzbot reported a bug when putting the last reference to a tasks file +descriptor table. Debugging this showed we didn't recalculate the +current maximum fd number for CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC +after we unshared the file descriptors table. So max_fd could exceed the +current fdtable maximum causing us to set excessive bits. As a concrete +example, let's say the user requested everything from fd 4 to ~0UL to be +closed and their current fdtable size is 256 with their highest open fd +being 4. With CLOSE_RANGE_UNSHARE the caller will end up with a new +fdtable which has room for 64 file descriptors since that is the lowest +fdtable size we accept. But now max_fd will still point to 255 and needs +to be adjusted. Fix this by retrieving the correct maximum fd value in +__range_cloexec(). + +Reported-by: syzbot+283ce5a46486d6acdbaf@syzkaller.appspotmail.com +Fixes: 582f1fb6b721 ("fs, close_range: add flag CLOSE_RANGE_CLOEXEC") +Fixes: fec8a6a69103 ("close_range: unshare all fds for CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC") +Cc: Christoph Hellwig +Cc: Giuseppe Scrivano +Cc: Al Viro +Cc: linux-fsdevel@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/file.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/fs/file.c ++++ b/fs/file.c +@@ -629,17 +629,30 @@ int close_fd(unsigned fd) + } + EXPORT_SYMBOL(close_fd); /* for ksys_close() */ + ++/** ++ * last_fd - return last valid index into fd table ++ * @cur_fds: files struct ++ * ++ * Context: Either rcu read lock or files_lock must be held. ++ * ++ * Returns: Last valid index into fdtable. ++ */ ++static inline unsigned last_fd(struct fdtable *fdt) ++{ ++ return fdt->max_fds - 1; ++} ++ + static inline void __range_cloexec(struct files_struct *cur_fds, + unsigned int fd, unsigned int max_fd) + { + struct fdtable *fdt; + +- if (fd > max_fd) +- return; +- ++ /* make sure we're using the correct maximum value */ + spin_lock(&cur_fds->file_lock); + fdt = files_fdtable(cur_fds); +- bitmap_set(fdt->close_on_exec, fd, max_fd - fd + 1); ++ max_fd = min(last_fd(fdt), max_fd); ++ if (fd <= max_fd) ++ bitmap_set(fdt->close_on_exec, fd, max_fd - fd + 1); + spin_unlock(&cur_fds->file_lock); + } + diff --git a/queue-5.11/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch b/queue-5.11/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch new file mode 100644 index 00000000000..e57f55eedb3 --- /dev/null +++ b/queue-5.11/nfc-avoid-endless-loops-caused-by-repeated-llcp_sock_connect.patch @@ -0,0 +1,44 @@ +From 4b5db93e7f2afbdfe3b78e37879a85290187e6f1 Mon Sep 17 00:00:00 2001 +From: Xiaoming Ni +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 + +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(尹亮)" +Link: https://www.openwall.com/lists/oss-security/2020/11/01/1 +Cc: #v3.11 +Signed-off-by: Xiaoming Ni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/nfc-fix-memory-leak-in-llcp_sock_connect.patch b/queue-5.11/nfc-fix-memory-leak-in-llcp_sock_connect.patch new file mode 100644 index 00000000000..ee0ad0d9b35 --- /dev/null +++ b/queue-5.11/nfc-fix-memory-leak-in-llcp_sock_connect.patch @@ -0,0 +1,41 @@ +From 7574fcdbdcb335763b6b322f6928dc0fd5730451 Mon Sep 17 00:00:00 2001 +From: Xiaoming Ni +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 + +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(尹亮)" +Link: https://www.openwall.com/lists/oss-security/2020/11/01/1 +Cc: #v3.3 +Signed-off-by: Xiaoming Ni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/nfc-fix-refcount-leak-in-llcp_sock_bind.patch b/queue-5.11/nfc-fix-refcount-leak-in-llcp_sock_bind.patch new file mode 100644 index 00000000000..a25a885d24d --- /dev/null +++ b/queue-5.11/nfc-fix-refcount-leak-in-llcp_sock_bind.patch @@ -0,0 +1,45 @@ +From c33b1cc62ac05c1dbb1cdafe2eb66da01c76ca8d Mon Sep 17 00:00:00 2001 +From: Xiaoming Ni +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 + +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(尹亮)" +Link: https://www.openwall.com/lists/oss-security/2020/11/01/1 +Cc: #v3.6 +Signed-off-by: Xiaoming Ni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/nfc-fix-refcount-leak-in-llcp_sock_connect.patch b/queue-5.11/nfc-fix-refcount-leak-in-llcp_sock_connect.patch new file mode 100644 index 00000000000..7d5172bd81d --- /dev/null +++ b/queue-5.11/nfc-fix-refcount-leak-in-llcp_sock_connect.patch @@ -0,0 +1,47 @@ +From 8a4cd82d62b5ec7e5482333a72b58a4eea4979f0 Mon Sep 17 00:00:00 2001 +From: Xiaoming Ni +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 + +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(尹亮)" +Link: https://www.openwall.com/lists/oss-security/2020/11/01/1 +Cc: #v3.6 +Signed-off-by: Xiaoming Ni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/selinux-fix-cond_list-corruption-when-changing-booleans.patch b/queue-5.11/selinux-fix-cond_list-corruption-when-changing-booleans.patch new file mode 100644 index 00000000000..2dca72b175a --- /dev/null +++ b/queue-5.11/selinux-fix-cond_list-corruption-when-changing-booleans.patch @@ -0,0 +1,215 @@ +From d8f5f0ea5b86300390b026b6c6e7836b7150814a Mon Sep 17 00:00:00 2001 +From: Ondrej Mosnacek +Date: Fri, 2 Apr 2021 10:56:19 +0200 +Subject: selinux: fix cond_list corruption when changing booleans + +From: Ondrej Mosnacek + +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 +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/selinux-fix-race-between-old-and-new-sidtab.patch b/queue-5.11/selinux-fix-race-between-old-and-new-sidtab.patch new file mode 100644 index 00000000000..5a6eda92d21 --- /dev/null +++ b/queue-5.11/selinux-fix-race-between-old-and-new-sidtab.patch @@ -0,0 +1,554 @@ +From 9ad6e9cb39c66366bf7b9aece114aca277981a1f Mon Sep 17 00:00:00 2001 +From: Ondrej Mosnacek +Date: Wed, 7 Apr 2021 09:24:43 +0200 +Subject: selinux: fix race between old and new sidtab + +From: Ondrej Mosnacek + +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 +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1551,6 +1551,7 @@ static int security_context_to_sid_core( + if (!str) + goto out; + } ++retry: + rcu_read_lock(); + policy = rcu_dereference(state->policy); + policydb = &policy->policydb; +@@ -1564,6 +1565,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(); +@@ -1713,7 +1723,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; +@@ -1735,6 +1745,8 @@ static int security_compute_sid(struct s + goto out; + } + ++retry: ++ cladatum = NULL; + context_init(&newcontext); + + rcu_read_lock(); +@@ -1879,6 +1891,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); +@@ -2190,6 +2207,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, +@@ -2211,7 +2229,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); +@@ -2355,13 +2379,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; +@@ -2380,6 +2406,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; + } +@@ -2406,13 +2436,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; +@@ -2433,6 +2465,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; + } +@@ -2458,13 +2494,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; +@@ -2485,6 +2523,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; + } +@@ -2508,7 +2550,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)) { +@@ -2516,6 +2558,8 @@ int security_netif_sid(struct selinux_st + return 0; + } + ++retry: ++ rc = 0; + rcu_read_lock(); + policy = rcu_dereference(state->policy); + policydb = &policy->policydb; +@@ -2532,10 +2576,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; + } +@@ -2585,6 +2637,7 @@ int security_node_sid(struct selinux_sta + return 0; + } + ++retry: + rcu_read_lock(); + policy = rcu_dereference(state->policy); + policydb = &policy->policydb; +@@ -2633,6 +2686,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; + } +@@ -2674,18 +2731,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; +@@ -2705,11 +2768,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; +@@ -2721,6 +2779,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) { +@@ -2743,14 +2805,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; +@@ -2763,12 +2825,10 @@ out_unlock: + mysids2[j++] = mysids[i]; + cond_resched(); + } +- rc = 0; + kfree(mysids); + *sids = mysids2; + *nel = j; +-out: +- return rc; ++ return 0; + } + + /** +@@ -2781,6 +2841,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, +@@ -2859,11 +2922,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; + } + +@@ -2886,7 +2951,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; +@@ -2897,6 +2962,8 @@ int security_fs_use(struct selinux_state + return 0; + } + ++retry: ++ rc = 0; + rcu_read_lock(); + policy = rcu_dereference(state->policy); + policydb = &policy->policydb; +@@ -2914,6 +2981,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; + } +@@ -2921,6 +2992,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; +@@ -3130,12 +3205,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(); +@@ -3194,10 +3270,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; + } + +@@ -3794,6 +3874,8 @@ int security_netlbl_secattr_to_sid(struc + return 0; + } + ++retry: ++ rc = 0; + rcu_read_lock(); + policy = rcu_dereference(state->policy); + policydb = &policy->policydb; +@@ -3820,23 +3902,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.11/selinux-make-nslot-handling-in-avtab-more-robust.patch b/queue-5.11/selinux-make-nslot-handling-in-avtab-more-robust.patch new file mode 100644 index 00000000000..b8188b65015 --- /dev/null +++ b/queue-5.11/selinux-make-nslot-handling-in-avtab-more-robust.patch @@ -0,0 +1,106 @@ +From 442dc00f82a9727dc0c48c44f792c168f593c6df Mon Sep 17 00:00:00 2001 +From: Ondrej Mosnacek +Date: Fri, 2 Apr 2021 10:56:18 +0200 +Subject: selinux: make nslot handling in avtab more robust + +From: Ondrej Mosnacek + +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 +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + 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.11/series b/queue-5.11/series new file mode 100644 index 00000000000..f325b8a8db2 --- /dev/null +++ b/queue-5.11/series @@ -0,0 +1,14 @@ +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 +file-fix-close_range-for-unshare-cloexec.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.11/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch b/queue-5.11/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch new file mode 100644 index 00000000000..99dc3d3e2bd --- /dev/null +++ b/queue-5.11/xen-evtchn-change-irq_info-lock-to-raw_spinlock_t.patch @@ -0,0 +1,80 @@ +From d120198bd5ff1d41808b6914e1eb89aff937415c Mon Sep 17 00:00:00 2001 +From: Luca Fancellu +Date: Tue, 6 Apr 2021 11:51:04 +0100 +Subject: xen/evtchn: Change irq_info lock to raw_spinlock_t + +From: Luca Fancellu + +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 +Reviewed-by: Julien Grall +Reviewed-by: Wei Liu +Link: https://lore.kernel.org/r/20210406105105.10141-1-luca.fancellu@arm.com +Signed-off-by: Boris Ostrovsky +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -109,7 +109,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; +@@ -310,7 +310,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) +@@ -463,28 +463,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.11/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch b/queue-5.11/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch new file mode 100644 index 00000000000..93eb497e311 --- /dev/null +++ b/queue-5.11/xfrm-compat-cleanup-warn-s-that-can-be-user-triggered.patch @@ -0,0 +1,79 @@ +From ef19e111337f6c3dca7019a8bad5fbc6fb18d635 Mon Sep 17 00:00:00 2001 +From: Dmitry Safonov +Date: Tue, 30 Mar 2021 00:25:06 +0100 +Subject: xfrm/compat: Cleanup WARN()s that can be user-triggered + +From: Dmitry Safonov + +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" +Cc: Eric Dumazet +Cc: Herbert Xu +Cc: Jakub Kicinski +Cc: Steffen Klassert +Cc: netdev@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Safonov +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + 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; + -- 2.47.3