From c9180a57a9ab2d5525faf8815a332364ee9e89b7 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 30 Nov 2007 13:00:35 -0500 Subject: Security: add get, set, and cloning of superblock security information Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and security_clont_sb_mnt_opts to the LSM and to SELinux. This will allow filesystems to directly own and control all of their mount options if they so choose. This interface deals only with option identifiers and strings so it should generic enough for any LSM which may come in the future. Filesystems which pass text mount data around in the kernel (almost all of them) need not currently make use of this interface when dealing with SELinux since it will still parse those strings as it always has. I assume future LSM's would do the same. NFS is the primary FS which does not use text mount data and thus must make use of this interface. An LSM would need to implement these functions only if they had mount time options, such as selinux has context= or fscontext=. If the LSM has no mount time options they could simply not implement and let the dummy ops take care of things. An LSM other than SELinux would need to define new option numbers in security.h and any FS which decides to own there own security options would need to be patched to use this new interface for every possible LSM. This is because it was stated to me very clearly that LSM's should not attempt to understand FS mount data and the burdon to understand security should be in the FS which owns the options. Signed-off-by: Eric Paris Acked-by: Stephen D. Smalley Signed-off-by: James Morris --- security/security.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'security/security.c') diff --git a/security/security.c b/security/security.c index 0e1f1f12436..b13b54f0af8 100644 --- a/security/security.c +++ b/security/security.c @@ -308,6 +308,26 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_ security_ops->sb_post_pivotroot(old_nd, new_nd); } +int security_sb_get_mnt_opts(const struct super_block *sb, + char ***mount_options, + int **flags, int *num_opts) +{ + return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts); +} + +int security_sb_set_mnt_opts(struct super_block *sb, + char **mount_options, + int *flags, int num_opts) +{ + return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts); +} + +void security_sb_clone_mnt_opts(const struct super_block *oldsb, + struct super_block *newsb) +{ + security_ops->sb_clone_mnt_opts(oldsb, newsb); +} + int security_inode_alloc(struct inode *inode) { inode->i_security = NULL; -- cgit v1.2.3-70-g09d2 From bced95283e9434611cbad8f2ff903cd396eaea72 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 29 Dec 2007 16:20:25 -0800 Subject: security: remove security_sb_post_mountroot hook The security_sb_post_mountroot() hook is long-since obsolete, and is fundamentally broken: it is never invoked if someone uses initramfs. This is particularly damaging, because the existence of this hook has been used as motivation for not using initramfs. Stephen Smalley confirmed on 2007-07-19 that this hook was originally used by SELinux but can now be safely removed: http://marc.info/?l=linux-kernel&m=118485683612916&w=2 Cc: Stephen Smalley Cc: James Morris Cc: Eric Paris Cc: Chris Wright Signed-off-by: H. Peter Anvin Signed-off-by: James Morris --- include/linux/security.h | 8 -------- init/do_mounts.c | 1 - security/dummy.c | 6 ------ security/security.c | 5 ----- 4 files changed, 20 deletions(-) (limited to 'security/security.c') diff --git a/include/linux/security.h b/include/linux/security.h index cbd970a735f..2e2c63faead 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -249,9 +249,6 @@ struct request_sock; * @mnt contains the mounted file system. * @flags contains the new filesystem flags. * @data contains the filesystem-specific data. - * @sb_post_mountroot: - * Update the security module's state when the root filesystem is mounted. - * This hook is only called if the mount was successful. * @sb_post_addmount: * Update the security module's state when a filesystem is mounted. * This hook is called any time a mount is successfully grafetd to @@ -1257,7 +1254,6 @@ struct security_operations { void (*sb_umount_busy) (struct vfsmount * mnt); void (*sb_post_remount) (struct vfsmount * mnt, unsigned long flags, void *data); - void (*sb_post_mountroot) (void); void (*sb_post_addmount) (struct vfsmount * mnt, struct nameidata * mountpoint_nd); int (*sb_pivotroot) (struct nameidata * old_nd, @@ -1524,7 +1520,6 @@ int security_sb_umount(struct vfsmount *mnt, int flags); void security_sb_umount_close(struct vfsmount *mnt); void security_sb_umount_busy(struct vfsmount *mnt); void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data); -void security_sb_post_mountroot(void); void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); @@ -1813,9 +1808,6 @@ static inline void security_sb_post_remount (struct vfsmount *mnt, unsigned long flags, void *data) { } -static inline void security_sb_post_mountroot (void) -{ } - static inline void security_sb_post_addmount (struct vfsmount *mnt, struct nameidata *mountpoint_nd) { } diff --git a/init/do_mounts.c b/init/do_mounts.c index 4efa1e5385e..31b2185ce30 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -470,6 +470,5 @@ void __init prepare_namespace(void) out: sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); - security_sb_post_mountroot(); } diff --git a/security/dummy.c b/security/dummy.c index a3b29d0d00e..8e34e03415f 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -225,11 +225,6 @@ static void dummy_sb_post_remount (struct vfsmount *mnt, unsigned long flags, } -static void dummy_sb_post_mountroot (void) -{ - return; -} - static void dummy_sb_post_addmount (struct vfsmount *mnt, struct nameidata *nd) { return; @@ -1017,7 +1012,6 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, sb_umount_close); set_to_dummy_if_null(ops, sb_umount_busy); set_to_dummy_if_null(ops, sb_post_remount); - set_to_dummy_if_null(ops, sb_post_mountroot); set_to_dummy_if_null(ops, sb_post_addmount); set_to_dummy_if_null(ops, sb_pivotroot); set_to_dummy_if_null(ops, sb_post_pivotroot); diff --git a/security/security.c b/security/security.c index b13b54f0af8..5068808343d 100644 --- a/security/security.c +++ b/security/security.c @@ -288,11 +288,6 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d security_ops->sb_post_remount(mnt, flags, data); } -void security_sb_post_mountroot(void) -{ - security_ops->sb_post_mountroot(); -} - void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd) { security_ops->sb_post_addmount(mnt, mountpoint_nd); -- cgit v1.2.3-70-g09d2 From 63cb34492351078479b2d4bae6a881806a396286 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 15 Jan 2008 23:47:35 +0000 Subject: security: add a secctx_to_secid() hook Add a secctx_to_secid() LSM hook to go along with the existing secid_to_secctx() LSM hook. This patch also includes the SELinux implementation for this hook. Signed-off-by: Paul Moore Acked-by: Stephen Smalley Signed-off-by: James Morris --- include/linux/security.h | 13 +++++++++++++ security/dummy.c | 6 ++++++ security/security.c | 6 ++++++ security/selinux/hooks.c | 6 ++++++ 4 files changed, 31 insertions(+) (limited to 'security/security.c') diff --git a/include/linux/security.h b/include/linux/security.h index 2e2c63faead..e4a91cb1b18 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1202,6 +1202,10 @@ struct request_sock; * Convert secid to security context. * @secid contains the security ID. * @secdata contains the pointer that stores the converted security context. + * @secctx_to_secid: + * Convert security context to secid. + * @secid contains the pointer to the generated security ID. + * @secdata contains the security context. * * @release_secctx: * Release the security context. @@ -1396,6 +1400,7 @@ struct security_operations { int (*getprocattr)(struct task_struct *p, char *name, char **value); int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); + int (*secctx_to_secid)(char *secdata, u32 seclen, u32 *secid); void (*release_secctx)(char *secdata, u32 seclen); #ifdef CONFIG_SECURITY_NETWORK @@ -1634,6 +1639,7 @@ int security_setprocattr(struct task_struct *p, char *name, void *value, size_t int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_netlink_recv(struct sk_buff *skb, int cap); int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); +int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid); void security_release_secctx(char *secdata, u32 seclen); #else /* CONFIG_SECURITY */ @@ -2308,6 +2314,13 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle return -EOPNOTSUPP; } +static inline int security_secctx_to_secid(char *secdata, + u32 seclen, + u32 *secid) +{ + return -EOPNOTSUPP; +} + static inline void security_release_secctx(char *secdata, u32 seclen) { } diff --git a/security/dummy.c b/security/dummy.c index 8e34e03415f..48d4b0a5273 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -946,6 +946,11 @@ static int dummy_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) return -EOPNOTSUPP; } +static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) +{ + return -EOPNOTSUPP; +} + static void dummy_release_secctx(char *secdata, u32 seclen) { } @@ -1106,6 +1111,7 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, getprocattr); set_to_dummy_if_null(ops, setprocattr); set_to_dummy_if_null(ops, secid_to_secctx); + set_to_dummy_if_null(ops, secctx_to_secid); set_to_dummy_if_null(ops, release_secctx); #ifdef CONFIG_SECURITY_NETWORK set_to_dummy_if_null(ops, unix_stream_connect); diff --git a/security/security.c b/security/security.c index 5068808343d..ca475ca206e 100644 --- a/security/security.c +++ b/security/security.c @@ -831,6 +831,12 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) } EXPORT_SYMBOL(security_secid_to_secctx); +int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) +{ + return security_ops->secctx_to_secid(secdata, seclen, secid); +} +EXPORT_SYMBOL(security_secctx_to_secid); + void security_release_secctx(char *secdata, u32 seclen) { return security_ops->release_secctx(secdata, seclen); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 233c8b97462..0396354fff9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4947,6 +4947,11 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) return security_sid_to_context(secid, secdata, seclen); } +static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) +{ + return security_context_to_sid(secdata, seclen, secid); +} + static void selinux_release_secctx(char *secdata, u32 seclen) { kfree(secdata); @@ -5138,6 +5143,7 @@ static struct security_operations selinux_ops = { .setprocattr = selinux_setprocattr, .secid_to_secctx = selinux_secid_to_secctx, + .secctx_to_secid = selinux_secctx_to_secid, .release_secctx = selinux_release_secctx, .unix_stream_connect = selinux_socket_unix_stream_connect, -- cgit v1.2.3-70-g09d2