From 60f2ed4936e6fbf58ab3fce57f536de75d5d3c9d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 15 Dec 2019 18:16:58 +0100 Subject: [PATCH] 5.4-stable patches added patches: ext2-check-err-when-partial-null.patch ext4-fix-credit-estimate-for-final-inode-freeing.patch powerpc-allow-64bit-vdso-__kernel_sync_dicache-to-work-across-ranges-4gb.patch powerpc-allow-flush_icache_range-to-work-across-ranges-4gb.patch powerpc-xive-prevent-page-fault-issues-in-the-machine-crash-handler.patch powerpc-xive-skip-ioremap-of-esb-pages-for-lsi-interrupts.patch quota-check-that-quota-is-not-dirty-before-release.patch quota-fix-livelock-in-dquot_writeback_dquots.patch reiserfs-fix-extended-attributes-on-the-root-directory.patch seccomp-avoid-overflow-in-implicit-constant-conversion.patch seccomp-test-seccomp_user_notif_flag_continue.patch video-hdmi-fix-avi-bar-unpack.patch --- .../ext2-check-err-when-partial-null.patch | 41 ++++ ...dit-estimate-for-final-inode-freeing.patch | 57 +++++ ...nc_dicache-to-work-across-ranges-4gb.patch | 46 ++++ ...ache_range-to-work-across-ranges-4gb.patch | 46 ++++ ...-issues-in-the-machine-crash-handler.patch | 52 +++++ ...emap-of-esb-pages-for-lsi-interrupts.patch | 100 +++++++++ ...at-quota-is-not-dirty-before-release.patch | 85 ++++++++ ...x-livelock-in-dquot_writeback_dquots.patch | 49 +++++ ...ded-attributes-on-the-root-directory.patch | 197 ++++++++++++++++++ ...flow-in-implicit-constant-conversion.patch | 67 ++++++ ...est-seccomp_user_notif_flag_continue.patch | 167 +++++++++++++++ queue-5.4/series | 12 ++ queue-5.4/video-hdmi-fix-avi-bar-unpack.patch | 50 +++++ 13 files changed, 969 insertions(+) create mode 100644 queue-5.4/ext2-check-err-when-partial-null.patch create mode 100644 queue-5.4/ext4-fix-credit-estimate-for-final-inode-freeing.patch create mode 100644 queue-5.4/powerpc-allow-64bit-vdso-__kernel_sync_dicache-to-work-across-ranges-4gb.patch create mode 100644 queue-5.4/powerpc-allow-flush_icache_range-to-work-across-ranges-4gb.patch create mode 100644 queue-5.4/powerpc-xive-prevent-page-fault-issues-in-the-machine-crash-handler.patch create mode 100644 queue-5.4/powerpc-xive-skip-ioremap-of-esb-pages-for-lsi-interrupts.patch create mode 100644 queue-5.4/quota-check-that-quota-is-not-dirty-before-release.patch create mode 100644 queue-5.4/quota-fix-livelock-in-dquot_writeback_dquots.patch create mode 100644 queue-5.4/reiserfs-fix-extended-attributes-on-the-root-directory.patch create mode 100644 queue-5.4/seccomp-avoid-overflow-in-implicit-constant-conversion.patch create mode 100644 queue-5.4/seccomp-test-seccomp_user_notif_flag_continue.patch create mode 100644 queue-5.4/video-hdmi-fix-avi-bar-unpack.patch diff --git a/queue-5.4/ext2-check-err-when-partial-null.patch b/queue-5.4/ext2-check-err-when-partial-null.patch new file mode 100644 index 00000000000..c8aed3f85db --- /dev/null +++ b/queue-5.4/ext2-check-err-when-partial-null.patch @@ -0,0 +1,41 @@ +From e705f4b8aa27a59f8933e8f384e9752f052c469c Mon Sep 17 00:00:00 2001 +From: Chengguang Xu +Date: Tue, 5 Nov 2019 12:51:00 +0800 +Subject: ext2: check err when partial != NULL + +From: Chengguang Xu + +commit e705f4b8aa27a59f8933e8f384e9752f052c469c upstream. + +Check err when partial == NULL is meaningless because +partial == NULL means getting branch successfully without +error. + +CC: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20191105045100.7104-1-cgxu519@mykernel.net +Signed-off-by: Chengguang Xu +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext2/inode.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/ext2/inode.c ++++ b/fs/ext2/inode.c +@@ -701,10 +701,13 @@ static int ext2_get_blocks(struct inode + if (!partial) { + count++; + mutex_unlock(&ei->truncate_mutex); +- if (err) +- goto cleanup; + goto got_it; + } ++ ++ if (err) { ++ mutex_unlock(&ei->truncate_mutex); ++ goto cleanup; ++ } + } + + /* diff --git a/queue-5.4/ext4-fix-credit-estimate-for-final-inode-freeing.patch b/queue-5.4/ext4-fix-credit-estimate-for-final-inode-freeing.patch new file mode 100644 index 00000000000..9b200c239d9 --- /dev/null +++ b/queue-5.4/ext4-fix-credit-estimate-for-final-inode-freeing.patch @@ -0,0 +1,57 @@ +From 65db869c754e7c271691dd5feabf884347e694f5 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 5 Nov 2019 17:44:12 +0100 +Subject: ext4: Fix credit estimate for final inode freeing + +From: Jan Kara + +commit 65db869c754e7c271691dd5feabf884347e694f5 upstream. + +Estimate for the number of credits needed for final freeing of inode in +ext4_evict_inode() was to small. We may modify 4 blocks (inode & sb for +orphan deletion, bitmap & group descriptor for inode freeing) and not +just 3. + +[ Fixed minor whitespace nit. -- TYT ] + +Fixes: e50e5129f384 ("ext4: xattr-in-inode support") +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20191105164437.32602-6-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -196,7 +196,12 @@ void ext4_evict_inode(struct inode *inod + { + handle_t *handle; + int err; +- int extra_credits = 3; ++ /* ++ * Credits for final inode cleanup and freeing: ++ * sb + inode (ext4_orphan_del()), block bitmap, group descriptor ++ * (xattr block freeing), bitmap, group descriptor (inode freeing) ++ */ ++ int extra_credits = 6; + struct ext4_xattr_inode_array *ea_inode_array = NULL; + + trace_ext4_evict_inode(inode); +@@ -252,8 +257,12 @@ void ext4_evict_inode(struct inode *inod + if (!IS_NOQUOTA(inode)) + extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb); + ++ /* ++ * Block bitmap, group descriptor, and inode are accounted in both ++ * ext4_blocks_for_truncate() and extra_credits. So subtract 3. ++ */ + handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, +- ext4_blocks_for_truncate(inode)+extra_credits); ++ ext4_blocks_for_truncate(inode) + extra_credits - 3); + if (IS_ERR(handle)) { + ext4_std_error(inode->i_sb, PTR_ERR(handle)); + /* diff --git a/queue-5.4/powerpc-allow-64bit-vdso-__kernel_sync_dicache-to-work-across-ranges-4gb.patch b/queue-5.4/powerpc-allow-64bit-vdso-__kernel_sync_dicache-to-work-across-ranges-4gb.patch new file mode 100644 index 00000000000..8c6e835ca53 --- /dev/null +++ b/queue-5.4/powerpc-allow-64bit-vdso-__kernel_sync_dicache-to-work-across-ranges-4gb.patch @@ -0,0 +1,46 @@ +From f9ec11165301982585e5e5f606739b5bae5331f3 Mon Sep 17 00:00:00 2001 +From: Alastair D'Silva +Date: Mon, 4 Nov 2019 13:32:54 +1100 +Subject: powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB + +From: Alastair D'Silva + +commit f9ec11165301982585e5e5f606739b5bae5331f3 upstream. + +When calling __kernel_sync_dicache with a size >4GB, we were masking +off the upper 32 bits, so we would incorrectly flush a range smaller +than intended. + +This patch replaces the 32 bit shifts with 64 bit ones, so that +the full size is accounted for. + +Signed-off-by: Alastair D'Silva +Cc: stable@vger.kernel.org +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20191104023305.9581-3-alastair@au1.ibm.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/vdso64/cacheflush.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/vdso64/cacheflush.S ++++ b/arch/powerpc/kernel/vdso64/cacheflush.S +@@ -35,7 +35,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10) +- srw. r8,r8,r9 /* compute line count */ ++ srd. r8,r8,r9 /* compute line count */ + crclr cr0*4+so + beqlr /* nothing to do? */ + mtctr r8 +@@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 + lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10) +- srw. r8,r8,r9 /* compute line count */ ++ srd. r8,r8,r9 /* compute line count */ + crclr cr0*4+so + beqlr /* nothing to do? */ + mtctr r8 diff --git a/queue-5.4/powerpc-allow-flush_icache_range-to-work-across-ranges-4gb.patch b/queue-5.4/powerpc-allow-flush_icache_range-to-work-across-ranges-4gb.patch new file mode 100644 index 00000000000..e66ff481689 --- /dev/null +++ b/queue-5.4/powerpc-allow-flush_icache_range-to-work-across-ranges-4gb.patch @@ -0,0 +1,46 @@ +From 29430fae82073d39b1b881a3cd507416a56a363f Mon Sep 17 00:00:00 2001 +From: Alastair D'Silva +Date: Mon, 4 Nov 2019 13:32:53 +1100 +Subject: powerpc: Allow flush_icache_range to work across ranges >4GB + +From: Alastair D'Silva + +commit 29430fae82073d39b1b881a3cd507416a56a363f upstream. + +When calling flush_icache_range with a size >4GB, we were masking +off the upper 32 bits, so we would incorrectly flush a range smaller +than intended. + +This patch replaces the 32 bit shifts with 64 bit ones, so that +the full size is accounted for. + +Signed-off-by: Alastair D'Silva +Cc: stable@vger.kernel.org +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20191104023305.9581-2-alastair@au1.ibm.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/misc_64.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -82,7 +82,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of cache block size */ +- srw. r8,r8,r9 /* compute line count */ ++ srd. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 + 1: dcbst 0,r6 +@@ -98,7 +98,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 + lwz r9,ICACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of Icache block size */ +- srw. r8,r8,r9 /* compute line count */ ++ srd. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 + 2: icbi 0,r6 diff --git a/queue-5.4/powerpc-xive-prevent-page-fault-issues-in-the-machine-crash-handler.patch b/queue-5.4/powerpc-xive-prevent-page-fault-issues-in-the-machine-crash-handler.patch new file mode 100644 index 00000000000..12b99eea3f8 --- /dev/null +++ b/queue-5.4/powerpc-xive-prevent-page-fault-issues-in-the-machine-crash-handler.patch @@ -0,0 +1,52 @@ +From 1ca3dec2b2dff9d286ce6cd64108bda0e98f9710 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +Date: Thu, 31 Oct 2019 07:31:00 +0100 +Subject: powerpc/xive: Prevent page fault issues in the machine crash handler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cédric Le Goater + +commit 1ca3dec2b2dff9d286ce6cd64108bda0e98f9710 upstream. + +When the machine crash handler is invoked, all interrupts are masked +but interrupts which have not been started yet do not have an ESB page +mapped in the Linux address space. This crashes the 'crash kexec' +sequence on sPAPR guests. + +To fix, force the mapping of the ESB page when an interrupt is being +mapped in the Linux IRQ number space. This is done by setting the +initial state of the interrupt to OFF which is not necessarily the +case on PowerNV. + +Fixes: 243e25112d06 ("powerpc/xive: Native exploitation of the XIVE interrupt controller") +Cc: stable@vger.kernel.org # v4.12+ +Signed-off-by: Cédric Le Goater +Reviewed-by: Greg Kurz +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20191031063100.3864-1-clg@kaod.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/sysdev/xive/common.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/arch/powerpc/sysdev/xive/common.c ++++ b/arch/powerpc/sysdev/xive/common.c +@@ -1035,6 +1035,15 @@ static int xive_irq_alloc_data(unsigned + xd->target = XIVE_INVALID_TARGET; + irq_set_handler_data(virq, xd); + ++ /* ++ * Turn OFF by default the interrupt being mapped. A side ++ * effect of this check is the mapping the ESB page of the ++ * interrupt in the Linux address space. This prevents page ++ * fault issues in the crash handler which masks all ++ * interrupts. ++ */ ++ xive_esb_read(xd, XIVE_ESB_SET_PQ_01); ++ + return 0; + } + diff --git a/queue-5.4/powerpc-xive-skip-ioremap-of-esb-pages-for-lsi-interrupts.patch b/queue-5.4/powerpc-xive-skip-ioremap-of-esb-pages-for-lsi-interrupts.patch new file mode 100644 index 00000000000..d656dfbdde7 --- /dev/null +++ b/queue-5.4/powerpc-xive-skip-ioremap-of-esb-pages-for-lsi-interrupts.patch @@ -0,0 +1,100 @@ +From b67a95f2abff0c34e5667c15ab8900de73d8d087 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +Date: Tue, 3 Dec 2019 17:36:42 +0100 +Subject: powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cédric Le Goater + +commit b67a95f2abff0c34e5667c15ab8900de73d8d087 upstream. + +The PCI INTx interrupts and other LSI interrupts are handled differently +under a sPAPR platform. When the interrupt source characteristics are +queried, the hypervisor returns an H_INT_ESB flag to inform the OS +that it should be using the H_INT_ESB hcall for interrupt management +and not loads and stores on the interrupt ESB pages. + +A default -1 value is returned for the addresses of the ESB pages. The +driver ignores this condition today and performs a bogus IO mapping. +Recent changes and the DEBUG_VM configuration option make the bug +visible with : + + kernel BUG at arch/powerpc/include/asm/book3s/64/pgtable.h:612! + Oops: Exception in kernel mode, sig: 5 [#1] + LE PAGE_SIZE=64K MMU=Radix MMU=Hash SMP NR_CPUS=1024 NUMA pSeries + Modules linked in: + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.4.0-0.rc6.git0.1.fc32.ppc64le #1 + NIP: c000000000f63294 LR: c000000000f62e44 CTR: 0000000000000000 + REGS: c0000000fa45f0d0 TRAP: 0700 Not tainted (5.4.0-0.rc6.git0.1.fc32.ppc64le) + ... + NIP ioremap_page_range+0x4c4/0x6e0 + LR ioremap_page_range+0x74/0x6e0 + Call Trace: + ioremap_page_range+0x74/0x6e0 (unreliable) + do_ioremap+0x8c/0x120 + __ioremap_caller+0x128/0x140 + ioremap+0x30/0x50 + xive_spapr_populate_irq_data+0x170/0x260 + xive_irq_domain_map+0x8c/0x170 + irq_domain_associate+0xb4/0x2d0 + irq_create_mapping+0x1e0/0x3b0 + irq_create_fwspec_mapping+0x27c/0x3e0 + irq_create_of_mapping+0x98/0xb0 + of_irq_parse_and_map_pci+0x168/0x230 + pcibios_setup_device+0x88/0x250 + pcibios_setup_bus_devices+0x54/0x100 + __of_scan_bus+0x160/0x310 + pcibios_scan_phb+0x330/0x390 + pcibios_init+0x8c/0x128 + do_one_initcall+0x60/0x2c0 + kernel_init_freeable+0x290/0x378 + kernel_init+0x2c/0x148 + ret_from_kernel_thread+0x5c/0x80 + +Fixes: bed81ee181dd ("powerpc/xive: introduce H_INT_ESB hcall") +Cc: stable@vger.kernel.org # v4.14+ +Signed-off-by: Cédric Le Goater +Tested-by: Daniel Axtens +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20191203163642.2428-1-clg@kaod.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/sysdev/xive/spapr.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/sysdev/xive/spapr.c ++++ b/arch/powerpc/sysdev/xive/spapr.c +@@ -392,20 +392,28 @@ static int xive_spapr_populate_irq_data( + data->esb_shift = esb_shift; + data->trig_page = trig_page; + ++ data->hw_irq = hw_irq; ++ + /* + * No chip-id for the sPAPR backend. This has an impact how we + * pick a target. See xive_pick_irq_target(). + */ + data->src_chip = XIVE_INVALID_CHIP_ID; + ++ /* ++ * When the H_INT_ESB flag is set, the H_INT_ESB hcall should ++ * be used for interrupt management. Skip the remapping of the ++ * ESB pages which are not available. ++ */ ++ if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB) ++ return 0; ++ + data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); + if (!data->eoi_mmio) { + pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); + return -ENOMEM; + } + +- data->hw_irq = hw_irq; +- + /* Full function page supports trigger */ + if (flags & XIVE_SRC_TRIGGER) { + data->trig_mmio = data->eoi_mmio; diff --git a/queue-5.4/quota-check-that-quota-is-not-dirty-before-release.patch b/queue-5.4/quota-check-that-quota-is-not-dirty-before-release.patch new file mode 100644 index 00000000000..ae226449854 --- /dev/null +++ b/queue-5.4/quota-check-that-quota-is-not-dirty-before-release.patch @@ -0,0 +1,85 @@ +From df4bb5d128e2c44848aeb36b7ceceba3ac85080d Mon Sep 17 00:00:00 2001 +From: Dmitry Monakhov +Date: Thu, 31 Oct 2019 10:39:20 +0000 +Subject: quota: Check that quota is not dirty before release + +From: Dmitry Monakhov + +commit df4bb5d128e2c44848aeb36b7ceceba3ac85080d upstream. + +There is a race window where quota was redirted once we drop dq_list_lock inside dqput(), +but before we grab dquot->dq_lock inside dquot_release() + +TASK1 TASK2 (chowner) +->dqput() + we_slept: + spin_lock(&dq_list_lock) + if (dquot_dirty(dquot)) { + spin_unlock(&dq_list_lock); + dquot->dq_sb->dq_op->write_dquot(dquot); + goto we_slept + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + spin_unlock(&dq_list_lock); + dquot->dq_sb->dq_op->release_dquot(dquot); + dqget() + mark_dquot_dirty() + dqput() + goto we_slept; + } +So dquot dirty quota will be released by TASK1, but on next we_sleept loop +we detect this and call ->write_dquot() for it. +XFSTEST: https://github.com/dmonakhov/xfstests/commit/440a80d4cbb39e9234df4d7240aee1d551c36107 + +Link: https://lore.kernel.org/r/20191031103920.3919-2-dmonakhov@openvz.org +CC: stable@vger.kernel.org +Signed-off-by: Dmitry Monakhov +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/quota_global.c | 2 +- + fs/quota/dquot.c | 2 +- + include/linux/quotaops.h | 10 ++++++++++ + 3 files changed, 12 insertions(+), 2 deletions(-) + +--- a/fs/ocfs2/quota_global.c ++++ b/fs/ocfs2/quota_global.c +@@ -728,7 +728,7 @@ static int ocfs2_release_dquot(struct dq + + mutex_lock(&dquot->dq_lock); + /* Check whether we are not racing with some other dqget() */ +- if (atomic_read(&dquot->dq_count) > 1) ++ if (dquot_is_busy(dquot)) + goto out; + /* Running from downconvert thread? Postpone quota processing to wq */ + if (current == osb->dc_task) { +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -497,7 +497,7 @@ int dquot_release(struct dquot *dquot) + + mutex_lock(&dquot->dq_lock); + /* Check whether we are not racing with some other dqget() */ +- if (atomic_read(&dquot->dq_count) > 1) ++ if (dquot_is_busy(dquot)) + goto out_dqlock; + if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { + ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); +--- a/include/linux/quotaops.h ++++ b/include/linux/quotaops.h +@@ -54,6 +54,16 @@ static inline struct dquot *dqgrab(struc + atomic_inc(&dquot->dq_count); + return dquot; + } ++ ++static inline bool dquot_is_busy(struct dquot *dquot) ++{ ++ if (test_bit(DQ_MOD_B, &dquot->dq_flags)) ++ return true; ++ if (atomic_read(&dquot->dq_count) > 1) ++ return true; ++ return false; ++} ++ + void dqput(struct dquot *dquot); + int dquot_scan_active(struct super_block *sb, + int (*fn)(struct dquot *dquot, unsigned long priv), diff --git a/queue-5.4/quota-fix-livelock-in-dquot_writeback_dquots.patch b/queue-5.4/quota-fix-livelock-in-dquot_writeback_dquots.patch new file mode 100644 index 00000000000..1af8100aa13 --- /dev/null +++ b/queue-5.4/quota-fix-livelock-in-dquot_writeback_dquots.patch @@ -0,0 +1,49 @@ +From 6ff33d99fc5c96797103b48b7b0902c296f09c05 Mon Sep 17 00:00:00 2001 +From: Dmitry Monakhov +Date: Thu, 31 Oct 2019 10:39:19 +0000 +Subject: quota: fix livelock in dquot_writeback_dquots + +From: Dmitry Monakhov + +commit 6ff33d99fc5c96797103b48b7b0902c296f09c05 upstream. + +Write only quotas which are dirty at entry. + +XFSTEST: https://github.com/dmonakhov/xfstests/commit/b10ad23566a5bf75832a6f500e1236084083cddc + +Link: https://lore.kernel.org/r/20191031103920.3919-1-dmonakhov@openvz.org +CC: stable@vger.kernel.org +Signed-off-by: Konstantin Khlebnikov +Signed-off-by: Dmitry Monakhov +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/quota/dquot.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -623,7 +623,7 @@ EXPORT_SYMBOL(dquot_scan_active); + /* Write all dquot structures to quota files */ + int dquot_writeback_dquots(struct super_block *sb, int type) + { +- struct list_head *dirty; ++ struct list_head dirty; + struct dquot *dquot; + struct quota_info *dqopt = sb_dqopt(sb); + int cnt; +@@ -637,9 +637,10 @@ int dquot_writeback_dquots(struct super_ + if (!sb_has_quota_active(sb, cnt)) + continue; + spin_lock(&dq_list_lock); +- dirty = &dqopt->info[cnt].dqi_dirty_list; +- while (!list_empty(dirty)) { +- dquot = list_first_entry(dirty, struct dquot, ++ /* Move list away to avoid livelock. */ ++ list_replace_init(&dqopt->info[cnt].dqi_dirty_list, &dirty); ++ while (!list_empty(&dirty)) { ++ dquot = list_first_entry(&dirty, struct dquot, + dq_dirty); + + WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)); diff --git a/queue-5.4/reiserfs-fix-extended-attributes-on-the-root-directory.patch b/queue-5.4/reiserfs-fix-extended-attributes-on-the-root-directory.patch new file mode 100644 index 00000000000..dfe76bc9c8a --- /dev/null +++ b/queue-5.4/reiserfs-fix-extended-attributes-on-the-root-directory.patch @@ -0,0 +1,197 @@ +From 60e4cf67a582d64f07713eda5fcc8ccdaf7833e6 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Thu, 24 Oct 2019 10:31:27 -0400 +Subject: reiserfs: fix extended attributes on the root directory + +From: Jeff Mahoney + +commit 60e4cf67a582d64f07713eda5fcc8ccdaf7833e6 upstream. + +Since commit d0a5b995a308 (vfs: Add IOP_XATTR inode operations flag) +extended attributes haven't worked on the root directory in reiserfs. + +This is due to reiserfs conditionally setting the sb->s_xattrs handler +array depending on whether it located or create the internal privroot +directory. It necessarily does this after the root inode is already +read in. The IOP_XATTR flag is set during inode initialization, so +it never gets set on the root directory. + +This commit unconditionally assigns sb->s_xattrs and clears IOP_XATTR on +internal inodes. The old return values due to the conditional assignment +are handled via open_xa_root, which now returns EOPNOTSUPP as the VFS +would have done. + +Link: https://lore.kernel.org/r/20191024143127.17509-1-jeffm@suse.com +CC: stable@vger.kernel.org +Fixes: d0a5b995a308 ("vfs: Add IOP_XATTR inode operations flag") +Signed-off-by: Jeff Mahoney +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/inode.c | 12 ++++++++++-- + fs/reiserfs/namei.c | 7 +++++-- + fs/reiserfs/reiserfs.h | 2 ++ + fs/reiserfs/super.c | 2 ++ + fs/reiserfs/xattr.c | 19 ++++++++++++------- + fs/reiserfs/xattr_acl.c | 4 +--- + 6 files changed, 32 insertions(+), 14 deletions(-) + +--- a/fs/reiserfs/inode.c ++++ b/fs/reiserfs/inode.c +@@ -2097,6 +2097,15 @@ int reiserfs_new_inode(struct reiserfs_t + goto out_inserted_sd; + } + ++ /* ++ * Mark it private if we're creating the privroot ++ * or something under it. ++ */ ++ if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) { ++ inode->i_flags |= S_PRIVATE; ++ inode->i_opflags &= ~IOP_XATTR; ++ } ++ + if (reiserfs_posixacl(inode->i_sb)) { + reiserfs_write_unlock(inode->i_sb); + retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); +@@ -2111,8 +2120,7 @@ int reiserfs_new_inode(struct reiserfs_t + reiserfs_warning(inode->i_sb, "jdm-13090", + "ACLs aren't enabled in the fs, " + "but vfs thinks they are!"); +- } else if (IS_PRIVATE(dir)) +- inode->i_flags |= S_PRIVATE; ++ } + + if (security->name) { + reiserfs_write_unlock(inode->i_sb); +--- a/fs/reiserfs/namei.c ++++ b/fs/reiserfs/namei.c +@@ -377,10 +377,13 @@ static struct dentry *reiserfs_lookup(st + + /* + * Propagate the private flag so we know we're +- * in the priv tree ++ * in the priv tree. Also clear IOP_XATTR ++ * since we don't have xattrs on xattr files. + */ +- if (IS_PRIVATE(dir)) ++ if (IS_PRIVATE(dir)) { + inode->i_flags |= S_PRIVATE; ++ inode->i_opflags &= ~IOP_XATTR; ++ } + } + reiserfs_write_unlock(dir->i_sb); + if (retval == IO_ERROR) { +--- a/fs/reiserfs/reiserfs.h ++++ b/fs/reiserfs/reiserfs.h +@@ -1168,6 +1168,8 @@ static inline int bmap_would_wrap(unsign + return bmap_nr > ((1LL << 16) - 1); + } + ++extern const struct xattr_handler *reiserfs_xattr_handlers[]; ++ + /* + * this says about version of key of all items (but stat data) the + * object consists of +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -2049,6 +2049,8 @@ static int reiserfs_fill_super(struct su + if (replay_only(s)) + goto error_unlocked; + ++ s->s_xattr = reiserfs_xattr_handlers; ++ + if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) { + SWARN(silent, s, "clm-7000", + "Detected readonly device, marking FS readonly"); +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -122,13 +122,13 @@ static struct dentry *open_xa_root(struc + struct dentry *xaroot; + + if (d_really_is_negative(privroot)) +- return ERR_PTR(-ENODATA); ++ return ERR_PTR(-EOPNOTSUPP); + + inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR); + + xaroot = dget(REISERFS_SB(sb)->xattr_root); + if (!xaroot) +- xaroot = ERR_PTR(-ENODATA); ++ xaroot = ERR_PTR(-EOPNOTSUPP); + else if (d_really_is_negative(xaroot)) { + int err = -ENODATA; + +@@ -619,6 +619,10 @@ int reiserfs_xattr_set(struct inode *ino + int error, error2; + size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size); + ++ /* Check before we start a transaction and then do nothing. */ ++ if (!d_really_is_positive(REISERFS_SB(inode->i_sb)->priv_root)) ++ return -EOPNOTSUPP; ++ + if (!(flags & XATTR_REPLACE)) + jbegin_count += reiserfs_xattr_jcreate_nblocks(inode); + +@@ -841,8 +845,7 @@ ssize_t reiserfs_listxattr(struct dentry + if (d_really_is_negative(dentry)) + return -EINVAL; + +- if (!dentry->d_sb->s_xattr || +- get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) ++ if (get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) + return -EOPNOTSUPP; + + dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE); +@@ -882,6 +885,7 @@ static int create_privroot(struct dentry + } + + d_inode(dentry)->i_flags |= S_PRIVATE; ++ d_inode(dentry)->i_opflags &= ~IOP_XATTR; + reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " + "storage.\n", PRIVROOT_NAME); + +@@ -895,7 +899,7 @@ static int create_privroot(struct dentry + #endif + + /* Actual operations that are exported to VFS-land */ +-static const struct xattr_handler *reiserfs_xattr_handlers[] = { ++const struct xattr_handler *reiserfs_xattr_handlers[] = { + #ifdef CONFIG_REISERFS_FS_XATTR + &reiserfs_xattr_user_handler, + &reiserfs_xattr_trusted_handler, +@@ -966,8 +970,10 @@ int reiserfs_lookup_privroot(struct supe + if (!IS_ERR(dentry)) { + REISERFS_SB(s)->priv_root = dentry; + d_set_d_op(dentry, &xattr_lookup_poison_ops); +- if (d_really_is_positive(dentry)) ++ if (d_really_is_positive(dentry)) { + d_inode(dentry)->i_flags |= S_PRIVATE; ++ d_inode(dentry)->i_opflags &= ~IOP_XATTR; ++ } + } else + err = PTR_ERR(dentry); + inode_unlock(d_inode(s->s_root)); +@@ -996,7 +1002,6 @@ int reiserfs_xattr_init(struct super_blo + } + + if (d_really_is_positive(privroot)) { +- s->s_xattr = reiserfs_xattr_handlers; + inode_lock(d_inode(privroot)); + if (!REISERFS_SB(s)->xattr_root) { + struct dentry *dentry; +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -320,10 +320,8 @@ reiserfs_inherit_default_acl(struct reis + * would be useless since permissions are ignored, and a pain because + * it introduces locking cycles + */ +- if (IS_PRIVATE(dir)) { +- inode->i_flags |= S_PRIVATE; ++ if (IS_PRIVATE(inode)) + goto apply_umask; +- } + + err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); + if (err) diff --git a/queue-5.4/seccomp-avoid-overflow-in-implicit-constant-conversion.patch b/queue-5.4/seccomp-avoid-overflow-in-implicit-constant-conversion.patch new file mode 100644 index 00000000000..adb4eb6387d --- /dev/null +++ b/queue-5.4/seccomp-avoid-overflow-in-implicit-constant-conversion.patch @@ -0,0 +1,67 @@ +From 223e660bc7638d126a0e4fbace4f33f2895788c4 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Fri, 20 Sep 2019 10:30:06 +0200 +Subject: seccomp: avoid overflow in implicit constant conversion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian Brauner + +commit 223e660bc7638d126a0e4fbace4f33f2895788c4 upstream. + +USER_NOTIF_MAGIC is assigned to int variables in this test so set it to INT_MAX +to avoid warnings: + +seccomp_bpf.c: In function ‘user_notification_continue’: +seccomp_bpf.c:3088:26: warning: overflow in implicit constant conversion [-Woverflow] + #define USER_NOTIF_MAGIC 116983961184613L + ^ +seccomp_bpf.c:3572:15: note: in expansion of macro ‘USER_NOTIF_MAGIC’ + resp.error = USER_NOTIF_MAGIC; + ^~~~~~~~~~~~~~~~ + +Fixes: 6a21cc50f0c7 ("seccomp: add a return code to trap to userspace") +Signed-off-by: Christian Brauner +Reviewed-by: Tyler Hicks +Cc: Andy Lutomirski +Cc: Will Drewry +Cc: Shuah Khan +Cc: Alexei Starovoitov +Cc: Daniel Borkmann +Cc: Martin KaFai Lau +Cc: Song Liu +Cc: Yonghong Song +Cc: Tycho Andersen +Cc: stable@vger.kernel.org +Cc: linux-kselftest@vger.kernel.org +Cc: netdev@vger.kernel.org +Cc: bpf@vger.kernel.org +Reviewed-by: Tycho Andersen +Link: https://lore.kernel.org/r/20190920083007.11475-3-christian.brauner@ubuntu.com +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + tools/testing/selftests/seccomp/seccomp_bpf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/tools/testing/selftests/seccomp/seccomp_bpf.c ++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -3082,7 +3083,7 @@ static int user_trap_syscall(int nr, uns + return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog); + } + +-#define USER_NOTIF_MAGIC 116983961184613L ++#define USER_NOTIF_MAGIC INT_MAX + TEST(user_notification_basic) + { + pid_t pid; diff --git a/queue-5.4/seccomp-test-seccomp_user_notif_flag_continue.patch b/queue-5.4/seccomp-test-seccomp_user_notif_flag_continue.patch new file mode 100644 index 00000000000..ddffadd0936 --- /dev/null +++ b/queue-5.4/seccomp-test-seccomp_user_notif_flag_continue.patch @@ -0,0 +1,167 @@ +From 0eebfed2954f152259cae0ad57b91d3ea92968e8 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Fri, 20 Sep 2019 10:30:07 +0200 +Subject: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE + +From: Christian Brauner + +commit 0eebfed2954f152259cae0ad57b91d3ea92968e8 upstream. + +Test whether a syscall can be performed after having been intercepted by +the seccomp notifier. The test uses dup() and kcmp() since it allows us to +nicely test whether the dup() syscall actually succeeded by comparing whether +the fds refer to the same underlying struct file. + +Signed-off-by: Christian Brauner +Cc: Andy Lutomirski +Cc: Will Drewry +Cc: Shuah Khan +Cc: Alexei Starovoitov +Cc: Daniel Borkmann +Cc: Martin KaFai Lau +Cc: Song Liu +Cc: Yonghong Song +Cc: Tycho Andersen +CC: Tyler Hicks +Cc: stable@vger.kernel.org +Cc: linux-kselftest@vger.kernel.org +Cc: netdev@vger.kernel.org +Cc: bpf@vger.kernel.org +Link: https://lore.kernel.org/r/20190920083007.11475-4-christian.brauner@ubuntu.com +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + tools/testing/selftests/seccomp/seccomp_bpf.c | 107 ++++++++++++++++++++++++++ + 1 file changed, 107 insertions(+) + +--- a/tools/testing/selftests/seccomp/seccomp_bpf.c ++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -166,6 +167,10 @@ struct seccomp_metadata { + + #define SECCOMP_RET_USER_NOTIF 0x7fc00000U + ++#ifndef SECCOMP_USER_NOTIF_FLAG_CONTINUE ++#define SECCOMP_USER_NOTIF_FLAG_CONTINUE 0x00000001 ++#endif ++ + #define SECCOMP_IOC_MAGIC '!' + #define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) + #define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) +@@ -3485,6 +3490,108 @@ TEST(seccomp_get_notif_sizes) + EXPECT_EQ(sizes.seccomp_notif_resp, sizeof(struct seccomp_notif_resp)); + } + ++static int filecmp(pid_t pid1, pid_t pid2, int fd1, int fd2) ++{ ++#ifdef __NR_kcmp ++ return syscall(__NR_kcmp, pid1, pid2, KCMP_FILE, fd1, fd2); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ ++TEST(user_notification_continue) ++{ ++ pid_t pid; ++ long ret; ++ int status, listener; ++ struct seccomp_notif req = {}; ++ struct seccomp_notif_resp resp = {}; ++ struct pollfd pollfd; ++ ++ ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); ++ ASSERT_EQ(0, ret) { ++ TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); ++ } ++ ++ listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); ++ ASSERT_GE(listener, 0); ++ ++ pid = fork(); ++ ASSERT_GE(pid, 0); ++ ++ if (pid == 0) { ++ int dup_fd, pipe_fds[2]; ++ pid_t self; ++ ++ ret = pipe(pipe_fds); ++ if (ret < 0) ++ exit(1); ++ ++ dup_fd = dup(pipe_fds[0]); ++ if (dup_fd < 0) ++ exit(1); ++ ++ self = getpid(); ++ ++ ret = filecmp(self, self, pipe_fds[0], dup_fd); ++ if (ret) ++ exit(2); ++ ++ exit(0); ++ } ++ ++ pollfd.fd = listener; ++ pollfd.events = POLLIN | POLLOUT; ++ ++ EXPECT_GT(poll(&pollfd, 1, -1), 0); ++ EXPECT_EQ(pollfd.revents, POLLIN); ++ ++ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); ++ ++ pollfd.fd = listener; ++ pollfd.events = POLLIN | POLLOUT; ++ ++ EXPECT_GT(poll(&pollfd, 1, -1), 0); ++ EXPECT_EQ(pollfd.revents, POLLOUT); ++ ++ EXPECT_EQ(req.data.nr, __NR_dup); ++ ++ resp.id = req.id; ++ resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; ++ ++ /* ++ * Verify that setting SECCOMP_USER_NOTIF_FLAG_CONTINUE enforces other ++ * args be set to 0. ++ */ ++ resp.error = 0; ++ resp.val = USER_NOTIF_MAGIC; ++ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); ++ EXPECT_EQ(errno, EINVAL); ++ ++ resp.error = USER_NOTIF_MAGIC; ++ resp.val = 0; ++ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); ++ EXPECT_EQ(errno, EINVAL); ++ ++ resp.error = 0; ++ resp.val = 0; ++ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0) { ++ if (errno == EINVAL) ++ XFAIL(goto skip, "Kernel does not support SECCOMP_USER_NOTIF_FLAG_CONTINUE"); ++ } ++ ++skip: ++ EXPECT_EQ(waitpid(pid, &status, 0), pid); ++ EXPECT_EQ(true, WIFEXITED(status)); ++ EXPECT_EQ(0, WEXITSTATUS(status)) { ++ if (WEXITSTATUS(status) == 2) { ++ XFAIL(return, "Kernel does not support kcmp() syscall"); ++ return; ++ } ++ } ++} ++ + /* + * TODO: + * - add microbenchmarks diff --git a/queue-5.4/series b/queue-5.4/series index 1b7f4298392..67dc3115735 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -141,3 +141,15 @@ rdma-core-fix-ib_dma_max_seg_size.patch ppdev-fix-ppgettime-ppsettime-ioctls.patch stm-class-lose-the-protocol-driver-when-dropping-its-reference.patch coresight-serialize-enabling-disabling-a-link-device.patch +powerpc-allow-64bit-vdso-__kernel_sync_dicache-to-work-across-ranges-4gb.patch +powerpc-xive-prevent-page-fault-issues-in-the-machine-crash-handler.patch +powerpc-allow-flush_icache_range-to-work-across-ranges-4gb.patch +powerpc-xive-skip-ioremap-of-esb-pages-for-lsi-interrupts.patch +video-hdmi-fix-avi-bar-unpack.patch +seccomp-test-seccomp_user_notif_flag_continue.patch +quota-check-that-quota-is-not-dirty-before-release.patch +ext2-check-err-when-partial-null.patch +seccomp-avoid-overflow-in-implicit-constant-conversion.patch +quota-fix-livelock-in-dquot_writeback_dquots.patch +ext4-fix-credit-estimate-for-final-inode-freeing.patch +reiserfs-fix-extended-attributes-on-the-root-directory.patch diff --git a/queue-5.4/video-hdmi-fix-avi-bar-unpack.patch b/queue-5.4/video-hdmi-fix-avi-bar-unpack.patch new file mode 100644 index 00000000000..c296ba45754 --- /dev/null +++ b/queue-5.4/video-hdmi-fix-avi-bar-unpack.patch @@ -0,0 +1,50 @@ +From 6039f37dd6b76641198e290f26b31c475248f567 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 19 Sep 2019 16:28:53 +0300 +Subject: video/hdmi: Fix AVI bar unpack +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 6039f37dd6b76641198e290f26b31c475248f567 upstream. + +The bar values are little endian, not big endian. The pack +function did it right but the unpack got it wrong. Fix it. + +Cc: stable@vger.kernel.org +Cc: linux-media@vger.kernel.org +Cc: Martin Bugge +Cc: Hans Verkuil +Cc: Thierry Reding +Cc: Mauro Carvalho Chehab +Fixes: 2c676f378edb ("[media] hdmi: added unpack and logging functions for InfoFrames") +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20190919132853.30954-1-ville.syrjala@linux.intel.com +Reviewed-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/hdmi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -1576,12 +1576,12 @@ static int hdmi_avi_infoframe_unpack(str + if (ptr[0] & 0x10) + frame->active_aspect = ptr[1] & 0xf; + if (ptr[0] & 0x8) { +- frame->top_bar = (ptr[5] << 8) + ptr[6]; +- frame->bottom_bar = (ptr[7] << 8) + ptr[8]; ++ frame->top_bar = (ptr[6] << 8) | ptr[5]; ++ frame->bottom_bar = (ptr[8] << 8) | ptr[7]; + } + if (ptr[0] & 0x4) { +- frame->left_bar = (ptr[9] << 8) + ptr[10]; +- frame->right_bar = (ptr[11] << 8) + ptr[12]; ++ frame->left_bar = (ptr[10] << 8) | ptr[9]; ++ frame->right_bar = (ptr[12] << 8) | ptr[11]; + } + frame->scan_mode = ptr[0] & 0x3; + -- 2.47.3