From c6993e4ac002c92bc75379212e9179c36d4bf7ee Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 4 Sep 2012 13:32:13 -0700 Subject: security: allow Yama to be unconditionally stacked Unconditionally call Yama when CONFIG_SECURITY_YAMA_STACKED is selected, no matter what LSM module is primary. Ubuntu and Chrome OS already carry patches to do this, and Fedora has voiced interest in doing this as well. Instead of having multiple distributions (or LSM authors) carrying these patches, just allow Yama to be called unconditionally when selected by the new CONFIG. Signed-off-by: Kees Cook Acked-by: Serge E. Hallyn Acked-by: Eric Paris Acked-by: John Johansen Signed-off-by: James Morris --- include/linux/security.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'include/linux/security.h') diff --git a/include/linux/security.h b/include/linux/security.h index 3dea6a9d568f..01ef030b9409 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -3021,5 +3021,36 @@ static inline void free_secdata(void *secdata) { } #endif /* CONFIG_SECURITY */ +#ifdef CONFIG_SECURITY_YAMA +extern int yama_ptrace_access_check(struct task_struct *child, + unsigned int mode); +extern int yama_ptrace_traceme(struct task_struct *parent); +extern void yama_task_free(struct task_struct *task); +extern int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5); +#else +static inline int yama_ptrace_access_check(struct task_struct *child, + unsigned int mode) +{ + return 0; +} + +static inline int yama_ptrace_traceme(struct task_struct *parent) +{ + return 0; +} + +static inline void yama_task_free(struct task_struct *task) +{ +} + +static inline int yama_task_prctl(int option, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5) +{ + return -ENOSYS; +} +#endif /* CONFIG_SECURITY_YAMA */ + #endif /* ! __LINUX_SECURITY_H */ -- cgit v1.2.3 From d2b31ca644fdc8704de3367a6a56a5c958c77f53 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 1 Jun 2012 16:14:19 -0600 Subject: userns: Teach security_path_chown to take kuids and kgids Don't make the security modules deal with raw user space uid and gids instead pass in a kuid_t and a kgid_t so that security modules only have to deal with internal kernel uids and gids. Cc: Al Viro Cc: James Morris Cc: John Johansen Cc: Kentaro Takeda Cc: Tetsuo Handa Acked-by: Serge Hallyn Signed-off-by: Eric W. Biederman --- fs/open.c | 2 +- include/linux/security.h | 6 +++--- security/apparmor/lsm.c | 2 +- security/capability.c | 2 +- security/security.c | 2 +- security/tomoyo/tomoyo.c | 12 +++++++----- 6 files changed, 14 insertions(+), 12 deletions(-) (limited to 'include/linux/security.h') diff --git a/fs/open.c b/fs/open.c index f3d96e7e7b19..2b2573980d0f 100644 --- a/fs/open.c +++ b/fs/open.c @@ -534,7 +534,7 @@ static int chown_common(struct path *path, uid_t user, gid_t group) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; mutex_lock(&inode->i_mutex); - error = security_path_chown(path, user, group); + error = security_path_chown(path, uid, gid); if (!error) error = notify_change(path->dentry, &newattrs); mutex_unlock(&inode->i_mutex); diff --git a/include/linux/security.h b/include/linux/security.h index 4e5a73cdbbef..ebb92cb1fa28 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1437,7 +1437,7 @@ struct security_operations { int (*path_rename) (struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); int (*path_chmod) (struct path *path, umode_t mode); - int (*path_chown) (struct path *path, uid_t uid, gid_t gid); + int (*path_chown) (struct path *path, kuid_t uid, kgid_t gid); int (*path_chroot) (struct path *path); #endif @@ -2832,7 +2832,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); int security_path_chmod(struct path *path, umode_t mode); -int security_path_chown(struct path *path, uid_t uid, gid_t gid); +int security_path_chown(struct path *path, kuid_t uid, kgid_t gid); int security_path_chroot(struct path *path); #else /* CONFIG_SECURITY_PATH */ static inline int security_path_unlink(struct path *dir, struct dentry *dentry) @@ -2888,7 +2888,7 @@ static inline int security_path_chmod(struct path *path, umode_t mode) return 0; } -static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid) +static inline int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { return 0; } diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8ea39aabe948..8c2a7f6b35e2 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -352,7 +352,7 @@ static int apparmor_path_chmod(struct path *path, umode_t mode) return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD); } -static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid) +static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid) { struct path_cond cond = { path->dentry->d_inode->i_uid, path->dentry->d_inode->i_mode diff --git a/security/capability.c b/security/capability.c index 61095df8b89a..a40aac677c72 100644 --- a/security/capability.c +++ b/security/capability.c @@ -284,7 +284,7 @@ static int cap_path_chmod(struct path *path, umode_t mode) return 0; } -static int cap_path_chown(struct path *path, uid_t uid, gid_t gid) +static int cap_path_chown(struct path *path, kuid_t uid, kgid_t gid) { return 0; } diff --git a/security/security.c b/security/security.c index 860aeb349cb3..f9a2f2ef2454 100644 --- a/security/security.c +++ b/security/security.c @@ -434,7 +434,7 @@ int security_path_chmod(struct path *path, umode_t mode) return security_ops->path_chmod(path, mode); } -int security_path_chown(struct path *path, uid_t uid, gid_t gid) +int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { if (unlikely(IS_PRIVATE(path->dentry->d_inode))) return 0; diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index c2d04a50f76a..d88eb3a046ed 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -373,13 +373,15 @@ static int tomoyo_path_chmod(struct path *path, umode_t mode) * * Returns 0 on success, negative value otherwise. */ -static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) +static int tomoyo_path_chown(struct path *path, kuid_t uid, kgid_t gid) { int error = 0; - if (uid != (uid_t) -1) - error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid); - if (!error && gid != (gid_t) -1) - error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid); + if (uid_valid(uid)) + error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, + from_kuid(&init_user_ns, uid)); + if (!error && gid_valid(gid)) + error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, + from_kgid(&init_user_ns, gid)); return error; } -- cgit v1.2.3 From 808d4e3cfdcc52b19276175464f6dbca4df13b09 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 11 Oct 2012 11:42:01 -0400 Subject: consitify do_mount() arguments Signed-off-by: Al Viro --- fs/namespace.c | 12 ++++++------ include/linux/fs.h | 2 +- include/linux/security.h | 12 ++++++------ security/capability.c | 4 ++-- security/security.c | 4 ++-- security/selinux/hooks.c | 4 ++-- security/smack/smack_lsm.c | 4 ++-- security/tomoyo/common.h | 2 +- security/tomoyo/mount.c | 5 +++-- security/tomoyo/tomoyo.c | 4 ++-- 10 files changed, 27 insertions(+), 26 deletions(-) (limited to 'include/linux/security.h') diff --git a/fs/namespace.c b/fs/namespace.c index 7bdf7907413f..fc33207e28ad 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1640,7 +1640,7 @@ static int do_change_type(struct path *path, int flag) /* * do loopback mount. */ -static int do_loopback(struct path *path, char *old_name, +static int do_loopback(struct path *path, const char *old_name, int recurse) { LIST_HEAD(umount_list); @@ -1764,7 +1764,7 @@ static inline int tree_contains_unbindable(struct mount *mnt) return 0; } -static int do_move_mount(struct path *path, char *old_name) +static int do_move_mount(struct path *path, const char *old_name) { struct path old_path, parent_path; struct mount *p; @@ -1917,8 +1917,8 @@ unlock: * create a new mount for userspace and request it to be added into the * namespace's tree */ -static int do_new_mount(struct path *path, char *type, int flags, - int mnt_flags, char *name, void *data) +static int do_new_mount(struct path *path, const char *type, int flags, + int mnt_flags, const char *name, void *data) { struct vfsmount *mnt; int err; @@ -2191,8 +2191,8 @@ int copy_mount_string(const void __user *data, char **where) * Therefore, if this magic number is present, it carries no information * and must be discarded. */ -long do_mount(char *dev_name, char *dir_name, char *type_page, - unsigned long flags, void *data_page) +long do_mount(const char *dev_name, const char *dir_name, + const char *type_page, unsigned long flags, void *data_page) { struct path path; int retval = 0; diff --git a/include/linux/fs.h b/include/linux/fs.h index ec911aeea968..9baf8270f9d1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2075,7 +2075,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data); extern void kern_unmount(struct vfsmount *mnt); extern int may_umount_tree(struct vfsmount *); extern int may_umount(struct vfsmount *); -extern long do_mount(char *, char *, char *, unsigned long, void *); +extern long do_mount(const char *, const char *, const char *, unsigned long, void *); extern struct vfsmount *collect_mounts(struct path *); extern void drop_collected_mounts(struct vfsmount *); extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, diff --git a/include/linux/security.h b/include/linux/security.h index 5b50c4e1a7c2..05e88bdcf7d9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1411,8 +1411,8 @@ struct security_operations { int (*sb_kern_mount) (struct super_block *sb, int flags, void *data); int (*sb_show_options) (struct seq_file *m, struct super_block *sb); int (*sb_statfs) (struct dentry *dentry); - int (*sb_mount) (char *dev_name, struct path *path, - char *type, unsigned long flags, void *data); + int (*sb_mount) (const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data); int (*sb_umount) (struct vfsmount *mnt, int flags); int (*sb_pivotroot) (struct path *old_path, struct path *new_path); @@ -1694,8 +1694,8 @@ int security_sb_remount(struct super_block *sb, void *data); int security_sb_kern_mount(struct super_block *sb, int flags, void *data); int security_sb_show_options(struct seq_file *m, struct super_block *sb); int security_sb_statfs(struct dentry *dentry); -int security_sb_mount(char *dev_name, struct path *path, - char *type, unsigned long flags, void *data); +int security_sb_mount(const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data); int security_sb_umount(struct vfsmount *mnt, int flags); int security_sb_pivotroot(struct path *old_path, struct path *new_path); int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); @@ -1964,8 +1964,8 @@ static inline int security_sb_statfs(struct dentry *dentry) return 0; } -static inline int security_sb_mount(char *dev_name, struct path *path, - char *type, unsigned long flags, +static inline int security_sb_mount(const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data) { return 0; diff --git a/security/capability.c b/security/capability.c index a40aac677c72..b14a30c234b8 100644 --- a/security/capability.c +++ b/security/capability.c @@ -74,8 +74,8 @@ static int cap_sb_statfs(struct dentry *dentry) return 0; } -static int cap_sb_mount(char *dev_name, struct path *path, char *type, - unsigned long flags, void *data) +static int cap_sb_mount(const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data) { return 0; } diff --git a/security/security.c b/security/security.c index 3724029d0f6d..8dcd4ae10a5f 100644 --- a/security/security.c +++ b/security/security.c @@ -276,8 +276,8 @@ int security_sb_statfs(struct dentry *dentry) return security_ops->sb_statfs(dentry); } -int security_sb_mount(char *dev_name, struct path *path, - char *type, unsigned long flags, void *data) +int security_sb_mount(const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data) { return security_ops->sb_mount(dev_name, path, type, flags, data); } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 651d8456611a..24ab4148547c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2452,9 +2452,9 @@ static int selinux_sb_statfs(struct dentry *dentry) return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } -static int selinux_mount(char *dev_name, +static int selinux_mount(const char *dev_name, struct path *path, - char *type, + const char *type, unsigned long flags, void *data) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 2874c7316783..38be92ce901e 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -408,8 +408,8 @@ static int smack_sb_statfs(struct dentry *dentry) * Returns 0 if current can write the floor of the filesystem * being mounted on, an error code otherwise. */ -static int smack_sb_mount(char *dev_name, struct path *path, - char *type, unsigned long flags, void *data) +static int smack_sb_mount(const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data) { struct superblock_smack *sbp = path->dentry->d_sb->s_security; struct smk_audit_info ad; diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index af010b62d544..d4f166bc3508 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -970,7 +970,7 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r, const u8 index); int tomoyo_mkdev_perm(const u8 operation, struct path *path, const unsigned int mode, unsigned int dev); -int tomoyo_mount_permission(char *dev_name, struct path *path, +int tomoyo_mount_permission(const char *dev_name, struct path *path, const char *type, unsigned long flags, void *data_page); int tomoyo_open_control(const u8 type, struct file *file); diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c index fe00cdfd0267..390c646013cb 100644 --- a/security/tomoyo/mount.c +++ b/security/tomoyo/mount.c @@ -71,7 +71,8 @@ static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, * * Caller holds tomoyo_read_lock(). */ -static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, +static int tomoyo_mount_acl(struct tomoyo_request_info *r, + const char *dev_name, struct path *dir, const char *type, unsigned long flags) { @@ -183,7 +184,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, * * Returns 0 on success, negative value otherwise. */ -int tomoyo_mount_permission(char *dev_name, struct path *path, +int tomoyo_mount_permission(const char *dev_name, struct path *path, const char *type, unsigned long flags, void *data_page) { diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index d88eb3a046ed..a2ee362546ab 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -408,8 +408,8 @@ static int tomoyo_path_chroot(struct path *path) * * Returns 0 on success, negative value otherwise. */ -static int tomoyo_sb_mount(char *dev_name, struct path *path, - char *type, unsigned long flags, void *data) +static int tomoyo_sb_mount(const char *dev_name, struct path *path, + const char *type, unsigned long flags, void *data) { return tomoyo_mount_permission(dev_name, path, type, flags, data); } -- cgit v1.2.3