diff options
| author | Srinivasarao P <spathi@codeaurora.org> | 2019-07-23 10:58:13 +0530 |
|---|---|---|
| committer | Srinivasarao P <spathi@codeaurora.org> | 2019-07-23 11:01:40 +0530 |
| commit | ae81a07395be43d63d9fe8ec632a351626320ead (patch) | |
| tree | 0410107ba5f9f481b398a41ab4cd84092625091f /fs | |
| parent | 4461eef69d3ea6b621af30636cf3ee05e3184d81 (diff) | |
| parent | aeb051d19e9322a87670556316f01f27abc20eed (diff) | |
Merge android-4.4.186 (aeb051d) into msm-4.4
* refs/heads/tmp-aeb051d
Linux 4.4.186
KVM: x86: protect KVM_CREATE_PIT/KVM_CREATE_PIT2 with kvm->lock
s390/qdio: don't touch the dsci in tiqdio_add_input_queues()
s390/qdio: (re-)initialize tiqdio list entries
s390: fix stfle zero padding
ARC: hide unused function unw_hdr_alloc
kvm: x86: avoid warning on repeated KVM_SET_TSS_ADDR
dm verity: use message limit for data block corruption message
sis900: fix TX completion
ppp: mppe: Add softdep to arc4
be2net: fix link failure after ethtool offline test
ARM: omap2: remove incorrect __init annotation
perf/core: Fix perf_sample_regs_user() mm check
e1000e: start network tx queue only when link is up
MIPS: Remove superfluous check for __linux__
VMCI: Fix integer overflow in VMCI handle arrays
carl9170: fix misuse of device driver API
staging: comedi: amplc_pci230: fix null pointer deref on interrupt
staging: comedi: dt282x: fix a null pointer deref on interrupt
usb: renesas_usbhs: add a workaround for a race condition of workqueue
usb: gadget: ether: Fix race between gether_disconnect and rx_submit
USB: serial: option: add support for GosunCn ME3630 RNDIS mode
USB: serial: ftdi_sio: add ID for isodebug v1
mwifiex: Don't abort on small, spec-compliant vendor IEs
fscrypt: don't set policy for a dead directory
mwifiex: Fix heap overflow in mwifiex_uap_parse_tail_ies()
mwifiex: Abort at too short BSS descriptor element
x86/tls: Fix possible spectre-v1 in do_get_thread_area()
x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg()
udf: Fix incorrect final NOT_ALLOCATED (hole) extent length
bnx2x: Check if transceiver implements DDM before access
md: fix for divide error in status_resync
ARM: davinci: da8xx: specify dma_coherent_mask for lcdc
ARM: davinci: da850-evm: call regulator_has_full_constraints()
Input: imx_keypad - make sure keyboard can always wake up system
can: mcp251x: add support for mcp25625
dt-bindings: can: mcp251x: add mcp25625 support
mwifiex: Fix possible buffer overflows at parsing bss descriptor
mac80211: mesh: fix RCU warning
samples, bpf: fix to change the buffer size for read()
Input: elantech - enable middle button support on 2 ThinkPads
ANDROID: overlayfs ovl_create_of_link regression
Change-Id: I42190d7fc7de3f2287199a9f69bc42bcf3596ec7
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext4/crypto_policy.c | 2 | ||||
| -rw-r--r-- | fs/overlayfs/dir.c | 9 | ||||
| -rw-r--r-- | fs/udf/inode.c | 93 |
3 files changed, 69 insertions, 35 deletions
diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c index e4f4fc4e56ab..77bd7bfb6329 100644 --- a/fs/ext4/crypto_policy.c +++ b/fs/ext4/crypto_policy.c @@ -111,6 +111,8 @@ int ext4_process_policy(const struct ext4_encryption_policy *policy, if (!ext4_inode_has_encryption_context(inode)) { if (!S_ISDIR(inode->i_mode)) return -EINVAL; + if (IS_DEADDIR(inode)) + return -ENOENT; if (!ext4_empty_dir(inode)) return -ENOTEMPTY; return ext4_create_encryption_context_from_policy(inode, diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index d7d880f9495b..4cc40de38dff 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -415,8 +415,13 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev, err = -ENOMEM; override_cred = prepare_creds(); if (override_cred) { - override_cred->fsuid = old_cred->fsuid; - override_cred->fsgid = old_cred->fsgid; + const struct cred *our_cred; + + our_cred = old_cred; + if (!our_cred) + our_cred = current_cred(); + override_cred->fsuid = our_cred->fsuid; + override_cred->fsgid = our_cred->fsgid; put_cred(override_creds(override_cred)); put_cred(override_cred); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 613193c6bb42..3876448ec0dc 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -479,13 +479,15 @@ static struct buffer_head *udf_getblk(struct inode *inode, long block, 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 = {}; @@ -495,7 +497,7 @@ static int udf_do_extend_file(struct inode *inode, /* 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); @@ -526,13 +528,12 @@ static int udf_do_extend_file(struct inode *inode, /* 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 inode *inode, last_ext->extLength, 1); /* 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 *inode, loff_t newsize) 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 *inode, loff_t newsize) 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 *inode, loff_t newsize) &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; @@ -748,6 +773,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, /* Are we beyond EOF? */ if (etype == -1) { int ret; + loff_t hole_len; isBeyondEOF = true; if (count) { if (c) @@ -763,7 +789,8 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, 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) { brelse(prev_epos.bh); brelse(cur_epos.bh); |
