mbox series

[Xenial,0/9] Fix for CVE-2015-1350

Message ID cover.1512634012.git.khalid.elmously@canonical.com
Headers show
Series Fix for CVE-2015-1350 | expand

Message

Khalid Elmously Dec. 7, 2017, 8:37 a.m. UTC
The VFS subsystem in the Linux kernel 3.x provides an incomplete set of
requirements for setattr operations that underspecifies removing extended
privilege attributes, which allows local users to cause a denial of service
(capability stripping) via a failed invocation of a system call, as
demonstrated by using chown to remove a capability from the ping or
Wireshark dumpcap program.



Al Viro (1):
  ->getxattr(): pass dentry and inode as separate arguments

Andreas Gruenbacher (1):
  ceph: Get rid of d_find_alias in ceph_set_acl

Jan Kara (5):
  xfs: Propagate dentry down to inode_change_ok()
  ceph: Propagate dentry down to inode_change_ok()
  fuse: Propagate dentry down to inode_change_ok()
  fs: Give dentry to inode_change_ok() instead of inode
  fs: Avoid premature clearing of capabilities

Khalid Elmously (2):
  wrappers for ->i_mutex access
  xattr_handler: pass dentry and inode as separate arguments of ->get()

 Documentation/filesystems/porting                  | 10 ++-
 arch/powerpc/platforms/cell/spufs/file.c           |  4 +-
 arch/powerpc/platforms/cell/spufs/inode.c          | 12 +--
 arch/s390/hypfs/inode.c                            |  8 +-
 arch/x86/kernel/cpuid.c                            |  4 +-
 arch/x86/kernel/msr.c                              |  4 +-
 drivers/base/devtmpfs.c                            | 12 +--
 drivers/block/aoe/aoecmd.c                         |  4 +-
 drivers/block/drbd/drbd_debugfs.c                  |  4 +-
 drivers/char/mem.c                                 |  4 +-
 drivers/char/ps3flash.c                            |  4 +-
 drivers/infiniband/hw/qib/qib_fs.c                 | 12 +--
 drivers/mtd/ubi/cdev.c                             |  4 +-
 drivers/oprofile/oprofilefs.c                      | 16 ++--
 drivers/staging/lustre/lustre/llite/dir.c          |  4 +-
 drivers/staging/lustre/lustre/llite/file.c         | 16 ++--
 .../staging/lustre/lustre/llite/llite_internal.h   |  4 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c    |  6 +-
 drivers/staging/lustre/lustre/llite/llite_nfs.c    |  4 +-
 drivers/staging/lustre/lustre/llite/lloop.c        |  4 +-
 drivers/staging/lustre/lustre/llite/rw.c           |  4 +-
 drivers/staging/lustre/lustre/llite/rw26.c         |  4 +-
 drivers/staging/lustre/lustre/llite/vvp_io.c       |  4 +-
 drivers/staging/lustre/lustre/llite/vvp_page.c     | 10 +--
 drivers/staging/lustre/lustre/llite/xattr.c        |  6 +-
 drivers/staging/rdma/ipath/ipath_fs.c              |  8 +-
 drivers/usb/core/devices.c                         |  4 +-
 drivers/usb/core/devio.c                           |  4 +-
 drivers/usb/gadget/function/f_printer.c            |  4 +-
 drivers/usb/gadget/legacy/inode.c                  |  4 +-
 drivers/usb/gadget/udc/atmel_usba_udc.c            | 12 +--
 drivers/video/fbdev/core/fb_defio.c                |  4 +-
 fs/9p/acl.c                                        |  6 +-
 fs/9p/vfs_file.c                                   |  8 +-
 fs/9p/vfs_inode.c                                  |  2 +-
 fs/9p/vfs_inode_dotl.c                             |  2 +-
 fs/9p/xattr.c                                      |  4 +-
 fs/adfs/inode.c                                    |  2 +-
 fs/affs/file.c                                     |  8 +-
 fs/affs/inode.c                                    |  2 +-
 fs/afs/flock.c                                     |  4 +-
 fs/afs/write.c                                     |  4 +-
 fs/attr.c                                          | 37 ++++++---
 fs/aufs/cpup.c                                     | 22 +++---
 fs/aufs/dentry.c                                   |  8 +-
 fs/aufs/dir.c                                      |  4 +-
 fs/aufs/export.c                                   |  4 +-
 fs/aufs/f_op.c                                     | 16 ++--
 fs/aufs/hnotify.c                                  |  8 +-
 fs/aufs/i_op.c                                     | 18 ++---
 fs/aufs/i_op_add.c                                 |  4 +-
 fs/aufs/inode.h                                    |  6 +-
 fs/aufs/mvdown.c                                   |  8 +-
 fs/aufs/plink.c                                    |  4 +-
 fs/aufs/posix_acl.c                                |  4 +-
 fs/aufs/rdu.c                                      |  4 +-
 fs/aufs/super.c                                    |  8 +-
 fs/aufs/wbr_policy.c                               | 10 +--
 fs/aufs/whout.c                                    |  8 +-
 fs/aufs/xattr.c                                    | 14 ++--
 fs/aufs/xino.c                                     |  8 +-
 fs/bad_inode.c                                     |  4 +-
 fs/binfmt_misc.c                                   | 12 +--
 fs/block_dev.c                                     |  8 +-
 fs/btrfs/file.c                                    | 42 +++++-----
 fs/btrfs/inode.c                                   |  6 +-
 fs/btrfs/ioctl.c                                   | 38 ++++-----
 fs/btrfs/relocation.c                              |  4 +-
 fs/btrfs/scrub.c                                   |  4 +-
 fs/btrfs/xattr.c                                   |  8 +-
 fs/btrfs/xattr.h                                   |  4 +-
 fs/cachefiles/interface.c                          |  4 +-
 fs/cachefiles/namei.c                              | 40 +++++-----
 fs/ceph/acl.c                                      | 19 ++---
 fs/ceph/cache.c                                    |  4 +-
 fs/ceph/caps.c                                     |  4 +-
 fs/ceph/dir.c                                      |  4 +-
 fs/ceph/export.c                                   |  4 +-
 fs/ceph/file.c                                     | 18 ++---
 fs/ceph/inode.c                                    | 25 +++---
 fs/ceph/super.h                                    |  7 +-
 fs/ceph/xattr.c                                    | 36 ++++-----
 fs/cifs/cifsfs.c                                   |  4 +-
 fs/cifs/cifsfs.h                                   |  2 +-
 fs/cifs/file.c                                     | 12 +--
 fs/cifs/inode.c                                    |  4 +-
 fs/cifs/xattr.c                                    |  6 +-
 fs/coda/dir.c                                      |  4 +-
 fs/coda/file.c                                     |  8 +-
 fs/configfs/dir.c                                  | 54 ++++++-------
 fs/configfs/file.c                                 |  4 +-
 fs/configfs/inode.c                                |  4 +-
 fs/dax.c                                           |  6 +-
 fs/dcache.c                                        |  4 +-
 fs/debugfs/inode.c                                 | 22 +++---
 fs/devpts/inode.c                                  | 12 +--
 fs/direct-io.c                                     |  8 +-
 fs/ecryptfs/crypto.c                               |  5 +-
 fs/ecryptfs/ecryptfs_kernel.h                      |  4 +-
 fs/ecryptfs/inode.c                                | 53 +++++++------
 fs/ecryptfs/mmap.c                                 |  7 +-
 fs/efivarfs/file.c                                 |  8 +-
 fs/efivarfs/super.c                                |  4 +-
 fs/exec.c                                          |  4 +-
 fs/exofs/file.c                                    |  4 +-
 fs/exofs/inode.c                                   |  2 +-
 fs/exportfs/expfs.c                                | 12 +--
 fs/ext2/inode.c                                    |  2 +-
 fs/ext2/ioctl.c                                    | 12 +--
 fs/ext2/xattr_security.c                           |  6 +-
 fs/ext2/xattr_trusted.c                            |  6 +-
 fs/ext2/xattr_user.c                               |  8 +-
 fs/ext4/ext4.h                                     |  2 +-
 fs/ext4/extents.c                                  | 20 ++---
 fs/ext4/file.c                                     | 22 +++---
 fs/ext4/inode.c                                    | 14 ++--
 fs/ext4/ioctl.c                                    | 16 ++--
 fs/ext4/namei.c                                    |  4 +-
 fs/ext4/super.c                                    |  4 +-
 fs/ext4/xattr_security.c                           |  6 +-
 fs/ext4/xattr_trusted.c                            |  6 +-
 fs/ext4/xattr_user.c                               |  8 +-
 fs/f2fs/data.c                                     |  4 +-
 fs/f2fs/file.c                                     | 22 +++---
 fs/f2fs/xattr.c                                    | 14 ++--
 fs/fat/dir.c                                       |  4 +-
 fs/fat/file.c                                      | 10 +--
 fs/fuse/dir.c                                      | 22 +++---
 fs/fuse/file.c                                     | 34 ++++----
 fs/fuse/fuse_i.h                                   |  2 +-
 fs/gfs2/file.c                                     |  4 +-
 fs/gfs2/inode.c                                    | 15 ++--
 fs/gfs2/quota.c                                    |  8 +-
 fs/gfs2/xattr.c                                    |  6 +-
 fs/hfs/attr.c                                      |  5 +-
 fs/hfs/dir.c                                       |  4 +-
 fs/hfs/hfs_fs.h                                    |  4 +-
 fs/hfs/inode.c                                     | 10 +--
 fs/hfsplus/dir.c                                   |  4 +-
 fs/hfsplus/inode.c                                 | 10 +--
 fs/hfsplus/ioctl.c                                 |  4 +-
 fs/hfsplus/xattr.c                                 | 10 +--
 fs/hfsplus/xattr.h                                 |  2 +-
 fs/hfsplus/xattr_security.c                        |  6 +-
 fs/hfsplus/xattr_trusted.c                         |  6 +-
 fs/hfsplus/xattr_user.c                            |  6 +-
 fs/hostfs/hostfs_kern.c                            |  6 +-
 fs/hpfs/dir.c                                      |  6 +-
 fs/hpfs/inode.c                                    |  2 +-
 fs/hugetlbfs/inode.c                               | 14 ++--
 fs/inode.c                                         |  8 +-
 fs/ioctl.c                                         |  4 +-
 fs/jffs2/file.c                                    |  4 +-
 fs/jffs2/fs.c                                      |  2 +-
 fs/jffs2/security.c                                |  6 +-
 fs/jffs2/xattr_trusted.c                           |  6 +-
 fs/jffs2/xattr_user.c                              |  6 +-
 fs/jfs/file.c                                      |  8 +-
 fs/jfs/ioctl.c                                     |  6 +-
 fs/jfs/jfs_xattr.h                                 |  2 +-
 fs/jfs/super.c                                     |  6 +-
 fs/jfs/xattr.c                                     |  8 +-
 fs/kernfs/dir.c                                    |  4 +-
 fs/kernfs/inode.c                                  |  8 +-
 fs/kernfs/kernfs-internal.h                        |  4 +-
 fs/kernfs/mount.c                                  |  4 +-
 fs/libfs.c                                         | 16 ++--
 fs/locks.c                                         |  6 +-
 fs/logfs/file.c                                    | 10 +--
 fs/minix/file.c                                    |  2 +-
 fs/namei.c                                         | 70 ++++++++--------
 fs/namespace.c                                     | 10 +--
 fs/ncpfs/dir.c                                     |  8 +-
 fs/ncpfs/file.c                                    |  4 +-
 fs/ncpfs/inode.c                                   |  2 +-
 fs/nfs/dir.c                                       |  8 +-
 fs/nfs/direct.c                                    | 12 +--
 fs/nfs/file.c                                      |  4 +-
 fs/nfs/inode.c                                     |  8 +-
 fs/nfs/nfs42proc.c                                 |  8 +-
 fs/nfs/nfs4file.c                                  | 24 +++---
 fs/nfs/nfs4proc.c                                  | 12 +--
 fs/nfsd/nfs4proc.c                                 |  4 +-
 fs/nfsd/nfs4recover.c                              | 12 +--
 fs/nfsd/nfsfh.h                                    |  4 +-
 fs/nfsd/nfsproc.c                                  |  8 +-
 fs/nfsd/vfs.c                                      |  6 +-
 fs/nilfs2/inode.c                                  |  6 +-
 fs/nilfs2/ioctl.c                                  |  4 +-
 fs/ntfs/dir.c                                      |  4 +-
 fs/ntfs/file.c                                     |  8 +-
 fs/ntfs/inode.c                                    |  2 +-
 fs/ntfs/quota.c                                    |  6 +-
 fs/ntfs/super.c                                    | 12 +--
 fs/ocfs2/alloc.c                                   | 32 ++++----
 fs/ocfs2/aops.c                                    |  4 +-
 fs/ocfs2/dir.c                                     |  4 +-
 fs/ocfs2/dlmfs/dlmfs.c                             |  2 +-
 fs/ocfs2/file.c                                    | 14 ++--
 fs/ocfs2/inode.c                                   | 12 +--
 fs/ocfs2/ioctl.c                                   | 12 +--
 fs/ocfs2/journal.c                                 |  8 +-
 fs/ocfs2/localalloc.c                              | 16 ++--
 fs/ocfs2/move_extents.c                            | 16 ++--
 fs/ocfs2/namei.c                                   | 28 +++----
 fs/ocfs2/quota_global.c                            |  4 +-
 fs/ocfs2/refcounttree.c                            | 12 +--
 fs/ocfs2/resize.c                                  |  8 +-
 fs/ocfs2/suballoc.c                                | 12 +--
 fs/ocfs2/xattr.c                                   | 34 ++++----
 fs/omfs/file.c                                     |  2 +-
 fs/open.c                                          | 12 +--
 fs/overlayfs/copy_up.c                             |  4 +-
 fs/overlayfs/dir.c                                 | 16 ++--
 fs/overlayfs/inode.c                               | 10 +--
 fs/overlayfs/overlayfs.h                           | 12 +--
 fs/overlayfs/readdir.c                             | 20 ++---
 fs/overlayfs/super.c                               | 21 ++---
 fs/posix_acl.c                                     | 12 +--
 fs/proc/base.c                                     |  2 +-
 fs/proc/generic.c                                  |  2 +-
 fs/proc/kcore.c                                    |  4 +-
 fs/proc/proc_sysctl.c                              |  2 +-
 fs/proc/self.c                                     |  4 +-
 fs/proc/thread_self.c                              |  4 +-
 fs/pstore/inode.c                                  |  6 +-
 fs/quota/dquot.c                                   | 20 ++---
 fs/ramfs/file-nommu.c                              |  2 +-
 fs/read_write.c                                    |  4 +-
 fs/readdir.c                                       |  2 +-
 fs/reiserfs/dir.c                                  |  4 +-
 fs/reiserfs/file.c                                 |  4 +-
 fs/reiserfs/inode.c                                |  2 +-
 fs/reiserfs/ioctl.c                                |  2 +-
 fs/reiserfs/xattr.c                                | 64 +++++++--------
 fs/reiserfs/xattr_security.c                       |  9 +--
 fs/reiserfs/xattr_trusted.c                        |  9 +--
 fs/reiserfs/xattr_user.c                           |  9 +--
 fs/squashfs/xattr.c                                |  6 +-
 fs/sysv/file.c                                     |  2 +-
 fs/tracefs/inode.c                                 | 34 ++++----
 fs/ubifs/dir.c                                     | 18 ++---
 fs/ubifs/file.c                                    |  6 +-
 fs/ubifs/ubifs.h                                   |  4 +-
 fs/ubifs/xattr.c                                   | 10 +--
 fs/udf/file.c                                      | 12 +--
 fs/udf/inode.c                                     |  2 +-
 fs/ufs/inode.c                                     |  2 +-
 fs/utimes.c                                        |  6 +-
 fs/xattr.c                                         | 19 ++---
 fs/xfs/xfs_file.c                                  |  8 +-
 fs/xfs/xfs_inode.c                                 |  2 +-
 fs/xfs/xfs_ioctl.c                                 |  2 +-
 fs/xfs/xfs_iops.c                                  | 92 ++++++++++++++--------
 fs/xfs/xfs_iops.h                                  |  3 +-
 fs/xfs/xfs_pnfs.c                                  |  4 +-
 fs/xfs/xfs_xattr.c                                 |  6 +-
 include/linux/fs.h                                 |  5 +-
 include/linux/xattr.h                              |  5 +-
 ipc/mqueue.c                                       |  8 +-
 kernel/audit_fsnotify.c                            |  2 +-
 kernel/audit_watch.c                               |  2 +-
 kernel/events/core.c                               |  4 +-
 kernel/relay.c                                     |  4 +-
 kernel/sched/core.c                                |  4 +-
 mm/filemap.c                                       |  4 +-
 mm/shmem.c                                         | 16 ++--
 mm/swapfile.c                                      | 12 +--
 net/socket.c                                       |  2 +-
 net/sunrpc/cache.c                                 | 10 +--
 net/sunrpc/rpc_pipe.c                              | 60 +++++++-------
 security/commoncap.c                               |  6 +-
 security/inode.c                                   | 10 +--
 security/integrity/evm/evm_main.c                  |  2 +-
 security/integrity/ima/ima_main.c                  |  8 +-
 security/selinux/hooks.c                           |  9 ++-
 security/selinux/selinuxfs.c                       |  4 +-
 security/smack/smack_lsm.c                         |  4 +-
 spl/include/linux/file_compat.h                    |  4 +-
 zfs/config/kernel-xattr-handler.m4                 |  2 +-
 zfs/include/linux/xattr_compat.h                   |  4 +-
 zfs/module/zfs/zpl_inode.c                         |  2 +-
 282 files changed, 1352 insertions(+), 1304 deletions(-)

