From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, stable@vger.kernel.org, "Steven J. Magnani" <steve@digidescorp.com>, Jan Kara <jack@suse.cz> Subject: [PATCH 5.2 05/61] udf: Fix incorrect final NOT_ALLOCATED (hole) extent length Date: Fri, 12 Jul 2019 14:19:18 +0200 [thread overview] Message-ID: <20190712121620.907410989@linuxfoundation.org> (raw) In-Reply-To: <20190712121620.632595223@linuxfoundation.org> From: Steven J. Magnani <steve.magnani@digidescorp.com> commit fa33cdbf3eceb0206a4f844fe91aeebcf6ff2b7a upstream. In some cases, using the 'truncate' command to extend a UDF file results in a mismatch between the length of the file's extents (specifically, due to incorrect length of the final NOT_ALLOCATED extent) and the information (file) length. The discrepancy can prevent other operating systems (i.e., Windows 10) from opening the file. Two particular errors have been observed when extending a file: 1. The final extent is larger than it should be, having been rounded up to a multiple of the block size. B. The final extent is not shorter than it should be, due to not having been updated when the file's information length was increased. [JK: simplified udf_do_extend_final_block(), fixed up some types] Fixes: 2c948b3f86e5 ("udf: Avoid IO in udf_clear_inode") CC: stable@vger.kernel.org Signed-off-by: Steven J. Magnani <steve@digidescorp.com> Link: https://lore.kernel.org/r/1561948775-5878-1-git-send-email-steve@digidescorp.com Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- fs/udf/inode.c | 93 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 33 deletions(-) --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -470,13 +470,15 @@ static struct buffer_head *udf_getblk(st return NULL; } -/* Extend the file by 'blocks' blocks, return the number of extents added */ +/* Extend the file with new blocks totaling 'new_block_bytes', + * return the number of extents added + */ static int udf_do_extend_file(struct inode *inode, struct extent_position *last_pos, struct kernel_long_ad *last_ext, - sector_t blocks) + loff_t new_block_bytes) { - sector_t add; + uint32_t add; int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); struct super_block *sb = inode->i_sb; struct kernel_lb_addr prealloc_loc = {}; @@ -486,7 +488,7 @@ static int udf_do_extend_file(struct ino /* The previous extent is fake and we should not extend by anything * - there's nothing to do... */ - if (!blocks && fake) + if (!new_block_bytes && fake) return 0; iinfo = UDF_I(inode); @@ -517,13 +519,12 @@ static int udf_do_extend_file(struct ino /* Can we merge with the previous extent? */ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) { - add = ((1 << 30) - sb->s_blocksize - - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> - sb->s_blocksize_bits; - if (add > blocks) - add = blocks; - blocks -= add; - last_ext->extLength += add << sb->s_blocksize_bits; + add = (1 << 30) - sb->s_blocksize - + (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); + if (add > new_block_bytes) + add = new_block_bytes; + new_block_bytes -= add; + last_ext->extLength += add; } if (fake) { @@ -544,28 +545,27 @@ static int udf_do_extend_file(struct ino } /* Managed to do everything necessary? */ - if (!blocks) + if (!new_block_bytes) goto out; /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ last_ext->extLocation.logicalBlockNum = 0; last_ext->extLocation.partitionReferenceNum = 0; - add = (1 << (30-sb->s_blocksize_bits)) - 1; - last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | - (add << sb->s_blocksize_bits); + add = (1 << 30) - sb->s_blocksize; + last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | add; /* Create enough extents to cover the whole hole */ - while (blocks > add) { - blocks -= add; + while (new_block_bytes > add) { + new_block_bytes -= add; err = udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); if (err) return err; count++; } - if (blocks) { + if (new_block_bytes) { last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | - (blocks << sb->s_blocksize_bits); + new_block_bytes; err = udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); if (err) @@ -596,6 +596,24 @@ out: return count; } +/* Extend the final block of the file to final_block_len bytes */ +static void udf_do_extend_final_block(struct inode *inode, + struct extent_position *last_pos, + struct kernel_long_ad *last_ext, + uint32_t final_block_len) +{ + struct super_block *sb = inode->i_sb; + uint32_t added_bytes; + + added_bytes = final_block_len - + (last_ext->extLength & (sb->s_blocksize - 1)); + last_ext->extLength += added_bytes; + UDF_I(inode)->i_lenExtents += added_bytes; + + udf_write_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); +} + static int udf_extend_file(struct inode *inode, loff_t newsize) { @@ -605,10 +623,12 @@ static int udf_extend_file(struct inode int8_t etype; struct super_block *sb = inode->i_sb; sector_t first_block = newsize >> sb->s_blocksize_bits, offset; + unsigned long partial_final_block; int adsize; struct udf_inode_info *iinfo = UDF_I(inode); struct kernel_long_ad extent; - int err; + int err = 0; + int within_final_block; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) adsize = sizeof(struct short_ad); @@ -618,18 +638,8 @@ static int udf_extend_file(struct inode BUG(); etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); + within_final_block = (etype != -1); - /* File has extent covering the new size (could happen when extending - * inside a block)? */ - if (etype != -1) - return 0; - if (newsize & (sb->s_blocksize - 1)) - offset++; - /* Extended file just to the boundary of the last file block? */ - if (offset == 0) - return 0; - - /* Truncate is extending the file by 'offset' blocks */ if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { /* File has no extents at all or has empty last @@ -643,7 +653,22 @@ static int udf_extend_file(struct inode &extent.extLength, 0); extent.extLength |= etype << 30; } - err = udf_do_extend_file(inode, &epos, &extent, offset); + + partial_final_block = newsize & (sb->s_blocksize - 1); + + /* File has extent covering the new size (could happen when extending + * inside a block)? + */ + if (within_final_block) { + /* Extending file within the last file block */ + udf_do_extend_final_block(inode, &epos, &extent, + partial_final_block); + } else { + loff_t add = ((loff_t)offset << sb->s_blocksize_bits) | + partial_final_block; + err = udf_do_extend_file(inode, &epos, &extent, add); + } + if (err < 0) goto out; err = 0; @@ -745,6 +770,7 @@ static sector_t inode_getblk(struct inod /* Are we beyond EOF? */ if (etype == -1) { int ret; + loff_t hole_len; isBeyondEOF = true; if (count) { if (c) @@ -760,7 +786,8 @@ static sector_t inode_getblk(struct inod startnum = (offset > 0); } /* Create extents for the hole between EOF and offset */ - ret = udf_do_extend_file(inode, &prev_epos, laarr, offset); + hole_len = (loff_t)offset << inode->i_blkbits; + ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len); if (ret < 0) { *err = ret; newblock = 0;
next prev parent reply other threads:[~2019-07-12 12:35 UTC|newest] Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-07-12 12:19 [PATCH 5.2 00/61] 5.2.1-stable review Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 01/61] crypto: talitos - fix hash on SEC1 Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 02/61] crypto: lrw - use correct alignmask Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 03/61] crypto: talitos - rename alternative AEAD algos Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 04/61] fscrypt: dont set policy for a dead directory Greg Kroah-Hartman 2019-07-12 12:19 ` Greg Kroah-Hartman [this message] 2019-07-12 12:19 ` [PATCH 5.2 06/61] media: stv0297: fix frequency range limit Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 07/61] ALSA: usb-audio: Fix parse of UAC2 Extension Units Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 08/61] ALSA: hda/realtek - Headphone Mic cant record after S3 Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 09/61] tpm: Actually fail on TPM errors during "get random" Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 10/61] tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 11/61] block: fix .bi_size overflow Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 12/61] block, bfq: NULL out the bic when its no longer valid Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 13/61] perf intel-pt: Fix itrace defaults for perf script Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 14/61] perf auxtrace: " Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 15/61] perf intel-pt: Fix itrace defaults for perf script intel-pt documentation Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 16/61] perf pmu: Fix uncore PMU alias list for ARM64 Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 17/61] perf thread-stack: Fix thread stack return from kernel for kernel-only case Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 18/61] perf header: Assign proper ff->ph in perf_event__synthesize_features() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 19/61] x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 20/61] x86/tls: Fix possible spectre-v1 in do_get_thread_area() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 21/61] Documentation: Add section about CPU vulnerabilities for Spectre Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 22/61] Documentation/admin: Remove the vsyscall=native documentation Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 23/61] mwifiex: Dont abort on small, spec-compliant vendor IEs Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 24/61] USB: serial: ftdi_sio: add ID for isodebug v1 Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 25/61] USB: serial: option: add support for GosunCn ME3630 RNDIS mode Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 26/61] Revert "serial: 8250: Dont service RX FIFO if interrupts are disabled" Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 27/61] p54usb: Fix race between disconnect and firmware loading Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 28/61] usb: gadget: f_fs: data_len used before properly set Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 29/61] usb: gadget: ether: Fix race between gether_disconnect and rx_submit Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 30/61] usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 31/61] usb: renesas_usbhs: add a workaround for a race condition of workqueue Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 32/61] drivers/usb/typec/tps6598x.c: fix portinfo width Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 33/61] drivers/usb/typec/tps6598x.c: fix 4CC cmd write Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 34/61] p54: fix crash during initialization Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 35/61] staging: comedi: dt282x: fix a null pointer deref on interrupt Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 36/61] staging: wilc1000: fix error path cleanup in wilc_wlan_initialize() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 37/61] staging: bcm2835-camera: Restore return behavior of ctrl_set_bitrate() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 38/61] staging: comedi: amplc_pci230: fix null pointer deref on interrupt Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 39/61] staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 40/61] HID: Add another Primax PIXART OEM mouse quirk Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 41/61] lkdtm: support llvm-objcopy Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 42/61] binder: fix memory leak in error path Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 43/61] binder: return errors from buffer copy functions Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 44/61] iio: adc: stm32-adc: add missing vdda-supply Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 45/61] coresight: Potential uninitialized variable in probe() Greg Kroah-Hartman 2019-07-12 12:19 ` [PATCH 5.2 46/61] coresight: etb10: Do not call smp_processor_id from preemptible Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 47/61] coresight: tmc-etr: Do not call smp_processor_id() " Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 48/61] coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id " Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 49/61] coresight: tmc-etf: " Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 50/61] carl9170: fix misuse of device driver API Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 51/61] Revert "x86/build: Move _etext to actual end of .text" Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 52/61] VMCI: Fix integer overflow in VMCI handle arrays Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 53/61] staging: vchiq_2835_arm: revert "quit using custom down_interruptible()" Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 54/61] staging: vchiq: make wait events interruptible Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 55/61] staging: vchiq: revert "switch to wait_for_completion_killable" Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 56/61] staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 57/61] staging: bcm2835-camera: Replace spinlock protecting context_map with mutex Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 58/61] staging: bcm2835-camera: Ensure all buffers are returned on disable Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 59/61] staging: bcm2835-camera: Remove check of the number of buffers supplied Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 60/61] staging: bcm2835-camera: Handle empty EOS buffers whilst streaming Greg Kroah-Hartman 2019-07-12 12:20 ` [PATCH 5.2 61/61] staging: rtl8712: reduce stack usage, again Greg Kroah-Hartman 2019-07-12 13:36 ` [PATCH 5.2 00/61] 5.2.1-stable review Jon Hunter 2019-07-12 15:31 ` Greg Kroah-Hartman 2019-07-12 16:10 ` Jon Hunter 2019-07-12 16:51 ` Greg Kroah-Hartman 2019-07-12 17:00 ` Major Hayden 2019-07-12 17:17 ` Dan Rue 2019-07-12 22:07 ` shuah 2019-07-13 8:23 ` Greg Kroah-Hartman 2019-07-13 3:04 ` Naresh Kamboju 2019-07-13 14:32 ` Greg Kroah-Hartman 2019-07-13 10:15 ` Shreeya Patel 2019-07-13 15:21 ` Greg Kroah-Hartman 2019-07-13 20:37 ` Luke Nowakowski-Krijger 2019-07-14 6:02 ` Greg Kroah-Hartman 2019-07-13 22:04 ` Guenter Roeck 2019-07-14 6:02 ` Greg Kroah-Hartman 2019-07-14 5:35 ` Kelsey Skunberg 2019-07-14 6:02 ` Greg Kroah-Hartman
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190712121620.907410989@linuxfoundation.org \ --to=gregkh@linuxfoundation.org \ --cc=jack@suse.cz \ --cc=linux-kernel@vger.kernel.org \ --cc=stable@vger.kernel.org \ --cc=steve@digidescorp.com \ --subject='Re: [PATCH 5.2 05/61] udf: Fix incorrect final NOT_ALLOCATED (hole) extent length' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).