2003-06-02 09:38:42

by Chris Wright

[permalink] [raw]
Subject: [BK PATCH][LSM] Early init for security modules and various cleanups

Hi Linus,

Here is a batch of LSM updates. This patchset allows for statically
linked security modules to be initialized earlier in the boot sequence
to give consistent security labels to the earliest dynamically created
objects such as filesystems and kernel threads. This patch was acked
by nearly all the arch maintainers, then subsequently updated based on
Sam Ravnborg's feedback. The current version was floated passed arch
maintainers without much response, but it did at least get one ack
from DaveM.

Additional changes are removing two unused hooks, fixing a bug that Jakub
Jelinek reported in setfs[ug]id, and fixing some capability checks in
oom killer.

Please consider pulling from: bk://lsm.bkbits.net/linus-2.5

This will update these files:

arch/alpha/vmlinux.lds.S | 3 +
arch/arm/vmlinux-armo.lds.in | 1
arch/arm/vmlinux-armv.lds.in | 1
arch/cris/vmlinux.lds.S | 4 +-
arch/h8300/platform/h8300h/generic/rom.ld | 1
arch/i386/vmlinux.lds.S | 1
arch/ia64/vmlinux.lds.S | 4 ++
arch/m68k/vmlinux-std.lds | 1
arch/m68k/vmlinux-sun3.lds | 1
arch/m68knommu/vmlinux.lds.S | 4 --
arch/mips/vmlinux.lds.S | 1
arch/mips64/vmlinux.lds.S | 1
arch/parisc/vmlinux.lds.S | 1
arch/ppc/vmlinux.lds.S | 2 +
arch/ppc64/vmlinux.lds.S | 1
arch/s390/vmlinux.lds.S | 1
arch/sh/vmlinux.lds.S | 1
arch/sparc/vmlinux.lds.S | 1
arch/sparc64/vmlinux.lds.S | 1
arch/x86_64/vmlinux.lds.S | 1
fs/namei.c | 2 -
include/asm-generic/vmlinux.lds.h | 6 +++
include/linux/init.h | 6 +++
include/linux/security.h | 49 ++++++------------------------
init/main.c | 2 -
kernel/sys.c | 20 ++++--------
mm/oom_kill.c | 7 ++--
security/capability.c | 10 ------
security/dummy.c | 12 -------
security/root_plug.c | 3 -
security/security.c | 13 +++++++
31 files changed, 77 insertions(+), 85 deletions(-)

with these changes:

Chris Wright:
o [LSM] early init for security modules. As discussed before, this allows
for early initialization of security modules when compiled statically into
the kernel. The standard do_initcalls is too late for complete coverage of
all filesystems and threads, for example.
o [LSM] Remove security_inode_permission_lite hook
o [LSM] Remove task_kmod_set_label hook, it is no longer necessary

Jakub Jel?nek:
o [LSM] make sure setfsuid/setfsgid return values are right. Before
include/linux/security.h was added, setfsuid/setfsgid always returned

Stephen D. Smalley:
o [LSM] Replaced the direct capability bit tests with calls to the
security_capable hook in mm/oom_kill.c

thanks,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net


2003-06-02 09:44:24

by Chris Wright

[permalink] [raw]
Subject: [PATCH][LSM] Early init for security modules and various cleanups

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1259 -> 1.1260
# mm/oom_kill.c 1.23 -> 1.24
# include/linux/security.h 1.21 -> 1.22
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/02 [email protected] 1.1260
# [LSM] Replaced the direct capability bit tests with calls to the
# security_capable hook in mm/oom_kill.c
# --------------------------------------------
#
diff -Nru a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h Mon Jun 2 01:30:56 2003
+++ b/include/linux/security.h Mon Jun 2 01:30:56 2003
@@ -1231,6 +1231,11 @@
return security_ops->sysctl(table, op);
}

