Re: [TOMOYO 05/15](repost) Domain transition handler functions.

Previous thread: none

Next thread: [patch] menuconfig - lift the fs menu by Jan Engelhardt on Tuesday, October 2, 2007 - 9:51 am. (3 messages)
To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:25 am

"TOMOYO Linux" is our work in the field of security enhanced Linux.
This is the repeated post of second submission of TOMOYO Linux
( http://lkml.org/lkml/2007/8/24/116 ).

Unfortunately it was just before the Kernel Summit.
We could not receive any suggestions about our codes.
Before this posting, we changed the program to use
securityfs (Kyle's comment) and re-generated patches
with the current git tree.

When we posted our first proposal to LKML, TOMOYO Linux's MAC was
limited to file access control. Now TOMOYO Linux has access control
functionality not only for files but also for networking, signal
transmission and namespace manipulation and we got the source code
cleaned-up.

Patches consist of four types.
* [TOMOYO 01/15]: Mandatory modifications against standard kernel.
* [TOMOYO 02-13/15]: LSM implementation of TOMOYO Linux.
* [TOMOYO 14/15]: Optional modifications against standard kernel.
* [TOMOYO 15/15]: Makefile and Kconfig .

<<What you can do with TOMOYO Linux.>>

The fundamental concept of TOMOYO Linux is "tracking process
invocation history".

The "struct task_struct"->security member holds a pointer to the
"process invocation history". Thus, every process (the kernel,
/sbin/init process and any children/descendant of /sbin/init) knows
its "process invocation history" (or ancestors). Since every process
knows its ancestors, TOMOYO Linux can enforce access control over all
processes.

TOMOYO Linux splits domains using "process invocation history" and the
process transits to a different domain whenever execution of a program
(i.e. do_execve()) is requested. By transiting to a different domain
whenever execution of a program is requested, each domain will have
the minimal permissions that are essential for processes in that
domain to do their roles.

You don't need to define domains beforehand. TOMOYO Linux kernel will
automatically define new domains whenever execution of a program is
requested, and the process wil...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:30 am

Basic functions to get canonicalized absolute pathnames
for TOMOYO Linux. Even the requested pathname is symlink()ed
or chroot()ed, TOMOYO Linux uses the original pathname.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/realpath.c | 697 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 697 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/realpath.c 2007-10-02 11:26:21.000000000 +0900
@@ -0,0 +1,697 @@
+/*
+ * security/tomoyo/realpath.c
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO Linux.
+ */
+
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/utime.h>
+#include <linux/file.h>
+#include <linux/smp_lock.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include "realpath.h"
+#include "tomoyo.h"
+
+/***** realpath handler *****/
+
+static int tmy_print_ascii(const char *sp, const char *cp,
+ int *buflen0, char **end0)
+{
+ int buflen = *buflen0;
+ char *end = *end0;
+
+ while (sp <= cp) {
+ unsigned char c;
+
+ c = *(unsigned char *) cp;
+ if (c == '\\') {
+ buflen -= 2;
+ if (buflen < 0)
+ goto out;
+ *--end = '\\';
+ *--end = '\\';
+ } else if (c > ' ' && c < 127) {
+ if (--buflen < 0)
+ goto out;
+ *--end = (char) c;
+ } else {
+ buflen -= 4;
+ if (buflen < 0)
+ goto out;
+ *--end = (c & 7) + '0';
+ *--end = ((c >> 3) & 7) + '0';
+ *--end = (c >> 6) + '0';
+ *--end = '\\';
+ }
+ cp--;
+ }
+
+ *buflen0 = buflen;
+ *end0 = end;
+
+ return 0;
+out: ;
+ return -ENOMEM;
+}
+
+/**
+ * tmy_get_absolute_...

To: Kentaro Takeda <takedakn@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 3:39 am

Would you please explain why you need another level of memory allocation?

What does it do apart from let you check for memory leaks?

- James
--
James Morris
<jmorris@namei.org>
-

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 7:12 am

Hello.

Difference between tmy_alloc() and kmalloc() are

tmy_alloc() allows administrator know "how much memory is used by TOMOYO Linux modules"
via /sys/kernel/security/tomoyo/meminfo interface.
This feature was requested by TOMOYO Linux users.
/proc/slabinfo can show how much memory is used by all modules,
but it cannot show how much memory is used by TOMOYO Linux modules.

tmy_alloc() can indicate memory-leaking bug and can avoid double-kfree() bug
by keeping the pointer returned by kmalloc() in a local "cache_list" list.

tmy_alloc() also keeps the size of memory allocated by kmalloc() in "cache_list" list
so that administrator can know "how much memory is used by TOMOYO Linux modules".
Calling ksize() after kmalloc() in tmy_alloc() and
calling ksize() before kfree() in tmy_free() might be better
if double-kfree-checks and memory-leaking-checks (i.e. "tmy_cachep") are unneeded.

Regards.

-

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:42 am

About problems of pathname-based access control and countermeasures:

TOMOYO Linux has many countermeasures that prevents many of pathname-based access control's problems.
In short, in TOMOYO Linux, attackers can't create link freely, can't rename freely,
can't manipulate namespace freely.

Not all problems can be solved (some of causes are current LSM specification),
but is enough for SOHO (Small Office/Home Office)/personal systems.

Last discussion log is at http://lkml.org/lkml/2007/8/28/113 .

About policy file handling:

Common implementations treat policy file on the filesystem as the up-to-date data,
and the kernel keeps a copy of policy file in kernel's memory.
But TOMOYO's implementation is opposite.

TOMOYO Linux has "learning mode" feature that helps administrator develop ACL (access control list).
Since the "learning mode" automatically appends entries to in-memory datastructure,
TOMOYO Linux implements in-memory datastructure using a singly-linked list
using a kind of DBMS (DataBase Management System).

TOMOYO Linux regards the ACL in kernel's DBMS as the up-to-date data
and the ACL in the policy file as a backup.
TOMOYO Linux's policy file consists of instructions for reproducing a snapshot of
ACL entries in kernel's DBMS which was saved in the past.

This is the reason why TOMOYO Linux doesn't use binary (offset-from-start-of-policy) format
for policy file, and in-kernel policy parser exists.

Last discussion log is at http://marc.info/?l=linux-security-module&m=119039218805158&w=2 .

About network hook expansion:

TOMOYO Linux makes use of userspace intervention to allow/reject connections and/or packets
based on the application's domain.
Current network-related LSM hooks can't know the final recipient of connections and/or packets.

This is the reason why TOMOYO Linux wants to add post-accept() and post-recvmsg() hooks.

Last discussion log is at http://lkml.org/lkml/2007/9/5/98 .

-

To: Kentaro Takeda <takedakn@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 6:37 am

It seems that patches 1-3 are missing.

I'd also suggest making all of the patches a reply to the first email, so
they can be threaded.

- James
--
James Morris
<jmorris@namei.org>
-

To: James Morris <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 6:58 am

Thanks a lot for your suggestions.

Actually we did just as you wrote, but somehow 0-3 parts are missing.

Unfortunately, the parent message [00/15] is in the three.
If the [00/15] will be delivered, everything goes just fine.
We are going to wait some more time and decide to repost them again.

Thanks again.

Kentaro Takeda

-

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:40 am

Kconfig and Makefile for TOMOYO Linux.
TOMOYO Linux is placed in security/tomoyo .

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/Kconfig | 1 +
security/Makefile | 1 +
security/tomoyo/Kconfig | 18 ++++++++++++++++++
security/tomoyo/Makefile | 3 +++
4 files changed, 23 insertions(+)

--- linux-2.6.orig/security/Kconfig 2007-10-02 11:11:53.000000000 +0900
+++ linux-2.6/security/Kconfig 2007-10-02 11:26:21.000000000 +0900
@@ -94,6 +94,7 @@ config SECURITY_ROOTPLUG
If you are unsure how to answer this question, answer N.

source security/selinux/Kconfig
+source security/tomoyo/Kconfig

endmenu

--- linux-2.6.orig/security/Makefile 2007-10-02 11:11:53.000000000 +0900
+++ linux-2.6/security/Makefile 2007-10-02 11:26:21.000000000 +0900
@@ -16,3 +16,4 @@ obj-$(CONFIG_SECURITY) += security.o d
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
+obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
\ No newline at end of file
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/Kconfig 2007-10-02 11:26:21.000000000 +0900
@@ -0,0 +1,18 @@
+config SECURITY_TOMOYO
+ bool "TOMOYO Linux support"
+ depends on SECURITY
+ select SECURITY_NETWORK
+ select AUDIT
+ default n
+ help
+ This selects TOMOYO Linux.
+
+ TOMOYO Linux is a domain-based access control method using LSM.
+ If you answer Y, you will need a policy loader program
+ (/sbin/tomoyo-init) and some configuration files.
+ You can get them from
+ <http://tomoyo.sourceforge.jp/en/2.1.x/>
+
+ TOMOYO Linux is also applicable to figuring out the behavior
+ of your system, for TOMOYO uses the canonicalized absolute
+ pathnames and TreeView style domain transitions.
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:39 am

LSM expansion for TOMOYO Linux.

LSM hooks for sending signal:
* task_kill_unlocked is added in sys_kill
* task_tkill_unlocked is added in sys_tkill
* task_tgkill_unlocked is added in sys_tgkill
LSM hooks for network accept and recv:
* socket_post_accept is modified to return int.
* post_recv_datagram is added in skb_recv_datagram.

You can try TOMOYO Linux without this patch, but in that case, you
can't use access control functionality for restricting signal
transmission and incoming network data.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
include/linux/security.h | 91 +++++++++++++++++++++++++++++++++++++++++++----
kernel/signal.c | 17 ++++++++
net/core/datagram.c | 22 +++++++++++
net/socket.c | 7 ++-
security/dummy.c | 32 ++++++++++++++--
5 files changed, 157 insertions(+), 12 deletions(-)

--- linux-2.6.orig/include/linux/security.h 2007-10-02 11:11:51.000000000 +0900
+++ linux-2.6/include/linux/security.h 2007-10-02 11:26:23.000000000 +0900
@@ -628,6 +628,22 @@ struct request_sock;
* @sig contains the signal value.
* @secid contains the sid of the process where the signal originated
* Return 0 if permission is granted.
+ * @task_kill_unlocked:
+ * Check permission before sending signal @sig to the process of @pid
+ * with sys_kill.
+ * @pid contains the pid of target process.
+ * @sig contains the signal value.
+ * @task_tkill_unlocked:
+ * Check permission before sending signal @sig to the process of @pid
+ * with sys_tkill.
+ * @pid contains the pid of target process.
+ * @sig contains the signal value.
+ * @task_tgkill_unlocked:
+ * Check permission before sending signal @sig to the process of @pid
+ * with sys_tgkill.
+ * @tgid contains the thread group id.
+ * @pid contains the pid of target process.
+ * @sig contains the signal value.
* @task_wait:
* Check permission before allowing a proc...

To: Kentaro Takeda <takedakn@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, Chris Wright <chrisw@...>, David S. Miller <davem@...>
Date: Tuesday, October 2, 2007 - 10:36 am

I'm guessing you need this to determine the receiving process, rather than
the socket (which is available via security_sock_rcv_skb()).

If so, is this to interactively determine from the user or admin whether
the packet should be accepted/denied for the receiving process?

- James
--
James Morris
<jmorris@namei.org>
-

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>, <davem@...>
Date: Tuesday, October 2, 2007 - 5:49 pm

Hello.

Thank you for your comment.

Use of security_sock_rcv_skb() was discussed at http://lkml.org/lkml/2007/8/28/74 ,
Yes, it is to determine whether the packet should be accepted/denied
based on the receiving process (like what anti-virus software's firewall does).

Regards.

-

To: Kentaro Takeda <takedakn@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 8:48 am

Why do you need racy unlocked versions, in addition to the existing
security_task_kill() hook which is called safely via
check_kill_permission() ?

- James
--
James Morris
<jmorris@namei.org>
-

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 9:33 am

Hello.

TOMOYO Linux provides "delayed enforcing mode" which allows administrator
judge interactively for requests that violated policy.

Sometimes, especially after updating software packages, irregular behavior arise.
So, the administrator prepares for such irregular behavior
by invoking "ccs-queryd" userland program.
The "ccs-queryd" prints the contents of policy violation and
asks the administrator whether to grant the request that violated policy.
This can reduce the possibility of "restarting process failed due to permission denied".

Thus, security_task_kill() which is called with tasklist_lock held
is not what TOMOYO Linux wants.

I know this approach is racy, but TOMOYO Linux wants these unlocked versions
to avoid failure due to permission denial caused by MAC's policy.

Regards.

-

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:39 am

This patch allows administrators use conditional permission.
TOMOYO Linux supports conditional permission based on
process's UID,GID etc. and/or requested pathname's UID/GID.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/condition.c | 680 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 680 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/condition.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,680 @@
+/*
+ * security/tomoyo/condition.c
+ *
+ * Functions to support conditional access control for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/**
+ * tmy_find_condition_part - check whether a line contains condition part.
+ * @data: a line to check.
+ *
+ * Returns pointer to condition part if found.
+ * Returns NULL if not found.
+ *
+ * Since the trailing spaces are removed by tmy_normalize_line(),
+ * the last "\040if\040" sequence corresponds to condition part.
+ */
+char *tmy_find_condition_part(char *data)
+{
+ char *cp = strstr(data, " if ");
+ if (cp) {
+ char *cp2;
+ while ((cp2 = strstr(cp + 3, " if ")) != NULL)
+ cp = cp2;
+ *cp++ = '\0';
+ }
+ return cp;
+}
+
+#define VALUE_TYPE_DECIMAL 1 /* 01 */
+#define VALUE_TYPE_OCTAL 2 /* 10 */
+#define VALUE_TYPE_HEXADECIMAL 3 /* 11 */
+
+static int tmy_parse_ulong(unsigned long *result, const char **str)
+{
+ const char *cp = *str;
+ char *ep;
+ int base = 10;
+ if (*cp == '0') {
+ char c = *(cp + 1);
+ if (c == 'x' || c == 'X') {
+ base = 16; cp += 2;
+ } else if (c >= '0' && c <= '7') {
+ base = 8; cp++;
+ }
+ }
+ *result = simple_strtoul(cp, &ep, base);
+ if (cp == ep) return 0; /* 00 */
+ *str = ep;
+ return (base == 16 ? VALUE_TYPE_HEXADECIMAL :
+ (base == 8 ? VALUE_TYPE_OCTAL : VALUE_TYPE_DECIMAL));
+}
+
+static void tmy_print_ulong(char *buffer, const int buf...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:38 am

LSM wrapper functions for TOMOYO Linux access control.
If bind mounts are used, TOMOYO requires all permissions for
all possible pathnames (whereas AppArmor requires one of possible pathnames).
If "struct vfsmount" is passed to LSM hooks as AppArmor proposes,
this file will become more simpler and "namespace_sem" can remain "static".

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/tomoyo.c | 748 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 748 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/tomoyo.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,748 @@
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * LSM hooks for TOMOYO Linux.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/security.h>
+#include <linux/highmem.h>
+#include <linux/namei.h>
+#include <linux/mnt_namespace.h>
+#include <linux/sysctl.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+#include "tomoyo.h"
+#include "realpath.h"
+#define MAX_SOCK_ADDR 128 /* net/socket.c */
+
+/* The initial domain. */
+struct domain_info KERNEL_DOMAIN = { NULL, NULL, NULL, 0, 0, 0 };
+
+static struct kmem_cache *tmy_cachep;
+
+static int tmy_task_alloc_security(struct task_struct *p)
+{
+ struct tmy_security *ptr = kmem_cache_alloc(tmy_cachep, GFP_KERNEL);
+
+ if (!ptr)
+ return -ENOMEM;
+ memcpy(ptr, TMY_SECURITY, sizeof(*ptr));
+ p->security = ptr;
+ return 0;
+}
+
+static void tmy_task_free_security(struct task_struct *p)
+{
+ kmem_cache_free(tmy_cachep, p->security);
+}
+
+static int tmy_bprm_alloc_security(struct linux_binprm *bprm)
+{
+ TMY_SECURITY->prev_domain = TMY_SECURITY->domain;
+ return 0;
+}
+
+static int tmy_bprm_check_security(struct l...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:37 am

Signal control functions for TOMOYO Linux.
TOMOYO Linux checks sending signal by signal number and
the domain of target process. In order to check signal
permission, LSM expansion patch [TOMOYO 14/15] is needed.

Each permission can be automatically accumulated into
the policy of each domain using 'learning mode'.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/signal.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 229 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/signal.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,229 @@
+/*
+ * security/tomoyo/signal.c
+ *
+ * Signal access contol functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/************************* AUDIT FUNCTIONS *************************/
+
+static int tmy_audit_signal_log(const int signal,
+ const struct path_info *dest_domain,
+ const u8 is_granted,
+ const u8 is_enforce)
+{
+ char *buf;
+ int len;
+
+ if (is_granted) {
+ if (!tmy_audit_grant())
+ return 0;
+ } else {
+ if (!tmy_audit_reject())
+ return 0;
+ }
+
+ len = dest_domain->total_len;
+ buf = tmy_init_audit_log(&len);
+
+ if (!buf)
+ return -ENOMEM;
+
+ snprintf(buf + strlen(buf),
+ len - strlen(buf) - 1,
+ "%s%d %s",
+ TMY_ALLOW_SIGNAL, signal, dest_domain->name);
+
+ return tmy_write_audit_log(buf, is_granted, is_enforce);
+}
+
+/************************* SIGNAL ACL HANDLER *************************/
+
+static int tmy_add_signal_entry(const u16 sig, const char *dest_pattern,
+ struct domain_info *domain,
+ const struct condition_list *cond,
+ const u8 is_delete)
+{
+ struct acl_info *ptr;
+ const struct path_info *saved_dest_pattern;
+ int error = -ENOMEM;
+
+ if (!domain)
+ return -EINVAL;
+ if (!dest_pattern ||
+ !tmy_is_correct_domain(dest_pattern, __F...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:37 am

Mount access control functions for TOMOYO Linux.
TOMOYO Linux checks permission according to
device name, mount point, filesystem type and optional flags.
TOMOYO Linux also checks permission in umount and pivot_root.

Each permission can be automatically accumulated into
the policy using 'learning mode'.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/mount.c | 1019 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1019 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/mount.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,1019 @@
+/*
+ * security/tomoyo/mount.c
+ *
+ * Mount access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include <linux/namei.h>
+#include <linux/mnt_namespace.h>
+
+/***** KEYWORDS for mount restrictions. *****/
+
+#define MOUNT_BIND_KEYWORD "--bind"
+#define MOUNT_MOVE_KEYWORD "--move"
+#define MOUNT_REMOUNT_KEYWORD "--remount"
+#define MOUNT_MAKE_UNBINDABLE_KEYWORD "--make-unbindable"
+#define MOUNT_MAKE_PRIVATE_KEYWORD "--make-private"
+#define MOUNT_MAKE_SLAVE_KEYWORD "--make-slave"
+#define MOUNT_MAKE_SHARED_KEYWORD "--make-shared"
+
+/***** The structure for mount restrictions. *****/
+
+struct mount_entry {
+ struct mount_entry *next; /* NULL if none. */
+ const struct path_info *dev_name;
+ const struct path_info *dir_name;
+ const struct path_info *fs_type;
+ unsigned int flags; /* Mount flags. */
+ u8 is_deleted;
+};
+
+struct no_umount_entry {
+ struct no_umount_entry *next; /* NULL if none. */
+ const struct path_info *dir;
+ u8 is_deleted;
+};
+
+/************************* AUDIT FUNCTIONS *************************/
+
+static int tmy_audit_mount_log(const u8 is_granted,
+ const u8 is_enforce,
+ const char *fmt, ...)
+ __attribute__((format(prin...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:36 am

Network access control functions for TOMOYO Linux.
TOMOYO Linux checks permission by the following four parameters.
* protocol type (TCP, UDP, RAW)
* access type (bind, listen, connect, accept)
* IP address (Both IPv4 and IPv6 are available)
* port number
In order to check 'TCP accept' and 'UDP connect',
LSM expansion patch ([TOMOYO 14/15]) is needed.

Each permission can be automatically accumulated into
the policy of each domain using 'learning mode'.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/net.c | 975 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 975 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/net.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,975 @@
+/*
+ * security/tomoyo/net.c
+ *
+ * Network access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include <net/ip.h>
+
+/************************* AUDIT FUNCTIONS *************************/
+
+static int tmy_audit_network_log(const u8 is_ipv6,
+ const char *operation,
+ const u32 *address,
+ const u16 port,
+ const u8 is_granted,
+ const u8 is_enforce)
+{
+ char *buf;
+ int len = 256;
+
+ if (is_granted) {
+ if (!tmy_audit_grant())
+ return 0;
+ } else {
+ if (!tmy_audit_reject())
+ return 0;
+ }
+
+ buf = tmy_init_audit_log(&len);
+ if (!buf)
+ return -ENOMEM;
+
+ snprintf(buf + strlen(buf), len - strlen(buf) - 1,
+ TMY_ALLOW_NETWORK "%s ", operation);
+
+ if (is_ipv6)
+ tmy_print_ipv6(buf + strlen(buf), len - strlen(buf),
+ (const u16 *) address);
+ else {
+ u32 ip = *address;
+ snprintf(buf + strlen(buf), len - strlen(buf) - 1,
+ NIPQUAD_FMT, NIPQUAD(ip));
+ }
+
+ snprintf(buf + strlen(buf), len - strlen(buf) - 1, " %u", port);
+
+ return tmy_write_audit_log(buf, is_granted, is_enforce);
+}
+
+/**...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:35 am

argv[0] check functions for TOMOYO Linux.
If the executed program name and argv[0] is different,
TOMOYO Linux checks permission.

Each permission can be automatically accumulated into
the policy of each domain using 'learning mode'.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/exec.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 222 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/exec.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,222 @@
+/*
+ * security/tomoyo/exec.c
+ *
+ * Argv0 access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/************************* AUDIT FUNCTIONS *************************/
+
+static int tmy_audit_argv0_log(const struct path_info *filename,
+ const char *argv0,
+ const u8 is_granted,
+ const u8 is_enforce)
+{
+ char *buf;
+ int len;
+
+ if (is_granted) {
+ if (!tmy_audit_grant())
+ return 0;
+ } else {
+ if (!tmy_audit_reject())
+ return 0;
+ }
+
+ len = filename->total_len + strlen(argv0) + 8;
+ buf = tmy_init_audit_log(&len);
+
+ if (!buf)
+ return -ENOMEM;
+
+ snprintf(buf + strlen(buf),
+ len - strlen(buf) - 1,
+ TMY_ALLOW_ARGV0 "%s %s",
+ filename->name,
+ argv0);
+
+ return tmy_write_audit_log(buf, is_granted, is_enforce);
+}
+
+/************************* ARGV0 MISMATCH HANDLER *************************/
+
+static int tmy_add_argv0_entry(const char *filename,
+ const char *argv0,
+ struct domain_info *domain,
+ const struct condition_list *cond,
+ const u8 is_delete)
+{
+ struct acl_info *ptr;
+ const struct path_info *saved_filename;
+ const struct path_info *saved_argv0;
+ int error = -ENOMEM;
+
+ if (!tmy_correct_path(filename, 1, 0, -1, __FUNCTION__) ||
+ !tmy_correct_path(argv0, -1,...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:34 am

File access control functions for TOMOYO Linux.
TOMOYO Linux checks permission in
open/creat/unlink/truncate/ftruncate/mknod/mkdir/
rmdir/symlink/link/rename/uselib/sysctl .

Each permission can be automatically accumulated into
the policy of each domain using 'learning mode'.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/file.c | 1544 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1544 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/file.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,1544 @@
+/*
+ * security/tomoyo/file.c
+ *
+ * File access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
+
+/************************* VARIABLES *************************/
+
+/***** The structure for globally readable files. *****/
+
+struct globally_readable_file_entry {
+ struct globally_readable_file_entry *next;
+ const struct path_info *filename;
+ u8 is_deleted;
+};
+
+/***** The structure for filename patterns. *****/
+
+struct pattern_entry {
+ struct pattern_entry *next;
+ const struct path_info *pattern;
+ u8 is_deleted;
+};
+
+/***** The structure for non-rewritable-by-default file patterns. *****/
+
+struct no_rewrite_entry {
+ struct no_rewrite_entry *next;
+ const struct path_info *pattern;
+ u8 is_deleted;
+};
+
+/***** The structure for detailed write operations. *****/
+
+static struct {
+ const char *keyword;
+ const int paths;
+} acl_type_array[] = {
+ { "create", 1 }, /* TMY_TYPE_CREATE_ACL */
+ { "unlink", 1 }, /* TMY_TYPE_UNLINK_ACL */
+ { "mkdir", 1 }, /* TMY_TYPE_MKDIR_ACL */
+ { "rmdir", 1 }, /* TMY_TYPE_RMDIR_ACL */
+ { "mkfifo", 1 }, /* TMY_TYPE_MKFIFO_ACL */
+ { "mksock", 1 }, /* TMY_TYPE_MKSOCK_ACL */
+ { "mkblock", 1 }, /* TMY_TYPE_MKBLOCK_ACL */
...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:33 am

This patch makes access logs sent to auditing subsystem.
TOMOYO Linux uses two channels for auditing.
One is 'AUDIT_TMY_GRANTED', used for auditing accesses which are
granted in the TOMOYO Linux policy.
The other is 'AUDIT_TMY_REJECTED', used for auditing accesses which
are not granted in the TOMOYO Linux policy.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
include/linux/audit.h | 3 ++
security/tomoyo/audit.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/audit.c 2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,68 @@
+/*
+ * security/tomoyo/audit.c
+ *
+ * Audit functions for TOMOYO Linux
+ */
+
+#include "tomoyo.h"
+#include <linux/audit.h>
+
+/**
+ * tmy_init_audit_log - allocate and initialize audit buffer.
+ * @len: pointer to length of requested size.
+ *
+ * Returns pointer to audit buffer on success. @len received allocated size.
+ * Returns NULL on failure.
+ *
+ * @len must not be a NULL.
+ */
+char *tmy_init_audit_log(int *len)
+{
+ char *buf;
+ struct task_struct *task = current;
+ const char *domainname = TMY_SECURITY->domain->domainname->name;
+
+ *len += strlen(domainname) + 256;
+ buf = tmy_alloc(*len);
+
+ if (!buf)
+ return NULL;
+
+ snprintf(buf, (*len) - 1,
+ "pid=%d uid=%d gid=%d euid=%d egid=%d "
+ "suid=%d sgid=%d fsuid=%d fsgid=%d : %s : ",
+ task->pid, task->uid, task->gid, task->euid, task->egid,
+ task->suid, task->sgid, task->fsuid, task->fsgid, domainname);
+
+ return buf;
+}
+
+/**
+ * tmy_write_audit_log - write audit log.
+ * @buf: pointer to access log contents.
+ * @is_granted: is the access request granted?
+ * @is_enforce: is the access requested in enforcing mode?
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ *
+ * Wri...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:32 am

Domain transition functions for TOMOYO Linux.
Every process belongs to a domain in TOMOYO Linux.
Domain transition occurs when execve(2) is called
and the domain is expressed as 'process invocation history',
such as '<kernel> /sbin/init /etc/init.d/rc'.
Domain information is stored in task_struct->security.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/domain.c | 1256 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1256 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/domain.c 2007-10-02 11:26:21.000000000 +0900
@@ -0,0 +1,1256 @@
+/*
+ * security/tomoyo/domain.c
+ *
+ * Domain transition functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include <linux/highmem.h>
+#include <linux/binfmts.h>
+
+/************************* VARIABLES *************************/
+
+/* Lock for appending domain's ACL. */
+DECLARE_MUTEX(domain_acl_lock);
+
+/* Domain creation lock. */
+static DECLARE_MUTEX(new_domain_assign_lock);
+
+/***** The structure for program files to force domain reconstruction. *****/
+
+struct domain_initializer_entry {
+ struct domain_initializer_entry *next;
+ const struct path_info *domainname; /* This may be NULL */
+ const struct path_info *program;
+ u8 is_deleted;
+ u8 is_not;
+ u8 is_last_name;
+};
+
+/***** The structure for domains to not to transit domains. *****/
+
+struct domain_keeper_entry {
+ struct domain_keeper_entry *next;
+ const struct path_info *domainname;
+ const struct path_info *program; /* This may be NULL */
+ u8 is_deleted;
+ u8 is_not;
+ u8 is_last_name;
+};
+
+/***** The structure for program files that should be aggregated. *****/
+
+struct aggregator_entry {
+ struct aggregator_entry *next;
+ const struct path_info *original_name;
+ const struct path_info *aggregated_name;
+ u8 is_delet...

To: Kentaro Takeda <takedakn@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 7:15 am

Please use standard kernel list handling, per include/linux/list.h

Why do you need to avoid spinlocks for these manipulations?

- James
--
James Morris
<jmorris@namei.org>
-

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 8:44 am

Hello.

Thank you for your comment.

I don't need to use spinlocks here.
What I need to do here is avoid read/write reordering,
so mb() will be appropriate here.

struct something {
struct something *next;
void *data;
};

struct something *prev_ptr = ...;
struct something *new_ptr = kmalloc(sizeof(*new_ptr), GFP_KERNEL);
new_ptr->next = NULL;
new_ptr->data = some_value;
mb();
prev_ptr->next = new_ptr;

TOMOYO Linux doesn't use locks for reading singly-linked list.
Thus, new_ptr->data has to be made visible to other CPUs
before new_ptr is appended at the tail of singly-linked list.
Otherwise, other CPU may read undefined new_ptr->data values.

Performance is not critical because this mb() is called

Since new_ptr never be removed, new_ptr needn't to know
it's previous element's address, thus having only ->next pointer is enough.
new_ptr->next is assigned *only once*
(initialized with NULL, and assigned non-NULL later),
indicating "if ptr->next == NULL, ptr is the last element" and
"if ptr->next != NULL, ptr is not the last element".

If I use "struct hlist_node" which has two pointers,
it needs more memory than "struct something" which has one pointer.
It is possible to use API defined in include/linux/list.h ,
but to reduce memory usage, I dare not use these API.
Singly-linked list's rule in TOMOYO Linux is quite simple,
"ptr->next is NULL if the last element" and "non-NULL if not".

Regards.

-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 9:07 am

You're introducing a custom API, which is open-coded repeatedly throughout
your module.

All linked lists (at least, new ones) must use the standard kernel list

Most of these uses appear to be slow path or nested inside other locks,
while overall, performance is likely to be dominated by your string
matching and permission checking. Use of mb(), which is typically
considered less understandable, in this case does not appear to be
justified vs. normal locking, and you also need to use the standard list
API. If performance really is an issue, then consider RCU.

- James
--
James Morris
<jmorris@namei.org>
-

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 7:24 am

Hello.

It seems that standard kernel list API does not have singly-linked list manipulation.
I'm considering the following list manipulation API.

--- Start of code ---
#include <stdio.h>
#include <stdlib.h>

static inline void prefetch(const void *x) {;}
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );})

/*
* nphlist -- hlist with no pointer to previous
*/
struct nphlist_node {
struct nphlist_node *next;
};
struct nphlist_head {
struct nphlist_node *first;
};

#define NPHLIST_HEAD_INIT { .first = NULL }
#define NPHLIST_HEAD(name) struct nphlist_head name = NPHLIST_HEAD_INIT
#define INIT_NPHLIST_HEAD(ptr) ((ptr)->first = NULL)
#define INIT_NPHLIST_NODE(ptr) ((ptr)->next = NULL)

static inline void nphlist_add(struct nphlist_node *entry, struct nphlist_head *list) {
struct nphlist_node *ptr = list->first;
if (ptr) {
while (ptr->next)
ptr = ptr->next;
ptr->next = entry;
} else {
list->first = entry;
}
}

#define nphlist_entry(ptr, type, member) container_of(ptr,type,member)

/**
* nphlist_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct nph_list to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the nphlist_node within the struct.
*/
#define nphlist_for_each_entry(tpos, pos, head, member) \
for (pos = (head); \
pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = nphlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)

struct something {
struct nphlist_node next;
int v;
};

static NPHLIST_HEAD(data);

int main(int argc, char *argv[]) {
struct something *ptr;
struct nphlist_node *p;
int i;
for (i = 0; i < 10; i++) {
printf("add %d\...

To: <penguin-kernel@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>, <yoshfuji@...>
Date: Wednesday, October 3, 2007 - 7:43 am

Tstsuo, please name it "slist", which is well-known.

--yoshfuji
-

To: YOSHIFUJI Hideaki / <yoshfuji@...>
Cc: <penguin-kernel@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 8:37 am

On Wed, 3 Oct 2007, YOSHIFUJI Hideaki /

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>
Date: Monday, October 15, 2007 - 8:09 am

Hello.

OK. I posted new one that uses existing API at http://lkml.org/lkml/2007/10/11/140 .

By the way, what do you think of new primitives shown below?
I'd like to use list_for_each_cookie() and list_add_tail_mb() if acceptable.

----- Start of code -----
/********** Existing API **********/

#include <stdio.h>
#include <stdlib.h>

static inline void mb(void) {;}
static inline void prefetch(void *p) {;}
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );})
#define list_entry(ptr, type, member) container_of(ptr, type, member)

struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &name, &name }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)

/********** Proposed API **********/

/**
* list_for_each_cookie - iterate over a list with cookie.
* @pos: the &struct list_head to use as a loop cursor.
* @cookie: the &struct list_head to use as a cookie.
* @head: the head for your list.
*
* Same with list_for_each except that this primitive uses cookie
* so that we can continue iteration.
*/
#define list_for_each_cookie(pos, cookie, head) \
for ((cookie) || ((cookie) = (head)), pos = (cookie)->next; \
prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
(cookie) = pos, pos = pos->next)

/**
* list_add_tail_mb - add a new entry with memory barrier.
* @new: new entry to be added.
* @head: list head to add it before.
*
* Same with list_add_tail_rcu() except that this primitive uses mb()
* so that we can traverse forwards using list_for_each() and
* list_for_each_cookie().
*/
static inline void list_add_tail_mb(struct list_head *new,
struct list_head *head)
{
struct list_head *prev = head->prev;
struct list_head *next = head;...

To: <jmorris@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 9:04 am

Too bad...

Well, is there a way to avoid read_lock when reading list?

Currently, TOMOYO Linux avoids read_lock, on the assumption that
(1) First, ptr->next is initialized with NULL.
(2) Later, ptr->next is assigned non-NULL address.
(3) Assigning to ptr->next is done atomically.

Regards.

-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 9:14 am

Is it all of the purpose for the list structure?
If so, you can apply RCU instead to avoid read lock
when scanning the list, like:

rcu_read_lock();
list_for_each_entry(...) {
....
}
rcu_read_unlock();

--
KaiGai Kohei <kaigai@kaigai.gr.jp>
-

To: <kaigai@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 9:59 am

Hello.

Can I sleep between rcu_read_lock() and rcu_read_unlock() ?
As far as I saw, rcu_read_lock() makes in_atomic() true, so I think I can't sleep.

If I use RCU, I have to give up " [TOMOYO 13/15] Conditional permission support"
because tmy_check_condition() can sleep.

Regards.

-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:07 am

You can indeed not sleep in an rcu_read_lock() section. However, you
could grab a reference on an item, stop the iteration, drop
rcu_read_lock. Do you thing, re-acquire rcu_read_lock(), drop the ref,
and continue the iteration.

Also, how do you avoid referencing dead data with your sll? I haven't
actually looked at your patches, but the simple scheme you outlined
didn't handle the iteration + concurrent removal scenario:

thread 1 thread 2

foo = ptr->next

< schedule >

killme = ptr->next (same item)
ptr->next = ptr->next->next;
kfree(killme)

< schedule >

foo->bar <-- *BANG*

-

To: <a.p.zijlstra@...>
Cc: <linux-kernel@...>, <linux-security-module@...>
Date: Sunday, October 7, 2007 - 6:38 am

Hello.

Something like this?

rcu_read_lock();
list_for_each_rcu(p, ...) {
ptr = list_entry(p, struct ..., list);
/* Grab a reference to "ptr". */
rcu_read_unlock();
my_task_that_may_sleep(ptr);
rcu_read_lock();
/* Drop a reference to "ptr". */
}
rcu_read_unlock();

Regarding my case, memory region pointed by "ptr" never be removed.
Do I need to grab a reference to "ptr" ?

Regards.

-

To: <a.p.zijlstra@...>
Cc: <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:26 am

Regarding my singly-linked list, no entries are removed from the list. It's append only (like CD-R media).
I set is_deleted flag of a entry instead of removing the entry from the list.

Regards.

-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <a.p.zijlstra@...>, <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:37 am

Why so?

This smells like a horrible leaking of memory. How fast can the list grow
during the lifetime of the system?

--
Jiri Kosina
-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:26 am

sounds like a might fine memory leak / dos attack.

-

To: <penguin-kernel@...>
Cc: <a.p.zijlstra@...>, <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>, <yoshfuji@...>
Date: Wednesday, October 3, 2007 - 10:32 am

It is not a good practice. Please free such objects.
BTW, how many objects do you have in the list?

--yoshfuji
-

To: <yoshfuji@...>, <a.p.zijlstra@...>
Cc: <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:56 am

Hello.

It varies from 0 to some thousands,
depending on the policy supplied by the administrator and/or the policy appended by "learning mode".

TOMOYO Linux keeps the policy in CD-R's manner.
Thus, once an entry is written, it's pointer is valid forever.
TOMOYO Linux's simplicity (singly-linked list with no read_lock) comes from
this "keep the policy in CD-R's manner".
Yes, it is a kind of memory leak, but is controllable.

The kernel no longer requires memory after entering into "enforcing mode".
So, attackers can't do DoS attack after entering into "enforcing mode".

Regards.

-

To: <yoshfuji@...>, <a.p.zijlstra@...>
Cc: <kaigai@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Thursday, October 4, 2007 - 8:57 am

About use of singly-linked list:

What my SLL (singly-linked list) holds is bit different from other lists.

Almost all lists hold list of elements (e.g. buffer) that are used *temporarily*.
Thus, adding to the list and removing from the list are essential.

My SLL holds ACL (access control list) entries that are used *permanently*
(i.e. throughout the kernel's lifetime).
These ACL entries are policy used for MAC (mandatory access control).
You don't change MAC's policy without clear reason, do you?
Therefore, ACL entries of MAC's policy seldom need to be removed.

So I wonder
"Remodeling the mechanism of holding ACL entries to support removal of individual entry
worth the cost of reference-counter manipulation and the risk of dead-pointers?"

Your next question would be
"Why are you using SLL for holding elements that are used *permanently*?"
"Why not allocate a large memory block and hold all elements in that block?"
Yes, you are right. But I can't do so.
The reason is explained in "policy file handling" at http://lkml.org/lkml/2007/10/2/56 .

About use of list that can't remove elements:

I think that many of you are misunderstanding about
"When entries are automatically appended to a list".

If you run the system in "learning mode" *forever*,
it will consume all memory; so DoS attacks are possible.

But please be aware that entries are automatically appended
only while you are running the system in "learning mode".
Also, there is a safeguard mechanism that controls upper limit.
These lists consume less than some hundreds KB
for embedded systems and/or targeted protection of PC systems,
less than 1 MB for complete protection of PC systems.
You can see how much memory is used for holding ACL entries
via /sys/kernel/security/tomoyo/meminfo interface
and you will find that these lists won't consume all memory in your system.

When you are running the system in "enforcing mode",
no entries are appended automatically; so DoS attacks are impossible.

-

To: YOSHIFUJI Hideaki / <yoshfuji@...>
Cc: <penguin-kernel@...>, <a.p.zijlstra@...>, <kaigai@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:39 am

On Wed, 3 Oct 2007, YOSHIFUJI Hideaki /

To: Tetsuo Handa <penguin-kernel@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 9:24 am

(4) wmb after asigning ptr->next
(5) rmb before reading ptr->next

But please do look at the various rcu list primitives. RCU allows one to
avoid non-exclusive locks in many cases.

non-exclusive locks are evil, they must all die...

-

To: <a.p.zijlstra@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:19 am

Hello.

Thank you for pointing out.

Excuse me, but I didn't understand why (4) and (5) are needed.

append_function() {

down(semaphore_for_write_protect);
...
ptr = head;
while (ptr->next) ptr = ptr->next;
ptr->next = new_entry;
...
up(semaphore_for_write_protect);

}

read_function() {

for (ptr = head; ptr; ptr = ptr->next) {
...
}

}

Are (4) and (5) needed even when (3) is exclusively protected by down() and up() ?

Regards.

-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <a.p.zijlstra@...>, <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:35 am

It seems to me that this function alone is a reason to argue against
using a singly linked list. I know your patch doesn't actually contain
this as a function but it does use the same logic to append to your
lists. Does the overhead of the second pointer that the regular list
head uses outweigh the O(1) insertion and deletion it provides
(especially in your case)? I know domain transitions are rare but why
use something with O(N) insertion? This could be one reason why there
isn't an slist already in list.h

Dave Quigley

-

To: Tetsuo Handa <penguin-kernel@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Wednesday, October 3, 2007 - 10:28 am

the up() would do 4. 5 ensures another cpu will actually see it. Althoug
in practise the various cache invalidations driven by the workload will
ensure it will become visible eventually anyway.

-

To: <a.p.zijlstra@...>
Cc: <linux-kernel@...>, <linux-security-module@...>
Date: Monday, October 15, 2007 - 7:46 am

Hello.

Fixed in the fourth submission ( http://lkml.org/lkml/2007/10/11/140 ).

Thank you.

-

To: <penguin-kernel@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>, <yoshfuji@...>
Date: Wednesday, October 3, 2007 - 9:11 am

RCU?

--yoshfuji
-

To: James Morris <jmorris@...>
Cc: Tetsuo Handa <penguin-kernel@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 10:50 am

Really? Why? That rule is new to me.

Would also seem very limiting especially since the standard kernel lists
do not allow to express important patterns (like single linked lists)

I don't think that is a requirement.

-Andi
-

To: <penguin-kernel@...>
Cc: <jmorris@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>, <yoshfuji@...>
Date: Tuesday, October 2, 2007 - 9:00 am

Introducing your own list is not good.
Please use hlist or introduce new "slist".

--yoshfuji
-

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:31 am

Common functions for TOMOYO Linux.

TOMOYO Linux uses /sys/kernel/security/tomoyo interface for configuration.

/sys/kernel/security/tomoyo/domain_policy is the domain-based access policy.
Access control list for files, networks, argv[0] and signal is
stored in domain_policy.

/sys/kernel/security/tomoyo/system_policy is the system-wide access policy.
Access control list for mount, umount and pivot_root is
stored in system_policy.

/sys/kernel/security/tomoyo/exception_policy is the other settings such as
globally readable files, domain transition configurations
or pre-defined patterned pathnames.

/sys/kernel/security/tomoyo/profile has some profiles, which configure
the access control level of TOMOYO Linux. A profile is assigned to a domain.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/common.c | 2406 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 2406 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/common.c 2007-10-02 11:26:21.000000000 +0900
@@ -0,0 +1,2406 @@
+/*
+ * security/tomoyo/common.c
+ *
+ * Common functions for TOMOYO Linux.
+ */
+
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/utime.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <stdarg.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/security.h>
+#include "realpath.h"
+#include "tomoyo.h"
+
+#define MAX_ACCEPT_ENTRY 2048
+
+static int tmy_read_control(struct file *file,
+ char __user *buffer,
+ const int buffer_len);
+
+/************************* VARIABLES *************************/
+
+/* /sbin/init started? */
+int sbin_init_started;
+
+static struct {
+ const char *keyword;
+ unsigned int current_value;
+ const unsigned in...

To: Kentaro Takeda <takedakn@...>
Cc: <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 4:05 am

This seems like a bit of an abuse of sysfs. Isn't this precisely what
configfs is for?
-

To: Paul Mundt <lethal@...>, Kentaro Takeda <takedakn@...>, <linux-kernel@...>, <linux-security-module@...>, <chrisw@...>
Date: Tuesday, October 2, 2007 - 10:15 am

Possibly, but you can do the same thing in securityfs if needed.

thanks,

greg k-h
-

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:29 am

Data structures and prototype defitions for TOMOYO Linux.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/include/realpath.h | 44 +++
security/tomoyo/include/tomoyo.h | 517 +++++++++++++++++++++++++++++++++++++
2 files changed, 561 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/include/realpath.h 2007-10-02 11:26:21.000000000 +0900
@@ -0,0 +1,44 @@
+/*
+ * security/tomoyo/include/realpath.h
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO.
+ */
+
+#ifndef _TMY_REALPATH_H
+#define _TMY_REALPATH_H
+
+struct path_info;
+
+/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
+int tmy_realpath_dentry2(struct dentry *dentry,
+ struct vfsmount *mnt,
+ char *newname,
+ int newname_len);
+
+/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
+/* These functions use tmy_alloc(), so caller must tmy_free() */
+/* if these functions didn't return NULL. */
+char *tmy_realpath(const char *pathname);
+char *tmy_realpath_nofollow(const char *pathname);
+char *tmy_realpath_dentry(struct dentry *dentry, struct vfsmount *mnt);
+
+/* Allocate memory for structures. */
+/* The RAM is chunked, so NEVER try to kfree() the returned pointer. */
+void *tmy_alloc_element(const unsigned int size);
+
+/* Get used RAM size for tmy_alloc_elements(). */
+unsigned int tmy_get_memory_used_for_elements(void);
+
+/* Keep the given name on the RAM. */
+/* The RAM is shared, so NEVER try to modify or kfree() the returned name. */
+const struct path_info *tmy_save_name(const char *name);
+
+/* Get used RAM size for tmy_save_name(). */
+unsigned int tmy_get_memory_used_for_save_name(void);
+
+unsigned int tmy_get_memory_used_for_dynamic(void);
+char *sysctlpath_from_table(struct ctl_table *table);
+extern void tmy_realpath_init(void);
+
+#endif
--- /dev/null 1...

To: <linux-kernel@...>, <linux-security-module@...>
Cc: <chrisw@...>
Date: Tuesday, October 2, 2007 - 3:28 am

TOMOYO Linux uses pathnames for auditing and controlling file access.
Therefore, namespace_sem is needed.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
fs/namespace.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)

--- linux-2.6.orig/fs/namespace.c 2007-10-02 11:11:53.000000000 +0900
+++ linux-2.6/fs/namespace.c 2007-10-02 11:26:21.000000000 +0900
@@ -38,7 +38,7 @@ static int event;
static struct list_head *mount_hashtable __read_mostly;
static int hash_mask __read_mostly, hash_bits __read_mostly;
static struct kmem_cache *mnt_cache __read_mostly;
-static struct rw_semaphore namespace_sem;
+struct rw_semaphore namespace_sem;

/* /sys/fs */
decl_subsys(fs, NULL, NULL);

-

Previous thread: none

Next thread: [patch] menuconfig - lift the fs menu by Jan Engelhardt on Tuesday, October 2, 2007 - 9:51 am. (3 messages)