1
0
Fork 0
remarkable-linux/security
Eddie.Horng 5a842ecca2 cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias()
commit 355139a8db upstream.

The code in cap_inode_getsecurity(), introduced by commit 8db6c34f1d
("Introduce v3 namespaced file capabilities"), should use
d_find_any_alias() instead of d_find_alias() do handle unhashed dentry
correctly. This is needed, for example, if execveat() is called with an
open but unlinked overlayfs file, because overlayfs unhashes dentry on
unlink.
This is a regression of real life application, first reported at
https://www.spinics.net/lists/linux-unionfs/msg05363.html

Below reproducer and setup can reproduce the case.
  const char* exec="echo";
  const char *newargv[] = { "echo", "hello", NULL};
  const char *newenviron[] = { NULL };
  int fd, err;

  fd = open(exec, O_PATH);
  unlink(exec);
  err = syscall(322/*SYS_execveat*/, fd, "", newargv, newenviron,
AT_EMPTY_PATH);
  if(err<0)
    fprintf(stderr, "execveat: %s\n", strerror(errno));

gcc compile into ~/test/a.out
mount -t overlay -orw,lowerdir=/mnt/l,upperdir=/mnt/u,workdir=/mnt/w
none /mnt/m
cd /mnt/m
cp /bin/echo .
~/test/a.out

Expected result:
hello
Actually result:
execveat: Invalid argument
dmesg:
Invalid argument reading file caps for /dev/fd/3

The 2nd reproducer and setup emulates similar case but for
regular filesystem:
  const char* exec="echo";
  int fd, err;
  char buf[256];

  fd = open(exec, O_RDONLY);
  unlink(exec);
  err = fgetxattr(fd, "security.capability", buf, 256);
  if(err<0)
    fprintf(stderr, "fgetxattr: %s\n", strerror(errno));

gcc compile into ~/test_fgetxattr

cd /tmp
cp /bin/echo .
~/test_fgetxattr

Result:
fgetxattr: Invalid argument

On regular filesystem, for example, ext4 read xattr from
disk and return to execveat(), will not trigger this issue, however,
the overlay attr handler pass real dentry to vfs_getxattr() will.
This reproducer calls fgetxattr() with an unlinked fd, involkes
vfs_getxattr() then reproduced the case that d_find_alias() in
cap_inode_getsecurity() can't find the unlinked dentry.

Suggested-by: Amir Goldstein <amir73il@gmail.com>
Acked-by: Amir Goldstein <amir73il@gmail.com>
Acked-by: Serge E. Hallyn <serge@hallyn.com>
Fixes: 8db6c34f1d ("Introduce v3 namespaced file capabilities")
Cc: <stable@vger.kernel.org> # v4.14
Signed-off-by: Eddie Horng <eddie.horng@mediatek.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-09-09 19:56:01 +02:00
..
apparmor apparmor: fix resource audit messages when auditing peer 2018-04-19 08:56:18 +02:00
integrity ima: based on policy verify firmware signatures (pre-allocated buffer) 2018-08-03 07:50:31 +02:00
keys KEYS: reject NULL restriction string when type is specified 2017-12-14 09:52:53 +01:00
loadpin security: mark LSM hooks as __ro_after_init 2017-03-06 11:00:15 +11:00
selinux selinux: KASAN: slab-out-of-bounds in xattr_getsecurity 2018-06-05 11:41:56 +02:00
smack Smack: Mark inode instant in smack_task_to_inode 2018-08-24 13:09:04 +02:00
tomoyo License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
yama doc: ReSTify Yama.txt 2017-05-18 10:33:04 -06:00
Kconfig /dev/mem: Add bounce buffer for copy-out 2018-03-24 11:01:24 +01:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
commoncap.c cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias() 2018-09-09 19:56:01 +02:00
device_cgroup.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
inode.c securityfs: add the ability to support symlinks 2017-06-08 12:51:43 -07:00
lsm_audit.c lsm_audit: update my email address 2017-08-17 15:33:39 -04:00
min_addr.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
security.c selinux/stable-4.14 PR 20170831 2017-09-12 13:21:00 -07:00