+static inline int security_capable(struct task_struct * tsk, int cap)
+{
+ return security_ops->capable(tsk, cap);
+}
+
static inline int security_quotactl (int cmds, int type, int id,
struct super_block *sb)
{
@@ -1894,6 +1899,11 @@
static inline int security_sysctl(ctl_table * table, int op)
{
return 0;
+}
+
+static inline int security_capable(struct task_struct * tsk, int cap)
+{
+ return cap_capable(tsk, cap);
}

static inline int security_quotactl (int cmds, int type, int id,
diff -Nru a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c Mon Jun 2 01:30:56 2003
+++ b/mm/oom_kill.c Mon Jun 2 01:30:56 2003
@@ -20,6 +20,7 @@
#include <linux/swap.h>
#include <linux/timex.h>
#include <linux/jiffies.h>
+#include <linux/security.h>

/* #define DEBUG */

@@ -91,7 +92,7 @@
* Superuser processes are usually more important, so we make it
* less likely that we kill those.
*/
- if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
+ if (!security_capable(p,CAP_SYS_ADMIN) ||
p->uid == 0 || p->euid == 0)
points /= 4;

@@ -101,7 +102,7 @@
* tend to only have this flag set on applications they think
* of as important.
*/
- if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
+ if (!security_capable(p,CAP_SYS_RAWIO))
points /= 4;
#ifdef DEBUG
printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
@@ -154,7 +155,7 @@
p->flags |= PF_MEMALLOC | PF_MEMDIE;

/* This process has hardware access, be more careful. */
- if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) {
+ if (!security_capable(p,CAP_SYS_RAWIO)) {
force_sig(SIGTERM, p);
} else {
force_sig(SIGKILL, p);

2003-06-02 09:47:28

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1260 -> 1.1261
# security/dummy.c 1.23 -> 1.24
# security/capability.c 1.15 -> 1.16
# include/linux/security.h 1.22 -> 1.23
# security/root_plug.c 1.2 -> 1.3
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/02 [email protected] 1.1261
# [LSM] Remove task_kmod_set_label hook, it is no longer necessary.
# kmod is now handled by keventd which already does reparent_to_init,
# so there is no need to worry about getting the security labels right
# for code running off the keventd workqueue.
# --------------------------------------------
#
diff -Nru a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h Mon Jun 2 01:31:14 2003
+++ b/include/linux/security.h Mon Jun 2 01:31:14 2003
@@ -46,7 +46,6 @@
extern int cap_bprm_set_security (struct linux_binprm *bprm);
extern void cap_bprm_compute_creds (struct linux_binprm *bprm);
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
-extern void cap_task_kmod_set_label (void);
extern void cap_task_reparent_to_init (struct task_struct *p);
extern int cap_syslog (int type);

@@ -607,10 +606,6 @@
* @arg4 contains a argument.
* @arg5 contains a argument.
* Return 0 if permission is granted.
- * @task_kmod_set_label:
- * Set the security attributes in current->security for the kernel module
- * loader thread, so that it has the permissions needed to perform its
- * function.
* @task_reparent_to_init:
* Set the security attributes in @p->security for a kernel thread that
* is being reparented to the init task.
@@ -1111,7 +1106,6 @@
int (*task_prctl) (int option, unsigned long arg2,
unsigned long arg3, unsigned long arg4,
unsigned long arg5);
- void (*task_kmod_set_label) (void);
void (*task_reparent_to_init) (struct task_struct * p);
void (*task_to_inode)(struct task_struct *p, struct inode *inode);

@@ -1697,11 +1691,6 @@
return security_ops->task_prctl (option, arg2, arg3, arg4, arg5);
}

-static inline void security_task_kmod_set_label (void)
-{
- security_ops->task_kmod_set_label ();
-}
-
static inline void security_task_reparent_to_init (struct task_struct *p)
{
security_ops->task_reparent_to_init (p);
@@ -2329,11 +2318,6 @@
unsigned long arg5)
{
return 0;
-}
-
-static inline void security_task_kmod_set_label (void)
-{
- cap_task_kmod_set_label ();
}

static inline void security_task_reparent_to_init (struct task_struct *p)
diff -Nru a/security/capability.c b/security/capability.c
--- a/security/capability.c Mon Jun 2 01:31:14 2003
+++ b/security/capability.c Mon Jun 2 01:31:14 2003
@@ -248,12 +248,6 @@
return 0;
}

-void cap_task_kmod_set_label (void)
-{
- cap_set_full (current->cap_effective);
- return;
-}
-
void cap_task_reparent_to_init (struct task_struct *p)
{
p->cap_effective = CAP_INIT_EFF_SET;
@@ -278,7 +272,6 @@
EXPORT_SYMBOL(cap_bprm_set_security);
EXPORT_SYMBOL(cap_bprm_compute_creds);
EXPORT_SYMBOL(cap_task_post_setuid);
-EXPORT_SYMBOL(cap_task_kmod_set_label);
EXPORT_SYMBOL(cap_task_reparent_to_init);
EXPORT_SYMBOL(cap_syslog);

@@ -298,7 +291,6 @@
.bprm_set_security = cap_bprm_set_security,

.task_post_setuid = cap_task_post_setuid,
- .task_kmod_set_label = cap_task_kmod_set_label,
.task_reparent_to_init = cap_task_reparent_to_init,

.syslog = cap_syslog,
diff -Nru a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c Mon Jun 2 01:31:14 2003
+++ b/security/dummy.c Mon Jun 2 01:31:14 2003
@@ -517,11 +517,6 @@
return 0;
}

-static void dummy_task_kmod_set_label (void)
-{
- return;
-}
-
static void dummy_task_reparent_to_init (struct task_struct *p)
{
p->euid = p->fsuid = 0;
@@ -871,7 +866,6 @@
set_to_dummy_if_null(ops, task_wait);
set_to_dummy_if_null(ops, task_kill);
set_to_dummy_if_null(ops, task_prctl);
- set_to_dummy_if_null(ops, task_kmod_set_label);
set_to_dummy_if_null(ops, task_reparent_to_init);
set_to_dummy_if_null(ops, task_to_inode);
set_to_dummy_if_null(ops, ipc_permission);
diff -Nru a/security/root_plug.c b/security/root_plug.c
--- a/security/root_plug.c Mon Jun 2 01:31:14 2003
+++ b/security/root_plug.c Mon Jun 2 01:31:14 2003
@@ -143,7 +143,6 @@
.bprm_set_security = cap_bprm_set_security,

.task_post_setuid = cap_task_post_setuid,
- .task_kmod_set_label = cap_task_kmod_set_label,
.task_reparent_to_init = cap_task_reparent_to_init,

.bprm_check_security = rootplug_bprm_check_security,

2003-06-02 09:50:08

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1261 -> 1.1262
# security/dummy.c 1.24 -> 1.25
# fs/namei.c 1.73 -> 1.74
# include/linux/security.h 1.23 -> 1.24
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/02 [email protected] 1.1262
# [LSM] Remove security_inode_permission_lite hook
# --------------------------------------------
#
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c Mon Jun 2 01:31:29 2003
+++ b/fs/namei.c Mon Jun 2 01:31:29 2003
@@ -325,7 +325,7 @@

return -EACCES;
ok:
- return security_inode_permission_lite(inode, MAY_EXEC);
+ return security_inode_permission(inode, MAY_EXEC);
}

/*
diff -Nru a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h Mon Jun 2 01:31:29 2003
+++ b/include/linux/security.h Mon Jun 2 01:31:29 2003
@@ -327,16 +327,6 @@
* @inode contains the inode structure to check.
* @mask contains the permission mask.
* Return 0 if permission is granted.
- * @inode_permission_lite:
- * Check permission before accessing an inode. This hook is
- * currently only called when checking MAY_EXEC access during
- * pathname resolution. The dcache lock is held and thus modules
- * that could sleep or contend the lock should return -EAGAIN to
- * inform the kernel to drop the lock and try again calling the
- * full permission hook.
- * @inode contains the inode structure to check.
- * @mask contains the permission mask.
- * Return 0 if permission is granted.
* @inode_setattr:
* Check permission before setting file attributes. Note that the kernel
* call to notify_change is performed from several locations, whenever
@@ -1052,7 +1042,6 @@
int (*inode_readlink) (struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask);
- int (*inode_permission_lite) (struct inode *inode, int mask);
int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
void (*inode_delete) (struct inode *inode);
@@ -1470,12 +1459,6 @@
return security_ops->inode_permission (inode, mask);
}

-static inline int security_inode_permission_lite (struct inode *inode,
- int mask)
-{
- return security_ops->inode_permission_lite (inode, mask);
-}
-
static inline int security_inode_setattr (struct dentry *dentry,
struct iattr *attr)
{
@@ -2103,12 +2086,6 @@
}

static inline int security_inode_permission (struct inode *inode, int mask)
-{
- return 0;
-}
-
-static inline int security_inode_permission_lite (struct inode *inode,
- int mask)
{
return 0;
}
diff -Nru a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c Mon Jun 2 01:31:29 2003
+++ b/security/dummy.c Mon Jun 2 01:31:29 2003
@@ -308,11 +308,6 @@
return 0;
}

-static int dummy_inode_permission_lite (struct inode *inode, int mask)
-{
- return 0;
-}
-
static int dummy_inode_setattr (struct dentry *dentry, struct iattr *iattr)
{
return 0;
@@ -826,7 +821,6 @@
set_to_dummy_if_null(ops, inode_readlink);
set_to_dummy_if_null(ops, inode_follow_link);
set_to_dummy_if_null(ops, inode_permission);
- set_to_dummy_if_null(ops, inode_permission_lite);
set_to_dummy_if_null(ops, inode_setattr);
set_to_dummy_if_null(ops, inode_getattr);
set_to_dummy_if_null(ops, inode_delete);

2003-06-02 09:51:23

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1262 -> 1.1263
# kernel/sys.c 1.45 -> 1.46
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/02 [email protected] 1.1263
# [LSM] make sure setfsuid/setfsgid return values are right. Before
# include/linux/security.h was added, setfsuid/setfsgid always returned
# old_fsuid, no matter if the fsuid was actually changed or not. With
# the default security ops it seems to do the same, because both
# security_task_setuid and security_task_post_setuid return 0, but
# these are hooks which seem to return 0 on success, -errno on failure,
# so if some non-default security hook is installed and ever returns
# -errno in setfsuid/setfsgid, -errno will be returned from the syscall
# instead of the expected old_fsuid. This makes it hard to distinguish
# uids 0xfffff001 .. 0xffffffff from errors of security hooks.
# --------------------------------------------
#
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c Mon Jun 2 01:31:40 2003
+++ b/kernel/sys.c Mon Jun 2 01:31:40 2003
@@ -829,13 +829,11 @@
asmlinkage long sys_setfsuid(uid_t uid)
{
int old_fsuid;
- int retval;
-
- retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
- if (retval)
- return retval;

old_fsuid = current->fsuid;
+ if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
+ return old_fsuid;
+
if (uid == current->uid || uid == current->euid ||
uid == current->suid || uid == current->fsuid ||
capable(CAP_SETUID))
@@ -848,9 +846,7 @@
current->fsuid = uid;
}

- retval = security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
- if (retval)
- return retval;
+ security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);

return old_fsuid;
}
@@ -861,13 +857,11 @@
asmlinkage long sys_setfsgid(gid_t gid)
{
int old_fsgid;
- int retval;
-
- retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS);
- if (retval)
- return retval;

old_fsgid = current->fsgid;
+ if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS))
+ return old_fsgid;
+
if (gid == current->gid || gid == current->egid ||
gid == current->sgid || gid == current->fsgid ||
capable(CAP_SETGID))

2003-06-02 09:53:24

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1263 -> 1.1264
# arch/m68k/vmlinux-sun3.lds 1.14 -> 1.15
# security/security.c 1.7 -> 1.8
# include/linux/init.h 1.25 -> 1.26
# include/asm-generic/vmlinux.lds.h 1.7 -> 1.8
# arch/x86_64/vmlinux.lds.S 1.16 -> 1.17
# arch/sparc/vmlinux.lds.S 1.16 -> 1.17
# arch/h8300/platform/h8300h/generic/rom.ld 1.1 -> 1.2
# init/main.c 1.99 -> 1.100
# arch/i386/vmlinux.lds.S 1.30 -> 1.31
# arch/parisc/vmlinux.lds.S 1.13 -> 1.14
# arch/mips/vmlinux.lds.S 1.8 -> 1.9
# arch/arm/vmlinux-armv.lds.in 1.24 -> 1.25
# security/capability.c 1.16 -> 1.17
# arch/s390/vmlinux.lds.S 1.13 -> 1.14
# arch/m68knommu/vmlinux.lds.S 1.9 -> 1.10
# arch/cris/vmlinux.lds.S 1.16 -> 1.17
# arch/mips64/vmlinux.lds.S 1.7 -> 1.8
# arch/alpha/vmlinux.lds.S 1.21 -> 1.22
# arch/sh/vmlinux.lds.S 1.10 -> 1.11
# arch/ppc64/vmlinux.lds.S 1.14 -> 1.15
# arch/ia64/vmlinux.lds.S 1.29 -> 1.30
# arch/sparc64/vmlinux.lds.S 1.18 -> 1.19
# arch/m68k/vmlinux-std.lds 1.16 -> 1.17
# arch/arm/vmlinux-armo.lds.in 1.15 -> 1.16
# security/root_plug.c 1.3 -> 1.4
# arch/ppc/vmlinux.lds.S 1.19 -> 1.20
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/02 [email protected] 1.1264
# [LSM] early init for security modules. As discussed before, this allows
# for early initialization of security modules when compiled statically
# into the kernel. The standard do_initcalls is too late for complete
# coverage of all filesystems and threads, for example.
# --------------------------------------------
#
diff -Nru a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S
--- a/arch/alpha/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/alpha/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -74,6 +74,9 @@
__con_initcall_end = .;
}

+ . = ALIGN(8);
+ SECURITY_INIT
+
. = ALIGN(64);
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
diff -Nru a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
--- a/arch/arm/vmlinux-armo.lds.in Mon Jun 2 01:31:49 2003
+++ b/arch/arm/vmlinux-armo.lds.in Mon Jun 2 01:31:49 2003
@@ -43,6 +43,7 @@
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(32768);
__init_end = .;
}
diff -Nru a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
--- a/arch/arm/vmlinux-armv.lds.in Mon Jun 2 01:31:49 2003
+++ b/arch/arm/vmlinux-armv.lds.in Mon Jun 2 01:31:49 2003
@@ -53,6 +53,7 @@
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(32);
__initramfs_start = .;
usr/built-in.o(.init.ramfs)
diff -Nru a/arch/cris/vmlinux.lds.S b/arch/cris/vmlinux.lds.S
--- a/arch/cris/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/cris/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -74,7 +74,9 @@
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
-
+ }
+ SECURITY_INIT
+
/* We fill to the next page, so we can discard all init
pages without needing to consider what payload might be
appended to the kernel image. */
diff -Nru a/arch/h8300/platform/h8300h/generic/rom.ld b/arch/h8300/platform/h8300h/generic/rom.ld
--- a/arch/h8300/platform/h8300h/generic/rom.ld Mon Jun 2 01:31:49 2003
+++ b/arch/h8300/platform/h8300h/generic/rom.ld Mon Jun 2 01:31:49 2003
@@ -83,6 +83,7 @@
___con_initcall_start = .;
*(.con_initcall.init)
___con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4);
___initramfs_start = .;
*(.init.ramfs)
diff -Nru a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S
--- a/arch/i386/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/i386/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -81,6 +81,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4);
__alt_instructions = .;
.altinstructions : { *(.altinstructions) }
diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
--- a/arch/ia64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/ia64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -141,6 +141,10 @@
.con_initcall.init : AT(ADDR(.con_initcall.init) - PAGE_OFFSET)
{ *(.con_initcall.init) }
__con_initcall_end = .;
+ __security_initcall_start = .;
+ .security_initcall.init : AT(ADDR(.security_initcall.init) - PAGE_OFFSET)
+ { *(.security_initcall.init) }
+ __security_initcall_end = .;
. = ALIGN(PAGE_SIZE);
__init_end = .;

