16 Mar, 2016

1 commit


19 Jan, 2016

1 commit

  • Conflicts:
    arch/arm/boot/dts/Makefile
    arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
    arch/arm/boot/dts/imx6qdl-sabresd.dtsi
    arch/arm/boot/dts/imx6qp-sabresd.dts
    arch/arm/boot/dts/imx6sl-evk.dts
    arch/arm/boot/dts/imx6sl.dtsi
    arch/arm/boot/dts/imx6sx-14x14-arm2.dts
    arch/arm/boot/dts/imx6sx-19x19-arm2.dts
    arch/arm/boot/dts/imx6sx-sabreauto.dts
    arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
    arch/arm/boot/dts/imx6sx-sdb.dtsi
    arch/arm/boot/dts/imx6sx.dtsi
    arch/arm/boot/dts/imx6ul-14x14-evk.dts
    arch/arm/boot/dts/imx6ul-9x9-evk.dts
    arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi
    arch/arm/boot/dts/imx6ul-pinfunc.h
    arch/arm/boot/dts/imx6ul.dtsi
    arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts
    arch/arm/boot/dts/imx7d-pinfunc.h
    arch/arm/boot/dts/imx7d-sdb-epdc.dtsi
    arch/arm/boot/dts/imx7d-sdb-m4.dtsi
    arch/arm/boot/dts/imx7d-sdb-reva-touch.dts
    arch/arm/boot/dts/imx7d-sdb-reva.dts
    arch/arm/boot/dts/imx7d-sdb.dts
    arch/arm/boot/dts/imx7d.dtsi
    arch/arm/configs/imx_v7_defconfig
    arch/arm/configs/imx_v7_mfg_defconfig
    arch/arm/mach-imx/clk-imx6q.c
    arch/arm/mach-imx/clk.h
    arch/arm/mach-imx/cpuidle-imx7d.c
    arch/arm/mach-imx/ddr3_freq_imx7d.S
    arch/arm/mach-imx/gpcv2.c
    arch/arm/mach-imx/imx7d_low_power_idle.S
    arch/arm/mach-imx/lpddr3_freq_imx.S
    arch/arm/mach-imx/mach-imx7d.c
    arch/arm/mach-imx/pm-imx7.c
    arch/arm/mach-imx/suspend-imx7.S
    drivers/ata/ahci_imx.c
    drivers/cpufreq/imx6q-cpufreq.c
    drivers/dma/imx-sdma.c
    drivers/dma/pxp/pxp_dma_v2.c
    drivers/input/touchscreen/ads7846.c
    drivers/media/platform/mxc/capture/ov5640_mipi.c
    drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
    drivers/mmc/core/core.c
    drivers/mmc/core/sd.c
    drivers/mtd/spi-nor/fsl-quadspi.c
    drivers/mxc/gpu-viv/Kbuild
    drivers/mxc/gpu-viv/config
    drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
    drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h
    drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
    drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
    drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c
    drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c
    drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h
    drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c
    drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h
    drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
    drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_mutex.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
    drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
    drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config
    drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
    drivers/mxc/ipu3/ipu_common.c
    drivers/mxc/mlb/mxc_mlb.c
    drivers/net/ethernet/freescale/fec_main.c
    drivers/net/wireless/bcmdhd/dhd_linux.c
    drivers/net/wireless/bcmdhd/dhd_sdio.c
    drivers/scsi/scsi_error.c
    drivers/spi/spi-imx.c
    drivers/thermal/imx_thermal.c
    drivers/tty/serial/imx.c
    drivers/usb/chipidea/udc.c
    drivers/usb/gadget/configfs.c
    drivers/video/fbdev/mxc/mipi_dsi.c
    drivers/video/fbdev/mxc/mipi_dsi.h
    drivers/video/fbdev/mxc/mipi_dsi_samsung.c
    drivers/video/fbdev/mxc/mxc_edid.c
    drivers/video/fbdev/mxc/mxc_epdc_fb.c
    drivers/video/fbdev/mxc/mxc_epdc_v2_fb.c
    drivers/video/fbdev/mxc/mxc_ipuv3_fb.c
    drivers/video/fbdev/mxc/mxcfb_hx8369_wvga.c
    drivers/video/fbdev/mxsfb.c
    firmware/imx/sdma/sdma-imx6q.bin.ihex
    include/trace/events/cpufreq_interactive.h

    guoyin.chen
     

15 Jan, 2016

1 commit


16 Dec, 2015

1 commit


15 Dec, 2015

