From: Luis Henriques <luis.henriques@canonical.com>
To: Ben Hutchings <ben@decadent.org.uk>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
akpm@linux-foundation.org, Filipe Manana <fdmanana@suse.com>
Subject: Re: [PATCH 3.2 38/52] Btrfs: fix race when listing an inode's xattrs
Date: Wed, 25 Nov 2015 23:11:00 +0000 [thread overview]
Message-ID: <20151125231100.GC21715@charon> (raw)
In-Reply-To: <lsq.1448404439.815293444@decadent.org.uk>
On Tue, Nov 24, 2015 at 10:33:59PM +0000, Ben Hutchings wrote:
> 3.2.74-rc1 review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Filipe Manana <fdmanana@suse.com>
>
> 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 <fdmanana@suse.com>
> [bwh: Backported to 3.2: s/found_key\.type/btrfs_key_type(\&found_key)/]
Actually, in my backport to 3.16 I decided to keep the usage of
'found_key.type' instead, as the usage of btrfs_key_type() has been
dropped with commit 962a298f3511 ("btrfs: kill the key type accessor
helpers").
Cheers,
--
Luís
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> ---
> fs/btrfs/xattr.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> --- a/fs/btrfs/xattr.c
> +++ b/fs/btrfs/xattr.c
> @@ -259,8 +259,10 @@ ssize_t btrfs_listxattr(struct dentry *d
> /* check to make sure this item is what we want */
> if (found_key.objectid != key.objectid)
> break;
> - if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
> + if (btrfs_key_type(&found_key) > BTRFS_XATTR_ITEM_KEY)
> break;
> + if (btrfs_key_type(&found_key) < BTRFS_XATTR_ITEM_KEY)
> + goto next;
>
> di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
> if (verify_dir_item(root, leaf, di))
>
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
WARNING: multiple messages have this Message-ID (diff)
From: Luis Henriques <luis.henriques@canonical.com>
To: Ben Hutchings <ben@decadent.org.uk>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
akpm@linux-foundation.org, Filipe Manana <fdmanana@suse.com>
Subject: Re: [PATCH 3.2 38/52] Btrfs: fix race when listing an inode's xattrs
Date: Wed, 25 Nov 2015 23:11:00 +0000 [thread overview]
Message-ID: <20151125231100.GC21715@charon> (raw)
In-Reply-To: <lsq.1448404439.815293444@decadent.org.uk>
On Tue, Nov 24, 2015 at 10:33:59PM +0000, Ben Hutchings wrote:
> 3.2.74-rc1 review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Filipe Manana <fdmanana@suse.com>
>
> 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 <fdmanana@suse.com>
> [bwh: Backported to 3.2: s/found_key\.type/btrfs_key_type(\&found_key)/]
Actually, in my backport to 3.16 I decided to keep the usage of
'found_key.type' instead, as the usage of btrfs_key_type() has been
dropped with commit 962a298f3511 ("btrfs: kill the key type accessor
helpers").
Cheers,
--
Lu�s
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> ---
> fs/btrfs/xattr.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> --- a/fs/btrfs/xattr.c
> +++ b/fs/btrfs/xattr.c
> @@ -259,8 +259,10 @@ ssize_t btrfs_listxattr(struct dentry *d
> /* check to make sure this item is what we want */
> if (found_key.objectid != key.objectid)
> break;
> - if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
> + if (btrfs_key_type(&found_key) > BTRFS_XATTR_ITEM_KEY)
> break;
> + if (btrfs_key_type(&found_key) < BTRFS_XATTR_ITEM_KEY)
> + goto next;
>
> di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
> if (verify_dir_item(root, leaf, di))
>
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-11-25 23:11 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-24 22:33 [PATCH 3.2 00/52] 3.2.74-rc1 review Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 37/52] scsi_sysfs: Fix queue_ramp_up_period return code Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 15/52] Btrfs: fix truncation of compressed and inlined extents Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 28/52] recordmcount: Fix endianness handling bug for nop_mcount Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 09/52] packet: fix match_fanout_group() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 48/52] irda: precedence bug in irlmp_seq_hb_idx() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 11/52] Btrfs: fix file corruption and data loss after cloning inline extents Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 34/52] Btrfs: fix race leading to incorrect item deletion when dropping extents Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 20/52] ACPI: Use correct IRQ when uninstalling ACPI interrupt handler Ben Hutchings
2015-11-25 2:37 ` Chen, Yu C
2015-11-25 2:37 ` Chen, Yu C
2015-11-24 22:33 ` [PATCH 3.2 30/52] ALSA: hda - Apply pin fixup for HP ProBook 6550b Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 50/52] ipmr: fix possible race resulting from improper usage of IP_INC_STATS_BH() in preemptible context Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 18/52] Bluetooth: ath3k: Add support of AR3012 0cf3:817b device Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 03/52] mac80211: fix driver RSSI event calculations Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 46/52] fs: make dumpable=2 require fully qualified path Ben Hutchings
2015-11-25 2:06 ` James Morris
2015-11-25 17:57 ` Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 44/52] FS-Cache: Handle a write to the page immediately beyond the EOF marker Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 36/52] perf: Fix inherited events vs. tracepoint filters Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 27/52] megaraid_sas : SMAP restriction--do not access user memory from IOCTL code Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 29/52] ipv6: fix tunnel error handling Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 31/52] firewire: ohci: fix JMicron JMB38x IT context discovery Ben Hutchings
2015-11-24 23:48 ` Stefan Richter
2015-11-24 22:33 ` [PATCH 3.2 07/52] mtd: mtdpart: fix add_mtd_partitions error path Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 32/52] scsi: restart list search after unlock in scsi_remove_target Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 33/52] x86/cpu: Call verify_cpu() after having entered long mode too Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 17/52] Bluetooth: ath3k: Add new AR3012 0930:021c id Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 01/52] PCI: Fix devfn for VPD access through function 0 Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 49/52] RDS-TCP: Recover correctly from pskb_pull()/pksb_trim() failure in rds_tcp_data_recv Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 35/52] Btrfs: fix race leading to BUG_ON when running delalloc for nodatacow Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 26/52] crypto: algif_hash - Only export and import on sockets with data Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 08/52] devres: fix a for loop bounds check Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 52/52] splice: sendfile() at once fails for big files Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 39/52] scsi: Fix a bdi reregistration race Ben Hutchings
2015-11-24 22:39 ` Bart Van Assche
2015-11-25 18:00 ` Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 41/52] KVM: svm: unconditionally intercept #DB Ben Hutchings
2015-11-25 11:31 ` Paolo Bonzini
2015-11-25 17:56 ` Ben Hutchings
2015-11-25 18:06 ` Paolo Bonzini
2015-11-24 22:33 ` [PATCH 3.2 23/52] megaraid_sas: Do not use PAGE_SIZE for max_sectors Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 06/52] mwifiex: fix mwifiex_rdeeprom_read() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 21/52] MIPS: atomic: Fix comment describing atomic64_add_unless's return value Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 16/52] ext4, jbd2: ensure entering into panic after recording an error in superblock Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 43/52] FS-Cache: Don't override netfs's primary_index if registering failed Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 05/52] wm831x_power: Use IRQF_ONESHOT to request threaded IRQs Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 25/52] mtd: blkdevs: fix potential deadlock + lockdep warnings Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 12/52] iommu/vt-d: Fix ATSR handling for Root-Complex integrated endpoints Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 22/52] ALSA: hda - Disable 64bit address for Creative HDA controllers Ben Hutchings
2015-11-25 23:05 ` Luis Henriques
2015-11-25 23:05 ` Luis Henriques
2015-11-26 0:34 ` Ben Hutchings
2015-11-26 10:30 ` Luis Henriques
2015-11-26 10:30 ` Luis Henriques
2015-11-24 22:33 ` [PATCH 3.2 47/52] fs: if a coredump already exists, unlink and recreate with O_EXCL Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 02/52] PCI: Use function 0 VPD for identical functions, regular VPD for others Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 24/52] can: Use correct type in sizeof() in nla_put() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 14/52] Btrfs: don't use ram_bytes for uncompressed inline items Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 40/52] net: fix a race in dst_release() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 45/52] binfmt_elf: Don't clobber passed executable's file header Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 38/52] Btrfs: fix race when listing an inode's xattrs Ben Hutchings
2015-11-25 23:11 ` Luis Henriques [this message]
2015-11-25 23:11 ` Luis Henriques
2015-11-26 0:39 ` Ben Hutchings
2015-11-26 9:39 ` Filipe Manana
2015-11-24 22:33 ` [PATCH 3.2 04/52] HID: core: Avoid uninitialized buffer access Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 19/52] staging: rtl8712: Add device ID for Sitecom WLA2100 Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 13/52] ARM: pxa: remove incorrect __init annotation on pxa27x_set_pwrmode Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 10/52] Btrfs: added helper btrfs_next_item() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 51/52] net: avoid NULL deref in inet_ctl_sock_destroy() Ben Hutchings
2015-11-24 22:33 ` [PATCH 3.2 42/52] FS-Cache: Increase reference of parent after registering, netfs success Ben Hutchings
2015-11-25 2:22 ` [PATCH 3.2 00/52] 3.2.74-rc1 review Guenter Roeck
2015-11-25 17:57 ` Ben Hutchings
2015-11-25 17:43 ` Ben Hutchings
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=20151125231100.GC21715@charon \
--to=luis.henriques@canonical.com \
--cc=akpm@linux-foundation.org \
--cc=ben@decadent.org.uk \
--cc=fdmanana@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.