diff -Nru a/arch/m68k/vmlinux-std.lds b/arch/m68k/vmlinux-std.lds
--- a/arch/m68k/vmlinux-std.lds Mon Jun 2 01:31:49 2003
+++ b/arch/m68k/vmlinux-std.lds Mon Jun 2 01:31:49 2003
@@ -67,6 +67,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds
--- a/arch/m68k/vmlinux-sun3.lds Mon Jun 2 01:31:49 2003
+++ b/arch/m68k/vmlinux-sun3.lds Mon Jun 2 01:31:49 2003
@@ -61,6 +61,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/arch/m68knommu/vmlinux.lds.S b/arch/m68knommu/vmlinux.lds.S
--- a/arch/m68knommu/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/m68knommu/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -277,9 +277,7 @@
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
- __security_initcall_start = .;
- *(.security_initcall.init)
- __security_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4);
__initramfs_start = .;
*(.init.ramfs)
diff -Nru a/arch/mips/vmlinux.lds.S b/arch/mips/vmlinux.lds.S
--- a/arch/mips/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/mips/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -54,6 +54,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096); /* Align double page for init_task_union */
__init_end = .;

diff -Nru a/arch/mips64/vmlinux.lds.S b/arch/mips64/vmlinux.lds.S
--- a/arch/mips64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/mips64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -53,6 +53,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096); /* Align double page for init_task_union */
__init_end = .;

