From: Greg Kroah-Hartman Date: Sun, 5 Nov 2017 14:43:59 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v3.18.80~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6b503edc883beedaf9a12e7e6812b85691901ff1;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: alsa-seq-fix-nested-rwsem-annotation-for-lockdep-splat.patch alsa-timer-add-missing-mutex-lock-for-compat-ioctls.patch arm-8715-1-add-a-private-asm-unaligned.h.patch arm64-ensure-__dump_instr-checks-addr_limit.patch asoc-adau17x1-workaround-for-noise-bug-in-adc.patch cifs-check-maxpathnamecomponentlength-0-before-using-it.patch keys-fix-out-of-bounds-read-during-asn.1-parsing.patch keys-return-full-count-in-keyring_read-if-buffer-is-too-small.patch --- diff --git a/queue-3.18/alsa-seq-fix-nested-rwsem-annotation-for-lockdep-splat.patch b/queue-3.18/alsa-seq-fix-nested-rwsem-annotation-for-lockdep-splat.patch new file mode 100644 index 00000000000..a4a65aac568 --- /dev/null +++ b/queue-3.18/alsa-seq-fix-nested-rwsem-annotation-for-lockdep-splat.patch @@ -0,0 +1,40 @@ +From 1f20f9ff57ca23b9f5502fca85ce3977e8496cb1 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 29 Oct 2017 11:10:43 +0100 +Subject: ALSA: seq: Fix nested rwsem annotation for lockdep splat + +From: Takashi Iwai + +commit 1f20f9ff57ca23b9f5502fca85ce3977e8496cb1 upstream. + +syzkaller reported the lockdep splat due to the possible deadlock of +grp->list_mutex of each sequencer client object. Actually this is +rather a false-positive report due to the missing nested lock +annotations. The sequencer client may deliver the event directly to +another client which takes another own lock. + +For addressing this issue, this patch replaces the simple down_read() +with down_read_nested(). As a lock subclass, the already existing +"hop" can be re-used, which indicates the depth of the call. + +Reference: http://lkml.kernel.org/r/089e082686ac9b482e055c832617@google.com +Reported-by: syzbot +Reported-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/seq_clientmgr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -676,7 +676,7 @@ static int deliver_to_subscribers(struct + if (atomic) + read_lock(&grp->list_lock); + else +- down_read(&grp->list_mutex); ++ down_read_nested(&grp->list_mutex, hop); + list_for_each_entry(subs, &grp->list_head, src_list) { + /* both ports ready? */ + if (atomic_read(&subs->ref_count) != 2) diff --git a/queue-3.18/alsa-timer-add-missing-mutex-lock-for-compat-ioctls.patch b/queue-3.18/alsa-timer-add-missing-mutex-lock-for-compat-ioctls.patch new file mode 100644 index 00000000000..43033bea995 --- /dev/null +++ b/queue-3.18/alsa-timer-add-missing-mutex-lock-for-compat-ioctls.patch @@ -0,0 +1,65 @@ +From 79fb0518fec8c8b4ea7f1729f54f293724b3dbb0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 29 Oct 2017 11:02:04 +0100 +Subject: ALSA: timer: Add missing mutex lock for compat ioctls + +From: Takashi Iwai + +commit 79fb0518fec8c8b4ea7f1729f54f293724b3dbb0 upstream. + +The races among ioctl and other operations were protected by the +commit af368027a49a ("ALSA: timer: Fix race among timer ioctls") and +later fixes, but one code path was forgotten in the scenario: the +32bit compat ioctl. As syzkaller recently spotted, a very similar +use-after-free may happen with the combination of compat ioctls. + +The fix is simply to apply the same ioctl_lock to the compat_ioctl +callback, too. + +Fixes: af368027a49a ("ALSA: timer: Fix race among timer ioctls") +Reference: http://lkml.kernel.org/r/089e082686ac9b482e055c832617@google.com +Reported-by: syzbot +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer_compat.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/sound/core/timer_compat.c ++++ b/sound/core/timer_compat.c +@@ -106,7 +106,8 @@ enum { + #endif /* CONFIG_X86_X32 */ + }; + +-static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) ++static long __snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, ++ unsigned long arg) + { + void __user *argp = compat_ptr(arg); + +@@ -127,7 +128,7 @@ static long snd_timer_user_ioctl_compat( + case SNDRV_TIMER_IOCTL_PAUSE: + case SNDRV_TIMER_IOCTL_PAUSE_OLD: + case SNDRV_TIMER_IOCTL_NEXT_DEVICE: +- return snd_timer_user_ioctl(file, cmd, (unsigned long)argp); ++ return __snd_timer_user_ioctl(file, cmd, (unsigned long)argp); + case SNDRV_TIMER_IOCTL_INFO32: + return snd_timer_user_info_compat(file, argp); + case SNDRV_TIMER_IOCTL_STATUS32: +@@ -139,3 +140,15 @@ static long snd_timer_user_ioctl_compat( + } + return -ENOIOCTLCMD; + } ++ ++static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct snd_timer_user *tu = file->private_data; ++ long ret; ++ ++ mutex_lock(&tu->ioctl_lock); ++ ret = __snd_timer_user_ioctl_compat(file, cmd, arg); ++ mutex_unlock(&tu->ioctl_lock); ++ return ret; ++} diff --git a/queue-3.18/arm-8715-1-add-a-private-asm-unaligned.h.patch b/queue-3.18/arm-8715-1-add-a-private-asm-unaligned.h.patch new file mode 100644 index 00000000000..5680329effc --- /dev/null +++ b/queue-3.18/arm-8715-1-add-a-private-asm-unaligned.h.patch @@ -0,0 +1,88 @@ +From 1cce91dfc8f7990ca3aea896bfb148f240b12860 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 20 Oct 2017 21:17:05 +0100 +Subject: ARM: 8715/1: add a private asm/unaligned.h + +From: Arnd Bergmann + +commit 1cce91dfc8f7990ca3aea896bfb148f240b12860 upstream. + +The asm-generic/unaligned.h header provides two different implementations +for accessing unaligned variables: the access_ok.h version used when +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is set pretends that all pointers +are in fact aligned, while the le_struct.h version convinces gcc that the +alignment of a pointer is '1', to make it issue the correct load/store +instructions depending on the architecture flags. + +On ARMv5 and older, we always use the second version, to let the compiler +use byte accesses. On ARMv6 and newer, we currently use the access_ok.h +version, so the compiler can use any instruction including stm/ldm and +ldrd/strd that will cause an alignment trap. This trap can significantly +impact performance when we have to do a lot of fixups and, worse, has +led to crashes in the LZ4 decompressor code that does not have a trap +handler. + +This adds an ARM specific version of asm/unaligned.h that uses the +le_struct.h/be_struct.h implementation unconditionally. This should lead +to essentially the same code on ARMv6+ as before, with the exception of +using regular load/store instructions instead of the trapping instructions +multi-register variants. + +The crash in the LZ4 decompressor code was probably introduced by the +patch replacing the LZ4 implementation, commit 4e1a33b105dd ("lib: update +LZ4 compressor module"), so linux-4.11 and higher would be affected most. +However, we probably want to have this backported to all older stable +kernels as well, to help with the performance issues. + +There are two follow-ups that I think we should also work on, but not +backport to stable kernels, first to change the asm-generic version of +the header to remove the ARM special case, and second to review all +other uses of CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS to see if they +might be affected by the same problem on ARM. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/include/asm/Kbuild | 1 - + arch/arm/include/asm/unaligned.h | 27 +++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+), 1 deletion(-) + +--- a/arch/arm/include/asm/Kbuild ++++ b/arch/arm/include/asm/Kbuild +@@ -37,4 +37,3 @@ generic-y += termbits.h + generic-y += termios.h + generic-y += timex.h + generic-y += trace_clock.h +-generic-y += unaligned.h +--- /dev/null ++++ b/arch/arm/include/asm/unaligned.h +@@ -0,0 +1,27 @@ ++#ifndef __ASM_ARM_UNALIGNED_H ++#define __ASM_ARM_UNALIGNED_H ++ ++/* ++ * We generally want to set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS on ARMv6+, ++ * but we don't want to use linux/unaligned/access_ok.h since that can lead ++ * to traps on unaligned stm/ldm or strd/ldrd. ++ */ ++#include ++ ++#if defined(__LITTLE_ENDIAN) ++# include ++# include ++# include ++# define get_unaligned __get_unaligned_le ++# define put_unaligned __put_unaligned_le ++#elif defined(__BIG_ENDIAN) ++# include ++# include ++# include ++# define get_unaligned __get_unaligned_be ++# define put_unaligned __put_unaligned_be ++#else ++# error need to define endianess ++#endif ++ ++#endif /* __ASM_ARM_UNALIGNED_H */ diff --git a/queue-3.18/arm64-ensure-__dump_instr-checks-addr_limit.patch b/queue-3.18/arm64-ensure-__dump_instr-checks-addr_limit.patch new file mode 100644 index 00000000000..c6186d5cc28 --- /dev/null +++ b/queue-3.18/arm64-ensure-__dump_instr-checks-addr_limit.patch @@ -0,0 +1,39 @@ +From 7a7003b1da010d2b0d1dc8bf21c10f5c73b389f1 Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Thu, 2 Nov 2017 16:12:03 +0000 +Subject: arm64: ensure __dump_instr() checks addr_limit + +From: Mark Rutland + +commit 7a7003b1da010d2b0d1dc8bf21c10f5c73b389f1 upstream. + +It's possible for a user to deliberately trigger __dump_instr with a +chosen kernel address. + +Let's avoid problems resulting from this by using get_user() rather than +__get_user(), ensuring that we don't erroneously access kernel memory. + +Where we use __dump_instr() on kernel text, we already switch to +KERNEL_DS, so this shouldn't adversely affect those cases. + +Fixes: 60ffc30d5652810d ("arm64: Exception handling") +Acked-by: Will Deacon +Signed-off-by: Mark Rutland +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/traps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -115,7 +115,7 @@ static void dump_instr(const char *lvl, + for (i = -4; i < 1; i++) { + unsigned int val, bad; + +- bad = __get_user(val, &((u32 *)addr)[i]); ++ bad = get_user(val, &((u32 *)addr)[i]); + + if (!bad) + p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val); diff --git a/queue-3.18/asoc-adau17x1-workaround-for-noise-bug-in-adc.patch b/queue-3.18/asoc-adau17x1-workaround-for-noise-bug-in-adc.patch new file mode 100644 index 00000000000..01f8f4dbdc4 --- /dev/null +++ b/queue-3.18/asoc-adau17x1-workaround-for-noise-bug-in-adc.patch @@ -0,0 +1,83 @@ +From 1e6f4fc06f6411adf98bbbe7fcd79442cd2b2a75 Mon Sep 17 00:00:00 2001 +From: Ricard Wanderlof +Date: Thu, 7 Sep 2017 15:31:38 +0200 +Subject: ASoC: adau17x1: Workaround for noise bug in ADC + +From: Ricard Wanderlof + +commit 1e6f4fc06f6411adf98bbbe7fcd79442cd2b2a75 upstream. + +The ADC in the ADAU1361 (and possibly other Analog Devices codecs) +exhibits a cyclic variation in the noise floor (in our test setup between +-87 and -93 dB), a new value being attained within this range whenever a +new capture stream is started. The cycle repeats after about 10 or 11 +restarts. + +The workaround recommended by the manufacturer is to toggle the ADOSR bit +in the Converter Control 0 register each time a new capture stream is +started. + +I have verified that the patch fixes this problem on the ADAU1361, and +according to the manufacturer toggling the bit in question in this manner +will at least have no detrimental effect on other chips served by this +driver. + +Signed-off-by: Ricard Wanderlof +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/adau17x1.c | 24 +++++++++++++++++++++++- + sound/soc/codecs/adau17x1.h | 2 ++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +--- a/sound/soc/codecs/adau17x1.c ++++ b/sound/soc/codecs/adau17x1.c +@@ -88,6 +88,27 @@ static int adau17x1_pll_event(struct snd + return 0; + } + ++static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); ++ struct adau *adau = snd_soc_codec_get_drvdata(codec); ++ ++ /* ++ * If we are capturing, toggle the ADOSR bit in Converter Control 0 to ++ * avoid losing SNR (workaround from ADI). This must be done after ++ * the ADC(s) have been enabled. According to the data sheet, it is ++ * normally illegal to set this bit when the sampling rate is 96 kHz, ++ * but according to ADI it is acceptable for this workaround. ++ */ ++ regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, ++ ADAU17X1_CONVERTER0_ADOSR, ADAU17X1_CONVERTER0_ADOSR); ++ regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, ++ ADAU17X1_CONVERTER0_ADOSR, 0); ++ ++ return 0; ++} ++ + static const char * const adau17x1_mono_stereo_text[] = { + "Stereo", + "Mono Left Channel (L+R)", +@@ -119,7 +140,8 @@ static const struct snd_soc_dapm_widget + SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0, + &adau17x1_dac_mode_mux), + +- SND_SOC_DAPM_ADC("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0), ++ SND_SOC_DAPM_ADC_E("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0, ++ adau17x1_adc_fixup, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0), + SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0), + SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0), +--- a/sound/soc/codecs/adau17x1.h ++++ b/sound/soc/codecs/adau17x1.h +@@ -119,5 +119,7 @@ bool adau17x1_has_dsp(struct adau *adau) + + #define ADAU17X1_CONVERTER0_CONVSR_MASK 0x7 + ++#define ADAU17X1_CONVERTER0_ADOSR BIT(3) ++ + + #endif diff --git a/queue-3.18/cifs-check-maxpathnamecomponentlength-0-before-using-it.patch b/queue-3.18/cifs-check-maxpathnamecomponentlength-0-before-using-it.patch new file mode 100644 index 00000000000..4b58bd183c0 --- /dev/null +++ b/queue-3.18/cifs-check-maxpathnamecomponentlength-0-before-using-it.patch @@ -0,0 +1,41 @@ +From f74bc7c6679200a4a83156bb89cbf6c229fe8ec0 Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Mon, 30 Oct 2017 13:28:03 +1100 +Subject: cifs: check MaxPathNameComponentLength != 0 before using it + +From: Ronnie Sahlberg + +commit f74bc7c6679200a4a83156bb89cbf6c229fe8ec0 upstream. + +And fix tcon leak in error path. + +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +Reviewed-by: David Disseldorp +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/dir.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -193,7 +193,8 @@ check_name(struct dentry *direntry, stru + struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); + int i; + +- if (unlikely(direntry->d_name.len > ++ if (unlikely(tcon->fsAttrInfo.MaxPathNameComponentLength && ++ direntry->d_name.len > + le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength))) + return -ENAMETOOLONG; + +@@ -509,7 +510,7 @@ cifs_atomic_open(struct inode *inode, st + + rc = check_name(direntry, tcon); + if (rc) +- goto out_free_xid; ++ goto out; + + server = tcon->ses->server; + diff --git a/queue-3.18/keys-fix-out-of-bounds-read-during-asn.1-parsing.patch b/queue-3.18/keys-fix-out-of-bounds-read-during-asn.1-parsing.patch new file mode 100644 index 00000000000..9d46756d8d6 --- /dev/null +++ b/queue-3.18/keys-fix-out-of-bounds-read-during-asn.1-parsing.patch @@ -0,0 +1,71 @@ +From 2eb9eabf1e868fda15808954fb29b0f105ed65f1 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 2 Nov 2017 00:47:19 +0000 +Subject: KEYS: fix out-of-bounds read during ASN.1 parsing + +From: Eric Biggers + +commit 2eb9eabf1e868fda15808954fb29b0f105ed65f1 upstream. + +syzkaller with KASAN reported an out-of-bounds read in +asn1_ber_decoder(). It can be reproduced by the following command, +assuming CONFIG_X509_CERTIFICATE_PARSER=y and CONFIG_KASAN=y: + + keyctl add asymmetric desc $'\x30\x30' @s + +The bug is that the length of an ASN.1 data value isn't validated in the +case where it is encoded using the short form, causing the decoder to +read past the end of the input buffer. Fix it by validating the length. + +The bug report was: + + BUG: KASAN: slab-out-of-bounds in asn1_ber_decoder+0x10cb/0x1730 lib/asn1_decoder.c:233 + Read of size 1 at addr ffff88003cccfa02 by task syz-executor0/6818 + + CPU: 1 PID: 6818 Comm: syz-executor0 Not tainted 4.14.0-rc7-00008-g5f479447d983 #2 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + Call Trace: + __dump_stack lib/dump_stack.c:16 [inline] + dump_stack+0xb3/0x10b lib/dump_stack.c:52 + print_address_description+0x79/0x2a0 mm/kasan/report.c:252 + kasan_report_error mm/kasan/report.c:351 [inline] + kasan_report+0x236/0x340 mm/kasan/report.c:409 + __asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427 + asn1_ber_decoder+0x10cb/0x1730 lib/asn1_decoder.c:233 + x509_cert_parse+0x1db/0x650 crypto/asymmetric_keys/x509_cert_parser.c:89 + x509_key_preparse+0x64/0x7a0 crypto/asymmetric_keys/x509_public_key.c:174 + asymmetric_key_preparse+0xcb/0x1a0 crypto/asymmetric_keys/asymmetric_type.c:388 + key_create_or_update+0x347/0xb20 security/keys/key.c:855 + SYSC_add_key security/keys/keyctl.c:122 [inline] + SyS_add_key+0x1cd/0x340 security/keys/keyctl.c:62 + entry_SYSCALL_64_fastpath+0x1f/0xbe + RIP: 0033:0x447c89 + RSP: 002b:00007fca7a5d3bd8 EFLAGS: 00000246 ORIG_RAX: 00000000000000f8 + RAX: ffffffffffffffda RBX: 00007fca7a5d46cc RCX: 0000000000447c89 + RDX: 0000000020006f4a RSI: 0000000020006000 RDI: 0000000020001ff5 + RBP: 0000000000000046 R08: fffffffffffffffd R09: 0000000000000000 + R10: 0000000000000002 R11: 0000000000000246 R12: 0000000000000000 + R13: 0000000000000000 R14: 00007fca7a5d49c0 R15: 00007fca7a5d4700 + +Fixes: 42d5ec27f873 ("X.509: Add an ASN.1 decoder") +Signed-off-by: Eric Biggers +Signed-off-by: David Howells +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + lib/asn1_decoder.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/lib/asn1_decoder.c ++++ b/lib/asn1_decoder.c +@@ -276,6 +276,9 @@ next_op: + if (unlikely(len > datalen - dp)) + goto data_overrun_error; + } ++ } else { ++ if (unlikely(len > datalen - dp)) ++ goto data_overrun_error; + } + + if (flags & FLAG_CONS) { diff --git a/queue-3.18/keys-return-full-count-in-keyring_read-if-buffer-is-too-small.patch b/queue-3.18/keys-return-full-count-in-keyring_read-if-buffer-is-too-small.patch new file mode 100644 index 00000000000..0cc09f6ab4b --- /dev/null +++ b/queue-3.18/keys-return-full-count-in-keyring_read-if-buffer-is-too-small.patch @@ -0,0 +1,88 @@ +From 3239b6f29bdfb4b0a2ba59df995fc9e6f4df7f1f Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 2 Nov 2017 00:47:03 +0000 +Subject: KEYS: return full count in keyring_read() if buffer is too small + +From: Eric Biggers + +commit 3239b6f29bdfb4b0a2ba59df995fc9e6f4df7f1f upstream. + +Commit e645016abc80 ("KEYS: fix writing past end of user-supplied buffer +in keyring_read()") made keyring_read() stop corrupting userspace memory +when the user-supplied buffer is too small. However it also made the +return value in that case be the short buffer size rather than the size +required, yet keyctl_read() is actually documented to return the size +required. Therefore, switch it over to the documented behavior. + +Note that for now we continue to have it fill the short buffer, since it +did that before (pre-v3.13) and dump_key_tree_aux() in keyutils arguably +relies on it. + +Fixes: e645016abc80 ("KEYS: fix writing past end of user-supplied buffer in keyring_read()") +Reported-by: Ben Hutchings +Signed-off-by: Eric Biggers +Signed-off-by: David Howells +Reviewed-by: James Morris +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/keys/keyring.c | 39 +++++++++++++++++++-------------------- + 1 file changed, 19 insertions(+), 20 deletions(-) + +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -452,34 +452,33 @@ static long keyring_read(const struct ke + char __user *buffer, size_t buflen) + { + struct keyring_read_iterator_context ctx; +- unsigned long nr_keys; +- int ret; ++ long ret; + + kenter("{%d},,%zu", key_serial(keyring), buflen); + + if (buflen & (sizeof(key_serial_t) - 1)) + return -EINVAL; + +- nr_keys = keyring->keys.nr_leaves_on_tree; +- if (nr_keys == 0) +- return 0; +- +- /* Calculate how much data we could return */ +- if (!buffer || !buflen) +- return nr_keys * sizeof(key_serial_t); +- +- /* Copy the IDs of the subscribed keys into the buffer */ +- ctx.buffer = (key_serial_t __user *)buffer; +- ctx.buflen = buflen; +- ctx.count = 0; +- ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx); +- if (ret < 0) { +- kleave(" = %d [iterate]", ret); +- return ret; ++ /* Copy as many key IDs as fit into the buffer */ ++ if (buffer && buflen) { ++ ctx.buffer = (key_serial_t __user *)buffer; ++ ctx.buflen = buflen; ++ ctx.count = 0; ++ ret = assoc_array_iterate(&keyring->keys, ++ keyring_read_iterator, &ctx); ++ if (ret < 0) { ++ kleave(" = %ld [iterate]", ret); ++ return ret; ++ } + } + +- kleave(" = %zu [ok]", ctx.count); +- return ctx.count; ++ /* Return the size of the buffer needed */ ++ ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t); ++ if (ret <= buflen) ++ kleave("= %ld [ok]", ret); ++ else ++ kleave("= %ld [buffer too small]", ret); ++ return ret; + } + + /* diff --git a/queue-3.18/series b/queue-3.18/series index 32e83a66613..e0724aa81a4 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -1 +1,9 @@ blk-mq-fix-race-between-timeout-and-freeing-request.patch +alsa-timer-add-missing-mutex-lock-for-compat-ioctls.patch +alsa-seq-fix-nested-rwsem-annotation-for-lockdep-splat.patch +cifs-check-maxpathnamecomponentlength-0-before-using-it.patch +keys-return-full-count-in-keyring_read-if-buffer-is-too-small.patch +keys-fix-out-of-bounds-read-during-asn.1-parsing.patch +asoc-adau17x1-workaround-for-noise-bug-in-adc.patch +arm64-ensure-__dump_instr-checks-addr_limit.patch +arm-8715-1-add-a-private-asm-unaligned.h.patch