15 commits

  • commit 777d738a5e58ba3b6f3932ab1543ce93703f4873 upstream.

    create_request_message() computes the maximum length of a message,
    but uses the wrong type for the time stamp: sizeof(struct timespec)
    may be 8 or 16 depending on the architecture, while sizeof(struct
    ceph_timespec) is always 8, and that is what gets put into the
    message.

    Found while auditing the uses of timespec for y2038 problems.

    Fixes: b8e69066d8af ("ceph: include time stamp in every MDS request")
    Signed-off-by: Arnd Bergmann
    Signed-off-by: Yan, Zheng
    Signed-off-by: Greg Kroah-Hartman

    Arnd Bergmann
     
  • commit 8f1eb48758aacf6c1ffce18179295adbf3bd7640 upstream.

    New created file's mode is not masked with umask, and this makes umask not
    work for ocfs2 volume.

    Fixes: 702e5bc ("ocfs2: use generic posix ACL infrastructure")
    Signed-off-by: Junxiao Bi
    Cc: Gang He
    Cc: Mark Fasheh
    Cc: Joel Becker
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds
    Signed-off-by: Greg Kroah-Hartman

    Junxiao Bi
     
  • commit c812012f9ca7cf89c9e1a1cd512e6c3b5be04b85 upstream.

    If we pass in an empty nfs_fattr struct to nfs_update_inode, it will
    (correctly) not update any of the attributes, but it then clears the
    NFS_INO_INVALID_ATTR flag, which indicates that the attributes are
    up to date. Don't clear the flag if the fattr struct has no valid
    attrs to apply.

    Reviewed-by: Steve French
    Signed-off-by: Jeff Layton
    Signed-off-by: Trond Myklebust
    Signed-off-by: Greg Kroah-Hartman

    Jeff Layton
     
  • commit c68a027c05709330fe5b2f50c50d5fa02124b5d8 upstream.

    If clp->cl_cb_ident is zero, then nfs_cb_idr_remove_locked() skips removing
    it when the nfs_client is freed. A decoding or server bug can then find
    and try to put that first nfs_client which would lead to a crash.

    Signed-off-by: Benjamin Coddington
    Fixes: d6870312659d ("nfs4client: convert to idr_alloc()")
    Signed-off-by: Trond Myklebust
    Signed-off-by: Greg Kroah-Hartman

    Benjamin Coddington
     
  • commit 0ee9608c89e81a1ccee52ecb58a7ff040e2522d9 upstream.

    In debugfs' start_creating(), we pin the file system to safely access
    its root. When we failed to create a file, we unpin the file system via
    failed_creating() to release the mount count and eventually the reference
    of the vfsmount.

    However, when we run into an error during lookup_one_len() when still
    in start_creating(), we only release the parent's mutex but not so the
    reference on the mount. Looks like it was done in the past, but after
    splitting portions of __create_file() into start_creating() and
    end_creating() via 190afd81e4a5 ("debugfs: split the beginning and the
    end of __create_file() off"), this seemed missed. Noticed during code
    review.

    Fixes: 190afd81e4a5 ("debugfs: split the beginning and the end of __create_file() off")
    Signed-off-by: Daniel Borkmann
    Signed-off-by: Al Viro
    Signed-off-by: Greg Kroah-Hartman

    Daniel Borkmann
     
  • commit 34ed9872e745fa56f10e9bef2cf3d2336c6c8816 upstream.

    We've observed the nfsd server in a state where there are
    multiple delegations on the same nfs4_file for the same client.
    The nfs client does attempt to DELEGRETURN these when they are presented to
    it - but apparently under some (unknown) circumstances the client does not
    manage to return all of them. This leads to the eventual
    attempt to CB_RECALL more than one delegation with the same nfs
    filehandle to the same client. The first recall will succeed, but the
    next recall will fail with NFS4ERR_BADHANDLE. This leads to the server
    having delegations on cl_revoked that the client has no way to FREE
    or DELEGRETURN, with resulting inability to recover. The state manager
    on the server will continually assert SEQ4_STATUS_RECALLABLE_STATE_REVOKED,
    and the state manager on the client will be looping unable to satisfy
    the server.

    List discussion also reports a race between OPEN and DELEGRETURN that
    will be avoided by only sending the delegation once to the
    client. This is also logically in accordance with RFC5561 9.1.1 and 10.2.

    So, let's:

    1.) Not hand out duplicate delegations.
    2.) Only send them to the client once.

    RFC 5561:

    9.1.1:
    "Delegations and layouts, on the other hand, are not associated with a
    specific owner but are associated with the client as a whole
    (identified by a client ID)."

    10.2:
    "...the stateid for a delegation is associated with a client ID and may be
    used on behalf of all the open-owners for the given client. A
    delegation is made to the client as a whole and not to any specific
    process or thread of control within it."

    Reported-by: Eric Meddaugh
    Cc: Trond Myklebust
    Cc: Olga Kornievskaia
    Signed-off-by: Andrew Elble
    Signed-off-by: J. Bruce Fields
    Signed-off-by: Greg Kroah-Hartman

    Andrew Elble
     
  • commit 35a92fe8770ce54c5eb275cd76128645bea2d200 upstream.

    Andrew was seeing a race occur when an OPEN and OPEN_DOWNGRADE were
    running in parallel. The server would receive the OPEN_DOWNGRADE first
    and check its seqid, but then an OPEN would race in and bump it. The
    OPEN_DOWNGRADE would then complete and bump the seqid again. The result
    was that the OPEN_DOWNGRADE would be applied after the OPEN, even though
    it should have been rejected since the seqid changed.

    The only recourse we have here I think is to serialize operations that
    bump the seqid in a stateid, particularly when we're given a seqid in
    the call. To address this, we add a new rw_semaphore to the
    nfs4_ol_stateid struct. We do a down_write prior to checking the seqid
    after looking up the stateid to ensure that nothing else is going to
    bump it while we're operating on it.

    In the case of OPEN, we do a down_read, as the call doesn't contain a
    seqid. Those can run in parallel -- we just need to serialize them when
    there is a concurrent OPEN_DOWNGRADE or CLOSE.

    LOCK and LOCKU however always take the write lock as there is no
    opportunity for parallelizing those.

    Reported-and-Tested-by: Andrew W Elble
    Signed-off-by: Jeff Layton
    Signed-off-by: J. Bruce Fields
    Signed-off-by: Greg Kroah-Hartman

    Jeff Layton
     
  • commit 4327ba52afd03fc4b5afa0ee1d774c9c5b0e85c5 upstream.

    If a EXT4 filesystem utilizes JBD2 journaling and an error occurs, the
    journaling will be aborted first and the error number will be recorded
    into JBD2 superblock and, finally, the system will enter into the
    panic state in "errors=panic" option. But, in the rare case, this
    sequence is little twisted like the below figure and it will happen
    that the system enters into panic state, which means the system reset
    in mobile environment, before completion of recording an error in the
    journal superblock. In this case, e2fsck cannot recognize that the
    filesystem failure occurred in the previous run and the corruption
    wouldn't be fixed.

    Task A Task B
    ext4_handle_error()
    -> jbd2_journal_abort()
    -> __journal_abort_soft()
    -> __jbd2_journal_abort_hard()
    | -> journal->j_flags |= JBD2_ABORT;
    |
    | __ext4_abort()
    | -> jbd2_journal_abort()
    | | -> __journal_abort_soft()
    | | -> if (journal->j_flags & JBD2_ABORT)
    | | return;
    | -> panic()
    |
    -> jbd2_journal_update_sb_errno()

    Tested-by: Hobin Woo
    Signed-off-by: Daeho Jeong
    Signed-off-by: Theodore Ts'o
    Signed-off-by: Greg Kroah-Hartman

    Daeho Jeong
     
  • commit 6934da9238da947628be83635e365df41064b09b upstream.

    There is a use-after-free possibility in __ext4_journal_stop() in the
    case that we free the handle in the first jbd2_journal_stop() because
    we're referencing handle->h_err afterwards. This was introduced in
    9705acd63b125dee8b15c705216d7186daea4625 and it is wrong. Fix it by
    storing the handle->h_err value beforehand and avoid referencing
    potentially freed handle.

    Fixes: 9705acd63b125dee8b15c705216d7186daea4625
    Signed-off-by: Lukas Czerner
    Reviewed-by: Andreas Dilger
    Signed-off-by: Greg Kroah-Hartman

    Lukas Czerner
     
  • commit 937d7b84dca58f2565715f2c8e52f14c3d65fb22 upstream.

    There are times when ext4_bio_write_page() is called even though we
    don't actually need to do any I/O. This happens when ext4_writepage()
    gets called by the jbd2 commit path when an inode needs to force its
    pages written out in order to provide data=ordered guarantees --- and
    a page is backed by an unwritten (e.g., uninitialized) block on disk,
    or if delayed allocation means the page's backing store hasn't been
    allocated yet. In that case, we need to skip the call to
    ext4_encrypt_page(), since in addition to wasting CPU, it leads to a
    bounce page and an ext4 crypto context getting leaked.

    Signed-off-by: Theodore Ts'o
    Signed-off-by: Greg Kroah-Hartman

    Theodore Ts'o
     
  • commit f1cd1f0b7d1b5d4aaa5711e8f4e4898b0045cb6d upstream.

    When listing a inode's xattrs we have a time window where we race against
    a concurrent operation for adding a new hard link for our inode that makes
    us not return any xattr to user space. In order for this to happen, the
    first xattr of our inode needs to be at slot 0 of a leaf and the previous
    leaf must still have room for an inode ref (or extref) item, and this can
    happen because an inode's listxattrs callback does not lock the inode's
    i_mutex (nor does the VFS does it for us), but adding a hard link to an
    inode makes the VFS lock the inode's i_mutex before calling the inode's
    link callback.

    If we have the following leafs:

    Leaf X (has N items) Leaf Y

    [ ... (257 INODE_ITEM 0) (257 INODE_REF 256) ] [ (257 XATTR_ITEM 12345), ... ]
    slot N - 2 slot N - 1 slot 0

    The race illustrated by the following sequence diagram is possible:

    CPU 1 CPU 2

    btrfs_listxattr()

    searches for key (257 XATTR_ITEM 0)

    gets path with path->nodes[0] == leaf X
    and path->slots[0] == N

    because path->slots[0] is >=
    btrfs_header_nritems(leaf X), it calls
    btrfs_next_leaf()

    btrfs_next_leaf()
    releases the path

    adds key (257 INODE_REF 666)
    to the end of leaf X (slot N),
    and leaf X now has N + 1 items

    searches for the key (257 INODE_REF 256),
    with path->keep_locks == 1, because that
    is the last key it saw in leaf X before
    releasing the path

    ends up at leaf X again and it verifies
    that the key (257 INODE_REF 256) is no
    longer the last key in leaf X, so it
    returns with path->nodes[0] == leaf X
    and path->slots[0] == N, pointing to
    the new item with key (257 INODE_REF 666)

    btrfs_listxattr's loop iteration sees that
    the type of the key pointed by the path is
    different from the type BTRFS_XATTR_ITEM_KEY
    and so it breaks the loop and stops looking
    for more xattr items
    --> the application doesn't get any xattr
    listed for our inode

    So fix this by breaking the loop only if the key's type is greater than
    BTRFS_XATTR_ITEM_KEY and skip the current key if its type is smaller.

    Signed-off-by: Filipe Manana
    Signed-off-by: Greg Kroah-Hartman

    Filipe Manana
     
  • commit 1d512cb77bdbda80f0dd0620a3b260d697fd581d upstream.

    If we are using the NO_HOLES feature, we have a tiny time window when
    running delalloc for a nodatacow inode where we can race with a concurrent
    link or xattr add operation leading to a BUG_ON.

    This happens because at run_delalloc_nocow() we end up casting a leaf item
    of type BTRFS_INODE_[REF|EXTREF]_KEY or of type BTRFS_XATTR_ITEM_KEY to a
    file extent item (struct btrfs_file_extent_item) and then analyse its
    extent type field, which won't match any of the expected extent types
    (values BTRFS_FILE_EXTENT_[REG|PREALLOC|INLINE]) and therefore trigger an
    explicit BUG_ON(1).

    The following sequence diagram shows how the race happens when running a
    no-cow dellaloc range [4K, 8K[ for inode 257 and we have the following
    neighbour leafs:

    Leaf X (has N items) Leaf Y

    [ ... (257 INODE_ITEM 0) (257 INODE_REF 256) ] [ (257 EXTENT_DATA 8192), ... ]
    slot N - 2 slot N - 1 slot 0

    (Note the implicit hole for inode 257 regarding the [0, 8K[ range)

    CPU 1 CPU 2

    run_dealloc_nocow()
    btrfs_lookup_file_extent()
    --> searches for a key with value
    (257 EXTENT_DATA 4096) in the
    fs/subvol tree
    --> returns us a path with
    path->nodes[0] == leaf X and
    path->slots[0] == N

    because path->slots[0] is >=
    btrfs_header_nritems(leaf X), it
    calls btrfs_next_leaf()

    btrfs_next_leaf()
    --> releases the path

    hard link added to our inode,
    with key (257 INODE_REF 500)
    added to the end of leaf X,
    so leaf X now has N + 1 keys

    --> searches for the key
    (257 INODE_REF 256), because
    it was the last key in leaf X
    before it released the path,
    with path->keep_locks set to 1

    --> ends up at leaf X again and
    it verifies that the key
    (257 INODE_REF 256) is no longer
    the last key in the leaf, so it
    returns with path->nodes[0] ==
    leaf X and path->slots[0] == N,
    pointing to the new item with
    key (257 INODE_REF 500)

    the loop iteration of run_dealloc_nocow()
    does not break out the loop and continues
    because the key referenced in the path
    at path->nodes[0] and path->slots[0] is
    for inode 257, its type is < BTRFS_EXTENT_DATA_KEY
    and its offset (500) is less then our delalloc
    range's end (8192)

    the item pointed by the path, an inode reference item,
    is (incorrectly) interpreted as a file extent item and
    we get an invalid extent type, leading to the BUG_ON(1):

    if (extent_type == BTRFS_FILE_EXTENT_REG ||
    extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
    (...)
    } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
    (...)
    } else {
    BUG_ON(1)
    }

    The same can happen if a xattr is added concurrently and ends up having
    a key with an offset smaller then the delalloc's range end.

    So fix this by skipping keys with a type smaller than
    BTRFS_EXTENT_DATA_KEY.

    Signed-off-by: Filipe Manana
    Signed-off-by: Greg Kroah-Hartman

    Filipe Manana
     
  • commit aeafbf8486c9e2bd53f5cc3c10c0b7fd7149d69c upstream.

    While running a stress test I got the following warning triggered:

    [191627.672810] ------------[ cut here ]------------
    [191627.673949] WARNING: CPU: 8 PID: 8447 at fs/btrfs/file.c:779 __btrfs_drop_extents+0x391/0xa50 [btrfs]()
    (...)
    [191627.701485] Call Trace:
    [191627.702037] [] dump_stack+0x4f/0x7b
    [191627.702992] [] ? console_unlock+0x356/0x3a2
    [191627.704091] [] warn_slowpath_common+0xa1/0xbb
    [191627.705380] [] ? __btrfs_drop_extents+0x391/0xa50 [btrfs]
    [191627.706637] [] warn_slowpath_null+0x1a/0x1c
    [191627.707789] [] __btrfs_drop_extents+0x391/0xa50 [btrfs]
    [191627.709155] [] ? cache_alloc_debugcheck_after.isra.32+0x171/0x1d0
    [191627.712444] [] ? kmemleak_alloc_recursive.constprop.40+0x16/0x18
    [191627.714162] [] insert_reserved_file_extent.constprop.40+0x83/0x24e [btrfs]
    [191627.715887] [] ? start_transaction+0x3bb/0x610 [btrfs]
    [191627.717287] [] btrfs_finish_ordered_io+0x273/0x4e2 [btrfs]
    [191627.728865] [] finish_ordered_fn+0x15/0x17 [btrfs]
    [191627.730045] [] normal_work_helper+0x14c/0x32c [btrfs]
    [191627.731256] [] btrfs_endio_write_helper+0x12/0x14 [btrfs]
    [191627.732661] [] process_one_work+0x24c/0x4ae
    [191627.733822] [] worker_thread+0x206/0x2c2
    [191627.734857] [] ? process_scheduled_works+0x2f/0x2f
    [191627.736052] [] ? process_scheduled_works+0x2f/0x2f
    [191627.737349] [] kthread+0xef/0xf7
    [191627.738267] [] ? time_hardirqs_on+0x15/0x28
    [191627.739330] [] ? __kthread_parkme+0xad/0xad
    [191627.741976] [] ret_from_fork+0x42/0x70
    [191627.743080] [] ? __kthread_parkme+0xad/0xad
    [191627.744206] ---[ end trace bbfddacb7aaada8d ]---

    $ cat -n fs/btrfs/file.c
    691 int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
    (...)
    758 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
    759 if (key.objectid > ino ||
    760 key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
    761 break;
    762
    763 fi = btrfs_item_ptr(leaf, path->slots[0],
    764 struct btrfs_file_extent_item);
    765 extent_type = btrfs_file_extent_type(leaf, fi);
    766
    767 if (extent_type == BTRFS_FILE_EXTENT_REG ||
    768 extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
    (...)
    774 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
    (...)
    778 } else {
    779 WARN_ON(1);
    780 extent_end = search_start;
    781 }
    (...)

    This happened because the item we were processing did not match a file
    extent item (its key type != BTRFS_EXTENT_DATA_KEY), and even on this
    case we cast the item to a struct btrfs_file_extent_item pointer and
    then find a type field value that does not match any of the expected
    values (BTRFS_FILE_EXTENT_[REG|PREALLOC|INLINE]). This scenario happens
    due to a tiny time window where a race can happen as exemplified below.
    For example, consider the following scenario where we're using the
    NO_HOLES feature and we have the following two neighbour leafs:

    Leaf X (has N items) Leaf Y

    [ ... (257 INODE_ITEM 0) (257 INODE_REF 256) ] [ (257 EXTENT_DATA 8192), ... ]
    slot N - 2 slot N - 1 slot 0

    Our inode 257 has an implicit hole in the range [0, 8K[ (implicit rather
    than explicit because NO_HOLES is enabled). Now if our inode has an
    ordered extent for the range [4K, 8K[ that is finishing, the following
    can happen:

    CPU 1 CPU 2

    btrfs_finish_ordered_io()
    insert_reserved_file_extent()
    __btrfs_drop_extents()
    Searches for the key
    (257 EXTENT_DATA 4096) through
    btrfs_lookup_file_extent()

    Key not found and we get a path where
    path->nodes[0] == leaf X and
    path->slots[0] == N

    Because path->slots[0] is >=
    btrfs_header_nritems(leaf X), we call
    btrfs_next_leaf()

    btrfs_next_leaf() releases the path

    inserts key
    (257 INODE_REF 4096)
    at the end of leaf X,
    leaf X now has N + 1 keys,
    and the new key is at
    slot N

    btrfs_next_leaf() searches for
    key (257 INODE_REF 256), with
    path->keep_locks set to 1,
    because it was the last key it
    saw in leaf X

    finds it in leaf X again and
    notices it's no longer the last
    key of the leaf, so it returns 0
    with path->nodes[0] == leaf X and
    path->slots[0] == N (which is now
    < btrfs_header_nritems(leaf X)),
    pointing to the new key
    (257 INODE_REF 4096)

    __btrfs_drop_extents() casts the
    item at path->nodes[0], slot
    path->slots[0], to a struct
    btrfs_file_extent_item - it does
    not skip keys for the target
    inode with a type less than
    BTRFS_EXTENT_DATA_KEY
    (BTRFS_INODE_REF_KEY < BTRFS_EXTENT_DATA_KEY)

    sees a bogus value for the type
    field triggering the WARN_ON in
    the trace shown above, and sets
    extent_end = search_start (4096)

    does the if-then-else logic to
    fixup 0 length extent items created
    by a past bug from hole punching:

    if (extent_end == key.offset &&
    extent_end >= search_start)
    goto delete_extent_item;

    that evaluates to true and it ends
    up deleting the key pointed to by
    path->slots[0], (257 INODE_REF 4096),
    from leaf X

    The same could happen for example for a xattr that ends up having a key
    with an offset value that matches search_start (very unlikely but not
    impossible).

    So fix this by ensuring that keys smaller than BTRFS_EXTENT_DATA_KEY are
    skipped, never casted to struct btrfs_file_extent_item and never deleted
    by accident. Also protect against the unexpected case of getting a key
    for a lower inode number by skipping that key and issuing a warning.

    Signed-off-by: Filipe Manana
    Signed-off-by: Greg Kroah-Hartman

    Filipe Manana
     
  • commit 0305cd5f7fca85dae392b9ba85b116896eb7c1c7 upstream.

    When truncating a file to a smaller size which consists of an inline
    extent that is compressed, we did not discard (or made unusable) the
    data between the new file size and the old file size, wasting metadata
    space and allowing for the truncated data to be leaked and the data
    corruption/loss mentioned below.
    We were also not correctly decrementing the number of bytes used by the
    inode, we were setting it to zero, giving a wrong report for callers of
    the stat(2) syscall. The fsck tool also reported an error about a mismatch
    between the nbytes of the file versus the real space used by the file.

    Now because we weren't discarding the truncated region of the file, it
    was possible for a caller of the clone ioctl to actually read the data
    that was truncated, allowing for a security breach without requiring root
    access to the system, using only standard filesystem operations. The
    scenario is the following:

    1) User A creates a file which consists of an inline and compressed
    extent with a size of 2000 bytes - the file is not accessible to
    any other users (no read, write or execution permission for anyone
    else);

    2) The user truncates the file to a size of 1000 bytes;

    3) User A makes the file world readable;

    4) User B creates a file consisting of an inline extent of 2000 bytes;

    5) User B issues a clone operation from user A's file into its own
    file (using a length argument of 0, clone the whole range);

    6) User B now gets to see the 1000 bytes that user A truncated from
    its file before it made its file world readbale. User B also lost
    the bytes in the range [1000, 2000[ bytes from its own file, but
    that might be ok if his/her intention was reading stale data from
    user A that was never supposed to be public.

    Note that this contrasts with the case where we truncate a file from 2000
    bytes to 1000 bytes and then truncate it back from 1000 to 2000 bytes. In
    this case reading any byte from the range [1000, 2000[ will return a value
    of 0x00, instead of the original data.

    This problem exists since the clone ioctl was added and happens both with
    and without my recent data loss and file corruption fixes for the clone
    ioctl (patch "Btrfs: fix file corruption and data loss after cloning
    inline extents").

    So fix this by truncating the compressed inline extents as we do for the
    non-compressed case, which involves decompressing, if the data isn't already
    in the page cache, compressing the truncated version of the extent, writing
    the compressed content into the inline extent and then truncate it.

    The following test case for fstests reproduces the problem. In order for
    the test to pass both this fix and my previous fix for the clone ioctl
    that forbids cloning a smaller inline extent into a larger one,
    which is titled "Btrfs: fix file corruption and data loss after cloning
    inline extents", are needed. Without that other fix the test fails in a
    different way that does not leak the truncated data, instead part of
    destination file gets replaced with zeroes (because the destination file
    has a larger inline extent than the source).

    seq=`basename $0`
    seqres=$RESULT_DIR/$seq
    echo "QA output created by $seq"
    tmp=/tmp/$$
    status=1 # failure is the default!
    trap "_cleanup; exit \$status" 0 1 2 3 15

    _cleanup()
    {
    rm -f $tmp.*
    }

    # get standard environment, filters and checks
    . ./common/rc
    . ./common/filter

    # real QA test starts here
    _need_to_be_root
    _supported_fs btrfs
    _supported_os Linux
    _require_scratch
    _require_cloner

    rm -f $seqres.full

    _scratch_mkfs >>$seqres.full 2>&1
    _scratch_mount "-o compress"

    # Create our test files. File foo is going to be the source of a clone operation
    # and consists of a single inline extent with an uncompressed size of 512 bytes,
    # while file bar consists of a single inline extent with an uncompressed size of
    # 256 bytes. For our test's purpose, it's important that file bar has an inline
    # extent with a size smaller than foo's inline extent.
    $XFS_IO_PROG -f -c "pwrite -S 0xa1 0 128" \
    -c "pwrite -S 0x2a 128 384" \
    $SCRATCH_MNT/foo | _filter_xfs_io
    $XFS_IO_PROG -f -c "pwrite -S 0xbb 0 256" $SCRATCH_MNT/bar | _filter_xfs_io

    # Now durably persist all metadata and data. We do this to make sure that we get
    # on disk an inline extent with a size of 512 bytes for file foo.
    sync

    # Now truncate our file foo to a smaller size. Because it consists of a
    # compressed and inline extent, btrfs did not shrink the inline extent to the
    # new size (if the extent was not compressed, btrfs would shrink it to 128
    # bytes), it only updates the inode's i_size to 128 bytes.
    $XFS_IO_PROG -c "truncate 128" $SCRATCH_MNT/foo

    # Now clone foo's inline extent into bar.
    # This clone operation should fail with errno EOPNOTSUPP because the source
    # file consists only of an inline extent and the file's size is smaller than
    # the inline extent of the destination (128 bytes < 256 bytes). However the
    # clone ioctl was not prepared to deal with a file that has a size smaller
    # than the size of its inline extent (something that happens only for compressed
    # inline extents), resulting in copying the full inline extent from the source
    # file into the destination file.
    #
    # Note that btrfs' clone operation for inline extents consists of removing the
    # inline extent from the destination inode and copy the inline extent from the
    # source inode into the destination inode, meaning that if the destination
    # inode's inline extent is larger (N bytes) than the source inode's inline
    # extent (M bytes), some bytes (N - M bytes) will be lost from the destination
    # file. Btrfs could copy the source inline extent's data into the destination's
    # inline extent so that we would not lose any data, but that's currently not
    # done due to the complexity that would be needed to deal with such cases
    # (specially when one or both extents are compressed), returning EOPNOTSUPP, as
    # it's normally not a very common case to clone very small files (only case
    # where we get inline extents) and copying inline extents does not save any
    # space (unlike for normal, non-inlined extents).
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar

    # Now because the above clone operation used to succeed, and due to foo's inline
    # extent not being shinked by the truncate operation, our file bar got the whole
    # inline extent copied from foo, making us lose the last 128 bytes from bar
    # which got replaced by the bytes in range [128, 256[ from foo before foo was
    # truncated - in other words, data loss from bar and being able to read old and
    # stale data from foo that should not be possible to read anymore through normal
    # filesystem operations. Contrast with the case where we truncate a file from a
    # size N to a smaller size M, truncate it back to size N and then read the range
    # [M, N[, we should always get the value 0x00 for all the bytes in that range.

    # We expected the clone operation to fail with errno EOPNOTSUPP and therefore
    # not modify our file's bar data/metadata. So its content should be 256 bytes
    # long with all bytes having the value 0xbb.
    #
    # Without the btrfs bug fix, the clone operation succeeded and resulted in
    # leaking truncated data from foo, the bytes that belonged to its range
    # [128, 256[, and losing data from bar in that same range. So reading the
    # file gave us the following content:
    #
    # 0000000 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1
    # *
    # 0000200 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a
    # *
    # 0000400
    echo "File bar's content after the clone operation:"
    od -t x1 $SCRATCH_MNT/bar

    # Also because the foo's inline extent was not shrunk by the truncate
    # operation, btrfs' fsck, which is run by the fstests framework everytime a
    # test completes, failed reporting the following error:
    #
    # root 5 inode 257 errors 400, nbytes wrong

    status=0
    exit

    Signed-off-by: Filipe Manana
    Signed-off-by: Greg Kroah-Hartman

    Filipe Manana
     
  • commit 8039d87d9e473aeb740d4fdbd59b9d2f89b2ced9 upstream.

    Currently the clone ioctl allows to clone an inline extent from one file
    to another that already has other (non-inlined) extents. This is a problem
    because btrfs is not designed to deal with files having inline and regular
    extents, if a file has an inline extent then it must be the only extent
    in the file and must start at file offset 0. Having a file with an inline
    extent followed by regular extents results in EIO errors when doing reads
    or writes against the first 4K of the file.

    Also, the clone ioctl allows one to lose data if the source file consists
    of a single inline extent, with a size of N bytes, and the destination
    file consists of a single inline extent with a size of M bytes, where we
    have M > N. In this case the clone operation removes the inline extent
    from the destination file and then copies the inline extent from the
    source file into the destination file - we lose the M - N bytes from the
    destination file, a read operation will get the value 0x00 for any bytes
    in the the range [N, M] (the destination inode's i_size remained as M,
    that's why we can read past N bytes).

    So fix this by not allowing such destructive operations to happen and
    return errno EOPNOTSUPP to user space.

    Currently the fstest btrfs/035 tests the data loss case but it totally
    ignores this - i.e. expects the operation to succeed and does not check
    the we got data loss.

    The following test case for fstests exercises all these cases that result
    in file corruption and data loss:

    seq=`basename $0`
    seqres=$RESULT_DIR/$seq
    echo "QA output created by $seq"
    tmp=/tmp/$$
    status=1 # failure is the default!
    trap "_cleanup; exit \$status" 0 1 2 3 15

    _cleanup()
    {
    rm -f $tmp.*
    }

    # get standard environment, filters and checks
    . ./common/rc
    . ./common/filter

    # real QA test starts here
    _need_to_be_root
    _supported_fs btrfs
    _supported_os Linux
    _require_scratch
    _require_cloner
    _require_btrfs_fs_feature "no_holes"
    _require_btrfs_mkfs_feature "no-holes"

    rm -f $seqres.full

    test_cloning_inline_extents()
    {
    local mkfs_opts=$1
    local mount_opts=$2

    _scratch_mkfs $mkfs_opts >>$seqres.full 2>&1
    _scratch_mount $mount_opts

    # File bar, the source for all the following clone operations, consists
    # of a single inline extent (50 bytes).
    $XFS_IO_PROG -f -c "pwrite -S 0xbb 0 50" $SCRATCH_MNT/bar \
    | _filter_xfs_io

    # Test cloning into a file with an extent (non-inlined) where the
    # destination offset overlaps that extent. It should not be possible to
    # clone the inline extent from file bar into this file.
    $XFS_IO_PROG -f -c "pwrite -S 0xaa 0K 16K" $SCRATCH_MNT/foo \
    | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo

    # Doing IO against any range in the first 4K of the file should work.
    # Due to a past clone ioctl bug which allowed cloning the inline extent,
    # these operations resulted in EIO errors.
    echo "File foo data after clone operation:"
    # All bytes should have the value 0xaa (clone operation failed and did
    # not modify our file).
    od -t x1 $SCRATCH_MNT/foo
    $XFS_IO_PROG -c "pwrite -S 0xcc 0 100" $SCRATCH_MNT/foo | _filter_xfs_io

    # Test cloning the inline extent against a file which has a hole in its
    # first 4K followed by a non-inlined extent. It should not be possible
    # as well to clone the inline extent from file bar into this file.
    $XFS_IO_PROG -f -c "pwrite -S 0xdd 4K 12K" $SCRATCH_MNT/foo2 \
    | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo2

    # Doing IO against any range in the first 4K of the file should work.
    # Due to a past clone ioctl bug which allowed cloning the inline extent,
    # these operations resulted in EIO errors.
    echo "File foo2 data after clone operation:"
    # All bytes should have the value 0x00 (clone operation failed and did
    # not modify our file).
    od -t x1 $SCRATCH_MNT/foo2
    $XFS_IO_PROG -c "pwrite -S 0xee 0 90" $SCRATCH_MNT/foo2 | _filter_xfs_io

    # Test cloning the inline extent against a file which has a size of zero
    # but has a prealloc extent. It should not be possible as well to clone
    # the inline extent from file bar into this file.
    $XFS_IO_PROG -f -c "falloc -k 0 1M" $SCRATCH_MNT/foo3 | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo3

    # Doing IO against any range in the first 4K of the file should work.
    # Due to a past clone ioctl bug which allowed cloning the inline extent,
    # these operations resulted in EIO errors.
    echo "First 50 bytes of foo3 after clone operation:"
    # Should not be able to read any bytes, file has 0 bytes i_size (the
    # clone operation failed and did not modify our file).
    od -t x1 $SCRATCH_MNT/foo3
    $XFS_IO_PROG -c "pwrite -S 0xff 0 90" $SCRATCH_MNT/foo3 | _filter_xfs_io

    # Test cloning the inline extent against a file which consists of a
    # single inline extent that has a size not greater than the size of
    # bar's inline extent (40 < 50).
    # It should be possible to do the extent cloning from bar to this file.
    $XFS_IO_PROG -f -c "pwrite -S 0x01 0 40" $SCRATCH_MNT/foo4 \
    | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo4

    # Doing IO against any range in the first 4K of the file should work.
    echo "File foo4 data after clone operation:"
    # Must match file bar's content.
    od -t x1 $SCRATCH_MNT/foo4
    $XFS_IO_PROG -c "pwrite -S 0x02 0 90" $SCRATCH_MNT/foo4 | _filter_xfs_io

    # Test cloning the inline extent against a file which consists of a
    # single inline extent that has a size greater than the size of bar's
    # inline extent (60 > 50).
    # It should not be possible to clone the inline extent from file bar
    # into this file.
    $XFS_IO_PROG -f -c "pwrite -S 0x03 0 60" $SCRATCH_MNT/foo5 \
    | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo5

    # Reading the file should not fail.
    echo "File foo5 data after clone operation:"
    # Must have a size of 60 bytes, with all bytes having a value of 0x03
    # (the clone operation failed and did not modify our file).
    od -t x1 $SCRATCH_MNT/foo5

    # Test cloning the inline extent against a file which has no extents but
    # has a size greater than bar's inline extent (16K > 50).
    # It should not be possible to clone the inline extent from file bar
    # into this file.
    $XFS_IO_PROG -f -c "truncate 16K" $SCRATCH_MNT/foo6 | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo6

    # Reading the file should not fail.
    echo "File foo6 data after clone operation:"
    # Must have a size of 16K, with all bytes having a value of 0x00 (the
    # clone operation failed and did not modify our file).
    od -t x1 $SCRATCH_MNT/foo6

    # Test cloning the inline extent against a file which has no extents but
    # has a size not greater than bar's inline extent (30 < 50).
    # It should be possible to clone the inline extent from file bar into
    # this file.
    $XFS_IO_PROG -f -c "truncate 30" $SCRATCH_MNT/foo7 | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo7

    # Reading the file should not fail.
    echo "File foo7 data after clone operation:"
    # Must have a size of 50 bytes, with all bytes having a value of 0xbb.
    od -t x1 $SCRATCH_MNT/foo7

    # Test cloning the inline extent against a file which has a size not
    # greater than the size of bar's inline extent (20 < 50) but has
    # a prealloc extent that goes beyond the file's size. It should not be
    # possible to clone the inline extent from bar into this file.
    $XFS_IO_PROG -f -c "falloc -k 0 1M" \
    -c "pwrite -S 0x88 0 20" \
    $SCRATCH_MNT/foo8 | _filter_xfs_io
    $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo8

    echo "File foo8 data after clone operation:"
    # Must have a size of 20 bytes, with all bytes having a value of 0x88
    # (the clone operation did not modify our file).
    od -t x1 $SCRATCH_MNT/foo8

    _scratch_unmount
    }

    echo -e "\nTesting without compression and without the no-holes feature...\n"
    test_cloning_inline_extents

    echo -e "\nTesting with compression and without the no-holes feature...\n"
    test_cloning_inline_extents "" "-o compress"

    echo -e "\nTesting without compression and with the no-holes feature...\n"
    test_cloning_inline_extents "-O no-holes" ""

    echo -e "\nTesting with compression and with the no-holes feature...\n"
    test_cloning_inline_extents "-O no-holes" "-o compress"

    status=0
    exit

    Signed-off-by: Filipe Manana
    Signed-off-by: Greg Kroah-Hartman

    Filipe Manana
     

10 Dec, 2015

1 commit

  • commit b2f73922d119686323f14fbbe46587f863852328 upstream.

    So the /proc/PID/stat 'wchan' field (the 30th field, which contains
    the absolute kernel address of the kernel function a task is blocked in)
    leaks absolute kernel addresses to unprivileged user-space:

    seq_put_decimal_ull(m, ' ', wchan);

    The absolute address might also leak via /proc/PID/wchan as well, if
    KALLSYMS is turned off or if the symbol lookup fails for some reason:

    static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
    struct pid *pid, struct task_struct *task)
    {
    unsigned long wchan;
    char symname[KSYM_NAME_LEN];

    wchan = get_wchan(task);

    if (lookup_symbol_name(wchan, symname) < 0) {
    if (!ptrace_may_access(task, PTRACE_MODE_READ))
    return 0;
    seq_printf(m, "%lu", wchan);
    } else {
    seq_printf(m, "%s", symname);
    }

    return 0;
    }

    This isn't ideal, because for example it trivially leaks the KASLR offset
    to any local attacker:

    fomalhaut:~> printf "%016lx\n" $(cat /proc/$$/stat | cut -d' ' -f35)
    ffffffff8123b380

    Most real-life uses of wchan are symbolic:

    ps -eo pid:10,tid:10,wchan:30,comm

    and procps uses /proc/PID/wchan, not the absolute address in /proc/PID/stat:

    triton:~/tip> strace -f ps -eo pid:10,tid:10,wchan:30,comm 2>&1 | grep wchan | tail -1
    open("/proc/30833/wchan", O_RDONLY) = 6

    There's one compatibility quirk here: procps relies on whether the
    absolute value is non-zero - and we can provide that functionality
    by outputing "0" or "1" depending on whether the task is blocked
    (whether there's a wchan address).

    These days there appears to be very little legitimate reason
    user-space would be interested in the absolute address. The
    absolute address is mostly historic: from the days when we
    didn't have kallsyms and user-space procps had to do the
    decoding itself via the System.map.

    So this patch sets all numeric output to "0" or "1" and keeps only
    symbolic output, in /proc/PID/wchan.

    ( The absolute sleep address can generally still be profiled via
    perf, by tasks with sufficient privileges. )

    Reviewed-by: Thomas Gleixner
    Acked-by: Kees Cook
    Acked-by: Linus Torvalds
    Cc: Al Viro
    Cc: Alexander Potapenko
    Cc: Andrey Konovalov
    Cc: Andrey Ryabinin
    Cc: Andy Lutomirski
    Cc: Andy Lutomirski
    Cc: Borislav Petkov
    Cc: Denys Vlasenko
    Cc: Dmitry Vyukov
    Cc: Kostya Serebryany
    Cc: Mike Galbraith
    Cc: Peter Zijlstra
    Cc: Peter Zijlstra
    Cc: Sasha Levin
    Cc: kasan-dev
    Cc: linux-kernel@vger.kernel.org
    Link: http://lkml.kernel.org/r/20150930135917.GA3285@gmail.com
    Signed-off-by: Ingo Molnar
    Signed-off-by: Greg Kroah-Hartman

    Ingo Molnar
     

20 Nov, 2015

10 commits

  • Avoid waking up every thread sleeping in an epoll_wait call during
    suspend and resume by calling a freezable blocking call. Previous
    patches modified the freezer to avoid sending wakeups to threads
    that are blocked in freezable blocking calls.

    This call was selected to be converted to a freezable call because
    it doesn't hold any locks or release any resources when interrupted
    that might be needed by another freezing task or a kernel driver
    during suspend, and is a common site where idle userspace tasks are
    blocked.

    Change-Id: I848d08d28c89302fd42bbbdfa76489a474ab27bf
    Acked-by: Tejun Heo
    Signed-off-by: Colin Cross
    Signed-off-by: Rafael J. Wysocki

    Colin Cross
     
  • adb reboot calls /proc/sysrq-trigger to force an emergency remount (ro) of all
    mounted disks. This is executed in the order of the time the mount was originally
    done. Because we have a test system which loop mount images from an extra
    partition, we see errors cause the loop mounted partitions gets remounted after
    this physical partition was set to read only already.

    Fix this by reversing the order of the emergency remount. This will remount the
    disk first which have been mounted last.

    So instead of remounting in this order:
    /dev/sda1
    /dev/loop1
    /dev/loop2
    we now remount in this order:
    /dev/loop2
    /dev/loop1
    /dev/sda1

    Change-Id: I68fe7e16cc9400ab5278877af70c9ea1d9b57936
    Signed-off-by: Christian Poetzsch

    Christian Poetzsch
     
  • * What
    This provides an interface for issuing an FITRIM which uses the
    secure discard instead of just a discard.
    Only the eMMC command is "secure", and not how the FS uses it:
    due to the fact that the FS might reassign a region somewhere else,
    the original deleted data will not be affected by the "trim" which only
    handles un-used regions.
    So we'll just call it "deep discard", and note that this is a
    "best effort" cleanup.

    * Why
    Once in a while, We want to be able to cleanup most of the unused blocks
    after erasing a bunch of files.
    We don't want to constantly secure-discard via a mount option.

    From an eMMC spec perspective, it tells the device to really get rid of
    all the data for the specified blocks and not just put them back into the
    pool of free ones (unlike the normal TRIM). The eMMC spec says the
    secure trim handling must make sure the data (and metadata) is not available
    anymore. A simple TRIM doesn't clear the data, it just puts blocks in the
    free pool.
    JEDEC Standard No. 84-A441
    7.6.9 Secure Erase
    7.6.10 Secure Trim

    From an FS perspective, it is acceptable to leave some data behind.
    - directory entries related to deleted files
    - databases entries related to deleted files
    - small-file data stored in inode extents
    - blocks held by the FS waiting to be re-used (mitigated by sync).
    - blocks reassigned by the FS prior to FIDTRIM.

    Change-Id: I676a1404a80130d93930c84898360f2e6fb2f81e
    Signed-off-by: Geremy Condra
    Signed-off-by: JP Abgrall

    JP Abgrall
     
  • Suspend attempts can abort when the FUSE daemon is already frozen
    and a client is waiting uninterruptibly for a response, causing
    freezing of tasks to fail.

    Use the freeze-friendly wait API, but disregard other signals.

    Change-Id: Icefb7e4bbc718ccb76bf3c04daaa5eeea7e0e63c
    Signed-off-by: Todd Poynor

    Todd Poynor
     
  • Userspace processes often have multiple allocators that each do
    anonymous mmaps to get memory. When examining memory usage of
    individual processes or systems as a whole, it is useful to be
    able to break down the various heaps that were allocated by
    each layer and examine their size, RSS, and physical memory
    usage.

    This patch adds a user pointer to the shared union in
    vm_area_struct that points to a null terminated string inside
    the user process containing a name for the vma. vmas that
    point to the same address will be merged, but vmas that
    point to equivalent strings at different addresses will
    not be merged.

    Userspace can set the name for a region of memory by calling
    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, (unsigned long)name);
    Setting the name to NULL clears it.

    The names of named anonymous vmas are shown in /proc/pid/maps
    as [anon:] and in /proc/pid/smaps in a new "Name" field
    that is only present for named vmas. If the userspace pointer
    is no longer valid all or part of the name will be replaced
    with "".

    The idea to store a userspace pointer to reduce the complexity
    within mm (at the expense of the complexity of reading
    /proc/pid/mem) came from Dave Hansen. This results in no
    runtime overhead in the mm subsystem other than comparing
    the anon_name pointers when considering vma merging. The pointer
    is stored in a union with fieds that are only used on file-backed
    mappings, so it does not increase memory usage.

    Includes fix from Jed Davis for typo in
    prctl_set_vma_anon_name, which could attempt to set the name
    across two vmas at the same time due to a typo, which might
    corrupt the vma list. Fix it to use tmp instead of end to limit
    the name setting to a single vma at a time.

    Change-Id: I9aa7b6b5ef536cd780599ba4e2fba8ceebe8b59f
    Signed-off-by: Dmitry Shmidt

    Colin Cross
     
  • Signed-off-by: Mark Salyzyn
    Bug: 23385441
    Change-Id: I1c6d98ea23f2fde4e59b6535fcce3a69d862da9b

    Mark Salyzyn
     
  • Allow writing into the ramoops console buffer.

    Change-Id: Iff0d69b562e4dae33ea7f8d19412227bebb17e47
    Signed-off-by: Arve Hjønnevåg

    Arve Hjønnevåg
     
  • Fix the build by removing the duplicate line that uses the obsolete INF
    macro.

    Signed-off-by: Dan Willemsen

    Dan Willemsen
     
  • Make oom_adj and oom_score_adj user read-only.

    Bug: 19636629
    Change-Id: I055bb172d5b4d3d856e25918f3c5de8edf31e4a3
    Signed-off-by: Rom Lemarchand

    Rom Lemarchand
     
  • Signed-off-by: San Mehat

    San Mehat
     

10 Nov, 2015

5 commits

  • commit 0f89abf56abbd0e1c6e3cef9813e6d9f05383c1e upstream.

    Commit 8eb934591f8b ("btrfs: check unsupported filters in balance
    arguments") adds a jump to exit label out_bargs in case the argument
    check fails. At this point in addition to the bargs memory, the
    memory for struct btrfs_balance_control has already been allocated.
    Ownership of bctl is passed to btrfs_balance() in the good case,
    thus the memory is not freed due to the introduced jump. Make sure
    that the memory gets freed in any case as necessary. Detected by
    Coverity CID 1328378.

    Signed-off-by: Christian Engelmayer
    Reviewed-by: David Sterba
    Signed-off-by: Chris Mason
    Signed-off-by: Greg Kroah-Hartman

    Christian Engelmayer
     
  • commit ab79efab0a0ba01a74df782eb7fa44b044dae8b5 upstream.

    In ovl_copy_up_locked(), newdentry is leaked if the function exits through
    out_cleanup as this just to out after calling ovl_cleanup() - which doesn't
    actually release the ref on newdentry.

    The out_cleanup segment should instead exit through out2 as certainly
    newdentry leaks - and possibly upper does also, though this isn't caught
    given the catch of newdentry.

    Without this fix, something like the following is seen:

    BUG: Dentry ffff880023e9eb20{i=f861,n=#ffff880023e82d90} still in use (1) [unmount of tmpfs tmpfs]
    BUG: Dentry ffff880023ece640{i=0,n=bigfile} still in use (1) [unmount of tmpfs tmpfs]

    when unmounting the upper layer after an error occurred in copyup.

    An error can be induced by creating a big file in a lower layer with
    something like:

    dd if=/dev/zero of=/lower/a/bigfile bs=65536 count=1 seek=$((0xf000))

    to create a large file (4.1G). Overlay an upper layer that is too small
    (on tmpfs might do) and then induce a copy up by opening it writably.

    Reported-by: Ulrich Obergfell
    Signed-off-by: David Howells
    Signed-off-by: Miklos Szeredi
    Signed-off-by: Greg Kroah-Hartman

    David Howells
     
  • commit 0480334fa60488d12ae101a02d7d9e1a3d03d7dd upstream.

    Open the lower file with O_LARGEFILE in ovl_copy_up().

    Pass O_LARGEFILE unconditionally in ovl_copy_up_data() as it's purely for
    catching 32-bit userspace dealing with a file large enough that it'll be
    mishandled if the application isn't aware that there might be an integer
    overflow. Inside the kernel, there shouldn't be any problems.

    Reported-by: Ulrich Obergfell
    Signed-off-by: David Howells
    Signed-off-by: Miklos Szeredi
    Signed-off-by: Greg Kroah-Hartman

    David Howells
     
  • commit 5ffdbe8bf1e485026e1c7e4714d2841553cf0b40 upstream.

    This fixes memory leak after umount.

    Kmemleak report:

    unreferenced object 0xffff8800ba791010 (size 8):
    comm "mount", pid 2394, jiffies 4294996294 (age 53.920s)
    hex dump (first 8 bytes):
    20 1c 13 02 00 88 ff ff .......
    backtrace:
    [] create_object+0x124/0x2c0
    [] kmemleak_alloc+0x7b/0xc0
    [] __kmalloc+0x106/0x340
    [] ovl_fill_super+0x55c/0x9b0 [overlay]
    [] mount_nodev+0x54/0xa0
    [] ovl_mount+0x18/0x20 [overlay]
    [] mount_fs+0x43/0x170
    [] vfs_kern_mount+0x74/0x170
    [] do_mount+0x22d/0xdf0
    [] SyS_mount+0x7b/0xc0
    [] entry_SYSCALL_64_fastpath+0x12/0x76
    [] 0xffffffffffffffff

    Signed-off-by: Konstantin Khlebnikov
    Signed-off-by: Miklos Szeredi
    Fixes: dd662667e6d3 ("ovl: add mutli-layer infrastructure")
    Signed-off-by: Greg Kroah-Hartman

    Konstantin Khlebnikov
     
  • commit 0f95502ad84874b3c05fc7cdd9d4d9d5cddf7859 upstream.

    This fixes small memory leak after mount.

    Kmemleak report:

    unreferenced object 0xffff88003683fe00 (size 16):
    comm "mount", pid 2029, jiffies 4294909563 (age 33.380s)
    hex dump (first 16 bytes):
    20 27 1f bb 00 88 ff ff 40 4b 0f 36 02 88 ff ff '......@K.6....
    backtrace:
    [] create_object+0x124/0x2c0
    [] kmemleak_alloc+0x7b/0xc0
    [] __kmalloc+0x106/0x340
    [] ovl_fill_super+0x389/0x9a0 [overlay]
    [] mount_nodev+0x54/0xa0
    [] ovl_mount+0x18/0x20 [overlay]
    [] mount_fs+0x43/0x170
    [] vfs_kern_mount+0x74/0x170
    [] do_mount+0x22d/0xdf0
    [] SyS_mount+0x7b/0xc0
    [] entry_SYSCALL_64_fastpath+0x12/0x76
    [] 0xffffffffffffffff

    Signed-off-by: Konstantin Khlebnikov
    Signed-off-by: Miklos Szeredi
    Fixes: a78d9f0d5d5c ("ovl: support multiple lower layers")
    Signed-off-by: Greg Kroah-Hartman

    Konstantin Khlebnikov
     

27 Oct, 2015

5 commits

  • commit 83bfff23e9ed19f37c4ef0bba84e75bd88e5cf21 upstream.

    Now that we have file locking helpers that can deal with an inode
    instead of a filp, we can change the NFSv4 locking code to use that
    instead.

    This should fix the case where we have a filp that is closed while flock
    or OFD locks are set on it, and the task is signaled so that it doesn't
    wait for the LOCKU reply to come in before the filp is freed. At that
    point we can end up with a use-after-free with the current code, which
    relies on dereferencing the fl_file in the lock request.

    Signed-off-by: Jeff Layton
    Reviewed-by: "J. Bruce Fields"
    Tested-by: "J. Bruce Fields"
    Cc: William Dauchy
    Signed-off-by: Greg Kroah-Hartman

    Jeff Layton
     
  • commit ee296d7c5709440f8abd36b5b65c6b3e388538d9 upstream.

    They just call file_inode and then the corresponding *_inode_file_wait
    function. Just make them static inlines instead.

    Signed-off-by: Jeff Layton
    Cc: William Dauchy
    Signed-off-by: Greg Kroah-Hartman

    Jeff Layton
     
  • commit 29d01b22eaa18d8b46091d3c98c6001c49f78e4a upstream.

    Allow callers to pass in an inode instead of a filp.

    Signed-off-by: Jeff Layton
    Reviewed-by: "J. Bruce Fields"
    Tested-by: "J. Bruce Fields"
    Cc: William Dauchy
    Signed-off-by: Greg Kroah-Hartman

    Jeff Layton
     
  • commit bcd7f78d078ff6197715c1ed070c92aca57ec12c upstream.

    ...and rename it to better describe how it works.

    In order to fix a use-after-free in NFS, we need to be able to remove
    locks from an inode after the filp associated with them may have already
    been freed. flock_lock_file already only dereferences the filp to get to
    the inode, so just change it so the callers do that.

    All of the callers already pass in a lock request that has the fl_file
    set properly, so we don't need to pass it in individually. With that
    change it now only dereferences the filp to get to the inode, so just
    push that out to the callers.

    Signed-off-by: Jeff Layton
    Reviewed-by: "J. Bruce Fields"
    Tested-by: "J. Bruce Fields"
    Cc: William Dauchy
    Signed-off-by: Greg Kroah-Hartman

    Jeff Layton
     
  • commit 8c3ad9cb7343dc5f61b8cf3cdbe1016c5e7c2c8b upstream.

    Recent Linux clients have started to send GETLAYOUT requests with
    minlength less than blocksize.

    Servers aren't really allowed to impose this kind of restriction on
    layouts; see RFC 5661 section 18.43.3 for details.

    This has been observed to cause indefinite hangs on fsx runs on some
    clients.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: J. Bruce Fields
    Signed-off-by: Greg Kroah-Hartman

    Christoph Hellwig