diff -Nru a/arch/parisc/vmlinux.lds.S b/arch/parisc/vmlinux.lds.S
--- a/arch/parisc/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/parisc/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -80,6 +80,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/arch/ppc/vmlinux.lds.S b/arch/ppc/vmlinux.lds.S
--- a/arch/ppc/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/ppc/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -115,6 +115,8 @@
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;

+ SECURITY_INIT
+
__start___ftr_fixup = .;
__ftr_fixup : { *(__ftr_fixup) }
__stop___ftr_fixup = .;
diff -Nru a/arch/ppc64/vmlinux.lds.S b/arch/ppc64/vmlinux.lds.S
--- a/arch/ppc64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/ppc64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -104,6 +104,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/arch/s390/vmlinux.lds.S b/arch/s390/vmlinux.lds.S
--- a/arch/s390/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/s390/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -94,6 +94,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(256);
__initramfs_start = .;
.init.ramfs : { *(.init.initramfs) }
diff -Nru a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
--- a/arch/sh/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/sh/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -71,6 +71,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
__machvec_start = .;
.machvec.init : { *(.machvec.init) }
__machvec_end = .;
diff -Nru a/arch/sparc/vmlinux.lds.S b/arch/sparc/vmlinux.lds.S
--- a/arch/sparc/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/sparc/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -62,6 +62,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/arch/sparc64/vmlinux.lds.S b/arch/sparc64/vmlinux.lds.S
--- a/arch/sparc64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/sparc64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -68,6 +68,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/arch/x86_64/vmlinux.lds.S b/arch/x86_64/vmlinux.lds.S
--- a/arch/x86_64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
+++ b/arch/x86_64/vmlinux.lds.S Mon Jun 2 01:31:49 2003
@@ -105,6 +105,7 @@
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff -Nru a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- a/include/asm-generic/vmlinux.lds.h Mon Jun 2 01:31:49 2003
+++ b/include/asm-generic/vmlinux.lds.h Mon Jun 2 01:31:49 2003
@@ -45,3 +45,9 @@
*(__ksymtab_strings) \
}

