Btrfs: make xattr replace operations atomic 29/76529/2
authorFilipe Manana <fdmanana@suse.com>
Sun, 9 Nov 2014 08:38:39 +0000 (08:38 +0000)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 3 Aug 2016 02:32:33 +0000 (19:32 -0700)
commitfe8173a61d6c5dd06e63281051a4ab184299fe03
treeb4144b3b88d31e51b09cca0e6aebed506ada00de
parent22ba78a338328de86f001c1c52b74b73331eb515
Btrfs: make xattr replace operations atomic

commit 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 upstream.

Replacing a xattr consists of doing a lookup for its existing value, delete
the current value from the respective leaf, release the search path and then
finally insert the new value. This leaves a time window where readers (getxattr,
listxattrs) won't see any value for the xattr. Xattrs are used to store ACLs,
so this has security implications.

This change also fixes 2 other existing issues which were:

*) Deleting the old xattr value without verifying first if the new xattr will
   fit in the existing leaf item (in case multiple xattrs are packed in the
   same item due to name hash collision);

*) Returning -EEXIST when the flag XATTR_CREATE is given and the xattr doesn't
   exist but we have have an existing item that packs muliple xattrs with
   the same name hash as the input xattr. In this case we should return ENOSPC.

A test case for xfstests follows soon.

Thanks to Alexandre Oliva for reporting the non-atomicity of the xattr replace
implementation.

Change-Id: I286d47858be086bb974cb4fa8eee5d32e8bee61d
Reported-by: Alexandre Oliva <oliva@gnu.org>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
[shengyong: backport to 3.10
 - FIX: CVE-2014-9710
 - adjust context
 - ASSERT() was added v3.12, so we do check with if statement
 - set the first parameter of btrfs_item_nr() as NULL, because it is not
   used, and is removed in v3.13
]
Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Junghoon Kim <jhoon20.kim@samsung.com>
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/dir-item.c
fs/btrfs/xattr.c