Comments

Thadeu Lima de Souza Cascardo Dec. 7, 2017, 11:56 a.m. UTC | #1
On Thu, Dec 07, 2017 at 03:37:48AM -0500, Khalid Elmously wrote:
> The VFS subsystem in the Linux kernel 3.x provides an incomplete set of
> requirements for setattr operations that underspecifies removing extended
> privilege attributes, which allows local users to cause a denial of service
> (capability stripping) via a failed invocation of a system call, as
> demonstrated by using chown to remove a capability from the ping or
> Wireshark dumpcap program.
> 
> 
> 
> Al Viro (1):
>   ->getxattr(): pass dentry and inode as separate arguments
> 
> Andreas Gruenbacher (1):
>   ceph: Get rid of d_find_alias in ceph_set_acl
> 
> Jan Kara (5):
>   xfs: Propagate dentry down to inode_change_ok()
>   ceph: Propagate dentry down to inode_change_ok()
>   fuse: Propagate dentry down to inode_change_ok()
>   fs: Give dentry to inode_change_ok() instead of inode
>   fs: Avoid premature clearing of capabilities
> 
> Khalid Elmously (2):
>   wrappers for ->i_mutex access
>   xattr_handler: pass dentry and inode as separate arguments of ->get()

The whole point of the fix is patch 9 ("fs: Avoid premature clearing of
capabilities"). I see how picking up patch 8 ("fs: Give dentry to
inode_change_ok() instead of inode") will make it a clean cherry-pick.
But that makes you bring all those changes to all filesystems and all
those other patches, then, are needed.

Why not just backport patch 9 and make the change to inode_change_ok? I
see how it uses the dentry instead of the inode, but why not just call
d_obtain_alias (with corresponding dput after dentry use)? That would
simplify the whole patchset. Though after some review of the other
patches, they seem to be fine aside from the usual style that we have
for backports (using -x from cherry-pick, instead of Upstream commit
style).

Regards.
Cascardo.
Thadeu Lima de Souza Cascardo Dec. 7, 2017, 12:06 p.m. UTC | #2
On Thu, Dec 07, 2017 at 03:37:48AM -0500, Khalid Elmously wrote:
> The VFS subsystem in the Linux kernel 3.x provides an incomplete set of
> requirements for setattr operations that underspecifies removing extended
> privilege attributes, which allows local users to cause a denial of service
> (capability stripping) via a failed invocation of a system call, as
> demonstrated by using chown to remove a capability from the ping or
> Wireshark dumpcap program.

One other thing: we stopped using bugs for CVEs. So, instead of a
BugLink, you should have a line as the one below all by itself. I
usually put it after the cherry-pick/backport line, right before my
SOB.

CVE-2015-1350
Khalid Elmously Dec. 11, 2017, 5:10 p.m. UTC | #3
Thanks for reviewing.

On 2017-12-07 09:56:55 , Thadeu Lima de Souza Cascardo wrote:
> On Thu, Dec 07, 2017 at 03:37:48AM -0500, Khalid Elmously wrote:
> > The VFS subsystem in the Linux kernel 3.x provides an incomplete set of
> > requirements for setattr operations that underspecifies removing extended
> > privilege attributes, which allows local users to cause a denial of service
> > (capability stripping) via a failed invocation of a system call, as
> > demonstrated by using chown to remove a capability from the ping or
> > Wireshark dumpcap program.
> > 
> > 
> > 
> > Al Viro (1):
> >   ->getxattr(): pass dentry and inode as separate arguments
> > 
> > Andreas Gruenbacher (1):
> >   ceph: Get rid of d_find_alias in ceph_set_acl
> > 
> > Jan Kara (5):
> >   xfs: Propagate dentry down to inode_change_ok()
> >   ceph: Propagate dentry down to inode_change_ok()
> >   fuse: Propagate dentry down to inode_change_ok()
> >   fs: Give dentry to inode_change_ok() instead of inode
> >   fs: Avoid premature clearing of capabilities
> > 
> > Khalid Elmously (2):
> >   wrappers for ->i_mutex access
> >   xattr_handler: pass dentry and inode as separate arguments of ->get()
> 
> The whole point of the fix is patch 9 ("fs: Avoid premature clearing of
> capabilities"). I see how picking up patch 8 ("fs: Give dentry to
> inode_change_ok() instead of inode") will make it a clean cherry-pick.
> But that makes you bring all those changes to all filesystems and all
> those other patches, then, are needed.
> 
> Why not just backport patch 9 and make the change to inode_change_ok? I
> see how it uses the dentry instead of the inode, but why not just call
> d_obtain_alias (with corresponding dput after dentry use)? That would
> simplify the whole patchset. 

The main reason is that I didn't want to come up with a solution myself since I don't really know if would be "correct" or not.

I tested the solution you propose here and it seems to work fine, though to be honest I still don't know if it's correct or not. 

I was surprised that your proposal works because: 
 a) Much of the refactoring that was done just before 030b533c4fd4d2ec3402363323de4bb2983c9cee (which is the patch we want) was done specifically for 030b533c4fd4d2ec3402363323de4bb2983c9cee, so I expected it to be necessary for a proper fix.
 b) My understanding was that there's a 1-to-many relationship between inodes and dentries (i.e hardlinks), thus calling security_inode_killpriv(d_obtain_alias(inode)) won't necessarily operate on the right dentry. However, since testing your suggestion I've realized that capabailities are set on the inode not the dentry so it doesn't even seem to matter which dentry is specified for killpriv().


The bottom line is that your proposal seems correct and testing shows that it fixes the problem, though I don't actually _know_ if it's the correct solution. I will go with your approach unless I receive objections.

Thanks for the feedback.



> Though after some review of the other
> patches, they seem to be fine aside from the usual style that we have
> for backports (using -x from cherry-pick, instead of Upstream commit
> style).


> 
> Regards.
> Cascardo.


Khaled