+#define SECURITY_INIT \
+ .security_initcall.init : { \
+ __security_initcall_start = .; \
+ *(.security_initcall.init) \
+ __security_initcall_end = .; \
+ }
diff -Nru a/include/linux/init.h b/include/linux/init.h
--- a/include/linux/init.h Mon Jun 2 01:31:49 2003
+++ b/include/linux/init.h Mon Jun 2 01:31:49 2003
@@ -64,6 +64,7 @@
typedef void (*exitcall_t)(void);

extern initcall_t __con_initcall_start, __con_initcall_end;
+extern initcall_t __security_initcall_start, __security_initcall_end;
#endif

#ifndef MODULE
@@ -96,6 +97,9 @@
#define console_initcall(fn) \
static initcall_t __initcall_##fn __attribute__ ((unused,__section__ (".con_initcall.init")))=fn

+#define security_initcall(fn) \
+ static initcall_t __initcall_##fn __attribute__ ((unused,__section__ (".security_initcall.init"))) = fn
+
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
@@ -142,6 +146,8 @@
#define fs_initcall(fn) module_init(fn)
#define device_initcall(fn) module_init(fn)
#define late_initcall(fn) module_init(fn)
+
+#define security_initcall(fn) module_init(fn)

/* These macros create a dummy inline: gcc 2.9x does not count alias
as usage, hence the `unused function' warning when __init functions
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c Mon Jun 2 01:31:49 2003
+++ b/init/main.c Mon Jun 2 01:31:49 2003
@@ -435,8 +435,8 @@
pte_chain_init();
fork_init(num_physpages);
proc_caches_init();
- security_scaffolding_startup();
buffer_init();
+ security_scaffolding_startup();
vfs_caches_init(num_physpages);
radix_tree_init();
signals_init();
diff -Nru a/security/capability.c b/security/capability.c
--- a/security/capability.c Mon Jun 2 01:31:49 2003
+++ b/security/capability.c Mon Jun 2 01:31:49 2003
@@ -340,7 +340,7 @@
}
}

-module_init (capability_init);
+security_initcall (capability_init);
module_exit (capability_exit);

MODULE_DESCRIPTION("Standard Linux Capabilities Security Module");
diff -Nru a/security/root_plug.c b/security/root_plug.c
--- a/security/root_plug.c Mon Jun 2 01:31:49 2003
+++ b/security/root_plug.c Mon Jun 2 01:31:49 2003
@@ -183,7 +183,7 @@
printk (KERN_INFO "Root Plug module removed\n");
}

-module_init (rootplug_init);
+security_initcall (rootplug_init);
module_exit (rootplug_exit);

MODULE_DESCRIPTION("Root Plug sample LSM module, written for Linux Journal article");
diff -Nru a/security/security.c b/security/security.c
--- a/security/security.c Mon Jun 2 01:31:49 2003
+++ b/security/security.c Mon Jun 2 01:31:49 2003
@@ -38,12 +38,22 @@
return 0;
}

+static void __init do_security_initcalls(void)
+{
+ initcall_t *call;
+ call = &__security_initcall_start;
+ while (call < &__security_initcall_end) {
+ (*call)();
+ call++;
+ }
+}
+
/**
* security_scaffolding_startup - initialzes the security scaffolding framework
*
* This should be called early in the kernel initialization sequence.
*/
-int security_scaffolding_startup (void)
+int __init security_scaffolding_startup (void)
{
printk (KERN_INFO "Security Scaffold v" SECURITY_SCAFFOLD_VERSION
" initialized\n");
@@ -55,6 +65,7 @@
}

