mirror of https://gitee.com/openkylin/linux.git
ipc: use private shmem or hugetlbfs inodes for shm segments.
The shm implementation internally uses shmem or hugetlbfs inodes for shm segments. As these inodes are never directly exposed to userspace and only accessed through the shm operations which are already hooked by security modules, mark the inodes with the S_PRIVATE flag so that inode security initialization and permission checking is skipped. This was motivated by the following lockdep warning: ====================================================== [ INFO: possible circular locking dependency detected ] 4.2.0-0.rc3.git0.1.fc24.x86_64+debug #1 Tainted: G W ------------------------------------------------------- httpd/1597 is trying to acquire lock: (&ids->rwsem){+++++.}, at: shm_close+0x34/0x130 but task is already holding lock: (&mm->mmap_sem){++++++}, at: SyS_shmdt+0x4b/0x180 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (&mm->mmap_sem){++++++}: lock_acquire+0xc7/0x270 __might_fault+0x7a/0xa0 filldir+0x9e/0x130 xfs_dir2_block_getdents.isra.12+0x198/0x1c0 [xfs] xfs_readdir+0x1b4/0x330 [xfs] xfs_file_readdir+0x2b/0x30 [xfs] iterate_dir+0x97/0x130 SyS_getdents+0x91/0x120 entry_SYSCALL_64_fastpath+0x12/0x76 -> #2 (&xfs_dir_ilock_class){++++.+}: lock_acquire+0xc7/0x270 down_read_nested+0x57/0xa0 xfs_ilock+0x167/0x350 [xfs] xfs_ilock_attr_map_shared+0x38/0x50 [xfs] xfs_attr_get+0xbd/0x190 [xfs] xfs_xattr_get+0x3d/0x70 [xfs] generic_getxattr+0x4f/0x70 inode_doinit_with_dentry+0x162/0x670 sb_finish_set_opts+0xd9/0x230 selinux_set_mnt_opts+0x35c/0x660 superblock_doinit+0x77/0xf0 delayed_superblock_init+0x10/0x20 iterate_supers+0xb3/0x110 selinux_complete_init+0x2f/0x40 security_load_policy+0x103/0x600 sel_write_load+0xc1/0x750 __vfs_write+0x37/0x100 vfs_write+0xa9/0x1a0 SyS_write+0x58/0xd0 entry_SYSCALL_64_fastpath+0x12/0x76 ... Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Reported-by: Morten Stevens <mstevens@fedoraproject.org> Acked-by: Hugh Dickins <hughd@google.com> Acked-by: Paul Moore <paul@paul-moore.com> Cc: Manfred Spraul <manfred@colorfullife.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Eric Paris <eparis@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
e298ff75f1
commit
e1832f2923
|
@ -1010,6 +1010,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
|
|||
inode = hugetlbfs_get_inode(sb, NULL, S_IFREG | S_IRWXUGO, 0);
|
||||
if (!inode)
|
||||
goto out_dentry;
|
||||
if (creat_flags == HUGETLB_SHMFS_INODE)
|
||||
inode->i_flags |= S_PRIVATE;
|
||||
|
||||
file = ERR_PTR(-ENOMEM);
|
||||
if (hugetlb_reserve_pages(inode, 0,
|
||||
|
|
|
@ -545,7 +545,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
|
|||
if ((shmflg & SHM_NORESERVE) &&
|
||||
sysctl_overcommit_memory != OVERCOMMIT_NEVER)
|
||||
acctflag = VM_NORESERVE;
|
||||
file = shmem_file_setup(name, size, acctflag);
|
||||
file = shmem_kernel_file_setup(name, size, acctflag);
|
||||
}
|
||||
error = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
|
|
|
@ -3363,8 +3363,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
|
|||
* shmem_kernel_file_setup - get an unlinked file living in tmpfs which must be
|
||||
* kernel internal. There will be NO LSM permission checks against the
|
||||
* underlying inode. So users of this interface must do LSM checks at a
|
||||
* higher layer. The one user is the big_key implementation. LSM checks
|
||||
* are provided at the key level rather than the inode level.
|
||||
* higher layer. The users are the big_key and shm implementations. LSM
|
||||
* checks are provided at the key or shm level rather than the inode.
|
||||
* @name: name for dentry (to be seen in /proc/<pid>/maps
|
||||
* @size: size to be set for the file
|
||||
* @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
|
||||
|
|
Loading…
Reference in New Issue