security_ops = &dummy_security_ops;
+ do_security_initcalls();

return 0;
}

Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

On Mon, 2 Jun 2003, Chris Wright wrote:

> @@ -91,7 +92,7 @@
> * Superuser processes are usually more important, so we make it
> * less likely that we kill those.
> */
> - if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
> + if (!security_capable(p,CAP_SYS_ADMIN) ||
> p->uid == 0 || p->euid == 0)
> points /= 4;
..............
> - if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
> + if (!security_capable(p,CAP_SYS_RAWIO))
> points /= 4;

Correct me if i am wrong, but I think it is not a good idea to favor
applications with more
capabilities, as ussualy those are most wanted target on a system.


--
Grzegorz Jaskiewcz

2003-06-02 09:59:25

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

* Grzegorz Jaskiewicz ([email protected]) wrote:
> On Mon, 2 Jun 2003, Chris Wright wrote:
>
> > @@ -91,7 +92,7 @@
> > * Superuser processes are usually more important, so we make it
> > * less likely that we kill those.
> > */
> > - if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
> > + if (!security_capable(p,CAP_SYS_ADMIN) ||
> > p->uid == 0 || p->euid == 0)
> > points /= 4;
> ..............
> > - if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
> > + if (!security_capable(p,CAP_SYS_RAWIO))
> > points /= 4;
>
> Correct me if i am wrong, but I think it is not a good idea to favor
> applications with more
> capabilities, as ussualy those are most wanted target on a system.

security_capable() returns 0 if that capability bit is set. so there is
no functional change here, just allows the security module to see the
capability check that was hand coded.

thanks,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net

2003-06-02 10:30:50

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

Chris Wright <[email protected]> wrote:
>
> security_capable() returns 0 if that capability bit is set.

That's just bizarre. Is there any logic behind it?


2003-06-02 12:37:24

by Stephen Smalley

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

On Mon, 2003-06-02 at 06:44, Andrew Morton wrote:
> Chris Wright <[email protected]> wrote:
> >
> > security_capable() returns 0 if that capability bit is set.
>
> That's just bizarre. Is there any logic behind it?

The LSM access control hooks all return 0 on success (i.e. permission
granted) and negative error code on failure, like most of the rest of
the kernel interfaces (e.g. consider permission()). Hence, the
security_capable() hook returns 0 when the capability is granted to the
specified task. Naturally, the capable() function (which now internally
calls security_capable) preserves the old interface, and most callers
still invoke it rather than directly calling security_capable().
However, the oom killer code is performing a capability test for a task
other than current; hence, it makes a direct call to the
security_capable() hook that supports passing a particular task, unlike
the capable() function.

--
Stephen Smalley <[email protected]>
National Security Agency

2003-06-02 16:23:42

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH][LSM] Early init for security modules and various cleanups

* Andrew Morton ([email protected]) wrote:
> Chris Wright <[email protected]> wrote:
> >
> > security_capable() returns 0 if that capability bit is set.
>
> That's just bizarre. Is there any logic behind it?

Yes, as Stephen pointed out, it's common for the security interface to
return 0 on success on -errno on failure.

cheers,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net