Re: [TOMOYO #6 retry 02/21] Add struct vfsmount to struct task_struct.

2008-01-16 Thread Kentaro Takeda
Serge:
> Right, but one will be preferred by the community - and while I have my
> own preference, I wouldn't put too much faith on that, rather talk with
> the apparmor folks, look over the lkml logs for previous submissions,
> and then decide.
Thanks for your advice.
We got the same advice from [EMAIL PROTECTED] in Embedded Linux Conference 2007,
and contacted AppArmor folks but no action occurred. We'll try to contact again.

John Johansen:
Both AppArmor and TOMOYO need vfsmount in LSM hooks. Although we suggested
another solution in [TOMOYO #6], we can use AppArmor's approach.
How about submitting only vfsmount patches before submitting AppArmor/TOMOYO
main module?

We think the patches relate to not only LSM folks but also fsdevel folks.
So we are going to post the brief description of the patches to fsdevel.

Regards,
Kentaro Takeda

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO #6 retry 02/21] Add struct vfsmount to struct task_struct.

2008-01-15 Thread Kentaro Takeda
Hello.

Serge E. Hallyn wrote:
> I must say I personally prefer the apparmor approach.
No problem.

> But I'd recommend
> you get together and get this piece pushed on its own, whichever version
> you can agree on.
TOMOYO can use AppArmor's patch.

> Yes it needs a user, but at this point I would think
> both tomoyo and apparmor have had enough visibility that everyone knows
> the intended users.
Not only AppArmor and TOMOYO but also SELinux want to use "vfsmount".
(http://marc.info/?l=selinux&m=120005904211942&w=2)

> It seems to me you're both being held up by this piece, and getting
> another full posting of either tomoyo or apparmor isn't going to help,
> so hopefully you can combine your efforts to get this solved.
We welcome AppArmor's vfsmount patches, but I wonder why AppArmor's
vfsmount patches are not merged yet.

What prevents AppArmor's vfsmount patches from merging into -mm tree?

Regards.
Kentaro Takeda

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO #6 retry 08/21] Utility functions and policy manipulation interface.

2008-01-08 Thread Kentaro Takeda
Hello.

James Morris wrote:
> Why aren't you using securityfs for this?  (It was designed for LSMs).
We are using securityfs mounted on /sys/kernel/security/ .
Thanks.

Kentaro Takeda

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO #6 retry 18/21] LSM adapter functions.

2008-01-08 Thread Kentaro Takeda
To avoid namespace_sem deadlock, this patch uses
"current->last_vfsmount" associated by wrapper functions.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/tomoyo.c |  825 +++
 1 file changed, 825 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/tomoyo.c
@@ -0,0 +1,825 @@
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * LSM hooks for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+#define MAX_SOCK_ADDR 128 /* net/socket.c */
+
+LIST_HEAD(domain_list);
+
+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 linux_binprm *bprm)
+{
+   struct domain_info *next_domain = NULL;
+   int retval = 0;
+
+   tmy_load_policy(bprm->filename);
+
+   /*
+* TMY_CHECK_READ_FOR_OPEN_EXEC bit indicates whether this function is
+* called by do_execve() or not.
+* If called by do_execve(), I do domain transition.
+*/
+   if (!(TMY_SECURITY->flags
+ & TMY_CHECK_READ_FOR_OPEN_EXEC)) {
+   retval = tmy_find_next_domain(bprm, &next_domain);
+   if (retval == 0) {
+   struct domain_info *domain = TMY_SECURITY->domain;
+   TMY_SECURITY->domain = next_domain;
+   retval = tmy_check_environ(bprm);
+   if (!retval)
+   TMY_SECURITY->flags |=
+   TMY_CHECK_READ_FOR_OPEN_EXEC;
+   else
+   TMY_SECURITY->domain = domain;
+   }
+   }
+
+   return retval;
+}
+
+static void tmy_bprm_post_apply_creds(struct linux_binprm *bprm)
+{
+   TMY_SECURITY->prev_domain = TMY_SECURITY->domain;
+}
+
+static void tmy_bprm_free_security(struct linux_binprm *bprm)
+{
+   TMY_SECURITY->domain = TMY_SECURITY->prev_domain;
+   TMY_SECURITY->flags &= ~TMY_CHECK_READ_FOR_OPEN_EXEC;
+}
+
+static int tmy_sysctl(struct ctl_table *table, int op)
+{
+   int error;
+   char *name;
+
+   if ((op & 6) == 0)
+   return 0;
+
+   name = sysctlpath_from_table(table);
+   if (!name)
+   return -ENOMEM;
+
+   error = tmy_file_perm(name, op & 6, "sysctl");
+   tmy_free(name);
+
+   return error;
+}
+
+static int tmy_inode_permission(struct inode *inode,
+   int mask,
+   struct nameidata *nd)
+{
+   int flag = 0;
+
+   if (S_ISDIR(inode->i_mode)) /* ignore because inode is directory */
+   return 0;
+   /*
+   if (!nd) {
+   printk("tmy_inode_permission: NULL nameidata\n");
+   dump_stack();
+   return 0;
+   } else if (!nd->mnt) {
+   printk("tmy_inode_permission: NULL vfsmount\n");
+   dump_stack();
+   return 0;
+   }
+   */
+   if (!nd || !nd->path.dentry || !nd->path.mnt)
+   return 0;
+   /*
+* If called by other than do_execve(), I check for read permission of
+* interpreter.
+* Unlike DAC, I don't check for read permission of pathname passed to
+* do_execve().
+* TOMOYO Linux checks for program's execute permission and
+* interpreter's read permission.
+*/
+   if ((mask == MAY_EXEC) &&
+   (TMY_SECURITY->flags & TMY_CHECK_READ_FOR_OPEN_EXEC))
+   mask = MAY_READ;
+   if ((mask == MAY_EXEC) || (mask == 0))
+   return 0;
+
+   if (mask == (MAY_READ | MAY_EXEC))
+   flag |= O_RDONLY + 1;
+   else {
+   if (mask & MAY_READ)
+   flag |= O_RDONLY + 1;
+   if (mask & MAY_WRITE)
+   flag |= O_WRONLY + 1;
+   if ((mask & MAY_APPEND))
+   flag |= O_APPEND;
+   }
+
+   return tmy_open_perm(nd->path.dentry, nd->path.mnt, flag);
+}
+
+static int tmy_do_single_write_perm(int operation, struct dentry *dentry)
+{
+   struct vfsmount *mnt = current->last_vfsmount;
+   if (!dentry || !mnt)
+

[TOMOYO #6 retry 21/21] Add signal hooks at sleepable location.

2008-01-08 Thread Kentaro Takeda
This patch adds 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

We know sleepable hooks are racy.
But we want to add sleepable hooks because TOMOYO Linux supports
"delayed enforcing" mode which allows administrator judge interactively.

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/security.h |   41 +
 kernel/signal.c  |   17 +
 security/dummy.c |   18 ++
 security/security.c  |   15 +++
 4 files changed, 91 insertions(+)

--- linux-2.6-mm.orig/include/linux/security.h
+++ linux-2.6-mm/include/linux/security.h
@@ -674,6 +674,25 @@ 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.
+ * Return 0 if permission is granted.
+ * @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.
+ * Return 0 if permission is granted.
+ * @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.
+ * Return 0 if permission is granted.
  * @task_wait:
  * Check permission before allowing a process to reap a child process @p
  * and collect its status information.
@@ -1364,6 +1383,9 @@ struct security_operations {
int (*task_movememory) (struct task_struct * p);
int (*task_kill) (struct task_struct * p,
  struct siginfo * info, int sig, u32 secid);
+   int (*task_kill_unlocked) (int pid, int sig);
+   int (*task_tkill_unlocked) (int pid, int sig);
+   int (*task_tgkill_unlocked) (int tgid, int pid, int sig);
int (*task_wait) (struct task_struct * p);
int (*task_prctl) (int option, unsigned long arg2,
   unsigned long arg3, unsigned long arg4,
@@ -1622,6 +1644,10 @@ int security_task_getscheduler(struct ta
 int security_task_movememory(struct task_struct *p);
 int security_task_kill(struct task_struct *p, struct siginfo *info,
int sig, u32 secid);
+#define __HAVE_LSM_TASK_KILL_UNLOCKED
+int security_task_kill_unlocked(int pid, int sig);
+int security_task_tkill_unlocked(int pid, int sig);
+int security_task_tgkill_unlocked(int tgid, int pid, int sig);
 int security_task_wait(struct task_struct *p);
 int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
 unsigned long arg4, unsigned long arg5);
@@ -2168,6 +2194,21 @@ static inline int security_task_kill (st
return cap_task_kill(p, info, sig, secid);
 }
 
+static inline int security_task_kill_unlocked(int pid, int sig)
+{
+   return 0;
+}
+
+static inline int security_task_tkill_unlocked(int pid, int sig)
+{
+   return 0;
+}
+
+static inline int security_task_tgkill_unlocked(int tgid, int pid, int sig)
+{
+   return 0;
+}
+
 static inline int security_task_wait (struct task_struct *p)
 {
return 0;
--- linux-2.6-mm.orig/kernel/signal.c
+++ linux-2.6-mm/kernel/signal.c
@@ -2219,6 +2219,11 @@ asmlinkage long
 sys_kill(int pid, int sig)
 {
struct siginfo info;
+   int ret;
+
+   ret = security_task_kill_unlocked(pid, sig);
+   if (ret)
+   return ret;
 
info.si_signo = sig;
info.si_errno = 0;
@@ -2274,10 +2279,16 @@ static int do_tkill(int tgid, int pid, i
  */
 asmlinkage long sys_tgkill(int tgid, int pid, int sig)
 {
+   int ret;
+
/* This is only valid for single tasks */
if (pid <= 0 || tgid <= 0)
return -EINVAL;
 
+   ret = security_task_tgkill_unlocked(tgid, pid, sig);
+   if (ret)
+   return ret;
+
return do_tkill(tgid, pid, sig);
 }
 
@@ -2287,10 +2298,16 @@ asmlinkage long sys_tgkill(int tgid, int
 asmlinkage long
 sys_tkill(int pid, int sig)
 {
+   int ret;
+
/* This is only valid for single tasks */
if (pid <= 0)
return -EINVAL;
 
+   ret = security_task_tkill_unlocked(pid, sig);
+   if (ret)
+   return ret;
+
return do_tkill(0, pid, sig);

[TOMOYO #6 retry 19/21] Conditional permission support.

2008-01-08 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/condition.c |  684 
 1 file changed, 684 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/condition.c
@@ -0,0 +1,684 @@
+/*
+ * 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) /* 00 */
+   return 0;
+   *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 buffer_len,
+   const unsigned long value, const int type)
+{
+   if (type == VALUE_TYPE_DECIMAL)
+   snprintf(buffer, buffer_len, "%lu", value);
+   else if (type == VALUE_TYPE_OCTAL)
+   snprintf(buffer, buffer_len, "0%lo", value);
+   else
+   snprintf(buffer, buffer_len, "0x%lX", value);
+}
+
+/* List of conditins. */
+static struct condition_list {
+   struct condition_list *next;
+   int length;
+   /* "unsigned long condition[length]" comes here.*/
+} head;
+
+#define TASK_UID  0
+#define TASK_EUID 1
+#define TASK_SUID 2
+#define TASK_FSUID3
+#define TASK_GID  4
+#define TASK_EGID 5
+#define TASK_SGID 6
+#define TASK_FSGID7
+#define TASK_PID  8
+#define TASK_PPID 9
+#define PATH1_UID10
+#define PATH1_GID11
+#define PATH1_INO12
+#define PATH1_PARENT_UID 13
+#define PATH1_PARENT_GID 14
+#define PATH1_PARENT_INO 15
+#define PATH2_PARENT_UID 16
+#define PATH2_PARENT_GID 17
+#define PATH2_PARENT_INO 18
+#define MAX_KEYWORD  19
+
+static struct {
+   const char *keyword;
+   const int keyword_len; /* strlen(keyword) */
+} cc_keyword[MAX_KEYWORD] = {
+   [TASK_UID] = { "task.uid",   8 },
+   [TASK_EUID]= { "task.euid",  9 },
+   [TASK_SUID]= { "task.suid",  9 },
+   [TASK_FSUID]   = { "task.fsuid",10 },
+   [TASK_GID] = { "task.gid",   8 },
+   [TASK_EGID]= { "task.egid",  9 },
+   [TASK_SGID]= { "task.sgid",  9 },
+   [TASK_FSGID]   = { "task.fsgid",10 },
+   [TASK_PID] = { "task.pid",   8 },
+   [TASK_PPID]= { "task.ppid",  9 },
+   [PATH1_UID]= { "path1.uid",  9 },
+   [PATH1_GID]= { "path1.gid",  9 },
+   [PATH1_INO]= { "path1.ino",  9 },
+   [PATH1_PARENT_UID] = { "path1.parent.uid",  16 },
+   [PATH1_PARENT_GID] = { "path1.parent.gid",  16 },
+   [PATH1_PARENT_INO] = { "path1.parent.ino",  16 },
+   [PATH2_PARENT_UID] = { "path2.parent.uid",  16 },
+   [PATH2_PARENT_GID] = { "path2.parent.gid",  16 },
+   [PATH2_PARENT_INO] = { "path2.parent.ino",  16 }
+};
+
+/**
+ * tmy_assign_condition - create condition part.
+ * @condition: pointer to c

[TOMOYO #6 retry 20/21] Kconfig and Makefile

2008-01-08 Thread Kentaro Takeda
TOMOYO Linux is placed in security/tomoyo .

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/Kconfig |1 +
 security/Makefile|1 +
 security/tomoyo/Kconfig  |   26 ++
 security/tomoyo/Makefile |2 ++
 4 files changed, 30 insertions(+)

--- linux-2.6-mm.orig/security/Kconfig
+++ linux-2.6-mm/security/Kconfig
@@ -105,6 +105,7 @@ config SECURITY_ROOTPLUG
 
 source security/selinux/Kconfig
 source security/smack/Kconfig
+source security/tomoyo/Kconfig
 
 endmenu
 
--- linux-2.6-mm.orig/security/Makefile
+++ linux-2.6-mm/security/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_SECURITY_SELINUX)+= selin
 obj-$(CONFIG_SECURITY_SMACK)   += commoncap.o smack/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/
--- /dev/null
+++ linux-2.6-mm/security/tomoyo/Kconfig
@@ -0,0 +1,26 @@
+config SECURITY_TOMOYO
+   bool "TOMOYO Linux support"
+   depends on SECURITY
+   select SECURITY_NETWORK
+   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.
+
+config SECURITY_TOMOYO_USE_AUDITD
+   bool "Use standard auditing subsystem"
+   depends on SECURITY_TOMOYO && AUDIT
+   default y
+   help
+ This makes messages sent to auditing subsystem.
+
+ If you say 'N' here, messages will be sent to printk().
--- /dev/null
+++ linux-2.6-mm/security/tomoyo/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo.o domain.o common.o realpath.o audit.o 
file.o exec.o environ.o net.o mount.o signal.o capability.o condition.o
+EXTRA_CFLAGS += -Isecurity/tomoyo/include

-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO #6 retry 17/21] Capability access control functions.

2008-01-08 Thread Kentaro Takeda
TOMOYO Linux checks permission for non-POSIX capability
so that the number of capabilities won't be limited to 32 or 64.

TOMOYO Linux uses per-a-domain capability, an approach that associate
capabilities with each domain, and assign a domain for each process.

The advantages of this approach are that

(1) minimum capabilities required for a process is directly given
compared to setting/clearing/inheriting bit fields of a process's
capability value.

(2) it can support as many types of capabilities as you want
without consuming much memory because you don't need to allocate
memory for per-a-task basis.

Although current implementation can handle up to 65536 types of capabilities.
we don't have enough hooks for checking/distinguishing
"What operation is requested.".
Therefore, some of capabilities defined in this module doesn't work.
We want to insert a new hook like operation_capable(syscall_number)
so that we can have enough hooks for checking/distinguishing requests.

May be system call auditing mechanism helps distinguish operations that are
all-combined into capable(CAP_SYS_ADMIN) operation. But to use it,
we think we have to enable system call auditing for all processes,
which may cause performance and log flooding problem?

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/capability.c |  320 +++
 1 file changed, 320 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/capability.c
@@ -0,0 +1,320 @@
+/*
+ * security/tomoyo/capability.c
+ *
+ * Capability access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+static struct {
+   const char *keyword;
+   unsigned int current_value;
+   const char *capability_name;
+} capability_control_array[TMY_MAX_CAPABILITY_INDEX] = {
+   [TMY_INET_STREAM_SOCKET_CREATE]  = /* OK */
+   { "inet_tcp_create", 0, "socket(PF_INET, SOCK_STREAM)" },
+   [TMY_INET_STREAM_SOCKET_LISTEN]  = /* OK */
+   { "inet_tcp_listen", 0, "listen(PF_INET, SOCK_STREAM)" },
+   [TMY_INET_STREAM_SOCKET_CONNECT] = /* OK */
+   { "inet_tcp_connect", 0, "connect(PF_INET, SOCK_STREAM)" },
+   [TMY_USE_INET_DGRAM_SOCKET]  = /* OK */
+   { "use_inet_udp", 0, "socket(PF_INET, SOCK_DGRAM)" },
+   [TMY_USE_INET_RAW_SOCKET]= /* OK */
+   { "use_inet_ip", 0, "socket(PF_INET, SOCK_RAW)" },
+   [TMY_USE_ROUTE_SOCKET]   = /* OK */
+   { "use_route", 0, "socket(PF_ROUTE)" },
+   [TMY_USE_PACKET_SOCKET]  = /* OK */
+   { "use_packet", 0, "socket(PF_PACKET)" },
+   [TMY_SYS_MOUNT]  = /* OK */
+   { "SYS_MOUNT", 0, "sys_mount()" },
+   [TMY_SYS_UMOUNT] = /* OK */
+   { "SYS_UMOUNT", 0, "sys_umount()" },
+   [TMY_SYS_REBOOT] = /* Too many hooks. */
+   { "SYS_REBOOT", 0, "sys_reboot()" },
+   [TMY_SYS_CHROOT] = /* OK */
+   { "SYS_CHROOT", 0, "sys_chroot()" },
+   [TMY_SYS_KILL]   = /* No appropriate hook. */
+   { "SYS_KILL", 0, "sys_kill()" },
+   [TMY_SYS_VHANGUP]= /* Too many hooks. */
+   { "SYS_VHANGUP", 0, "sys_vhangup()" },
+   [TMY_SYS_SETTIME]= /* Too many hooks. */
+   { "SYS_TIME", 0, "sys_settimeofday()" },
+   [TMY_SYS_NICE]   = /* No appropriate hook. */
+   { "SYS_NICE", 0, "sys_nice()" },
+   [TMY_SYS_SETHOSTNAME]= /* No appropriate hook. */
+   { "SYS_SETHOSTNAME", 0, "sys_sethostname()" },
+   [TMY_USE_KERNEL_MODULE]  = /* Too many hooks. */
+   { "use_kernel_module", 0, "kernel_module" },
+   [TMY_CREATE_FIFO]= /* OK */
+   { "create_fifo", 0, "mknod(FIFO)" },
+   [TMY_CREATE_BLOCK_DEV]   = /* OK */
+   { "create_block_dev", 0, "mknod(BDEV)" },
+   [TMY_CREATE_CHAR_DEV]= /* OK */
+   { "create_char_dev", 0, "mknod(CDEV)" },
+   [TMY_CREATE_UNIX_SOCKET] = /* OK */
+   { "create_unix_socket", 0, "mknod(SOCKET)" },
+   [TMY_SYS_LINK]   = /* OK */
+   { "SYS_LINK", 0, "sys_link()" },
+   [TMY_SYS_SYMLINK]= /* OK */
+   { "SYS_SYMLINK", 0, "sys_s

[TOMOYO #6 retry 15/21] Namespace manipulation control functions.

2008-01-08 Thread Kentaro Takeda
TOMOYO Linux checks mount permission based on
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/mount.c |  908 
 1 file changed, 908 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/mount.c
@@ -0,0 +1,908 @@
+/*
+ * security/tomoyo/mount.c
+ *
+ * Mount access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.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 list_head list;
+   const struct path_info *dev_name;
+   const struct path_info *dir_name;
+   const struct path_info *fs_type;
+   unsigned int flags; /* Mount flags. */
+   bool is_deleted;
+};
+
+struct no_umount_entry {
+   struct list_head list;
+   const struct path_info *dir;
+   bool is_deleted;
+};
+
+/  MOUNT RESTRICTION HANDLER  /
+
+static LIST_HEAD(mount_list);
+
+/* Add or remove a mount entry. */
+static int tmy_add_mount_acl(const char *dev_name,
+const char *dir_name,
+const char *fs_type,
+const unsigned int flags,
+const bool is_delete)
+{
+   struct mount_entry *new_entry;
+   struct mount_entry  *ptr;
+   const struct path_info *fs;
+   const struct path_info *dev;
+   const struct path_info *dir;
+   static DEFINE_MUTEX(mutex);
+   int error = -ENOMEM;
+
+   fs = tmy_save_name(fs_type);
+   if (!fs)
+   return -EINVAL;
+
+   if (!dev_name)
+   /* Map dev_name to "" for if no dev_name given. */
+   dev_name = "";
+   if (strcmp(fs->name, MOUNT_REMOUNT_KEYWORD) == 0)
+   /* Fix dev_name to "any" for remount permission. */
+   dev_name = "any";
+   if (strcmp(fs->name, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0)
+   dev_name = "any";
+
+   if (!tmy_correct_path(dev_name, 0, 0, 0, __FUNCTION__) ||
+   !tmy_correct_path(dir_name, 0, 0, 0, __FUNCTION__))
+   return -EINVAL;
+
+   dev = tmy_save_name(dev_name);
+   if (!dev)
+   return -ENOMEM;
+   dir = tmy_save_name(dir_name);
+   if (!dir)
+   return -ENOMEM;
+
+   mutex_lock(&mutex);
+
+   list_for_each_entry(ptr, &mount_list, list) {
+   if (ptr->flags != flags ||
+   tmy_pathcmp(ptr->dev_name, dev) ||
+   tmy_pathcmp(ptr->dir_name, dir) ||
+   tmy_pathcmp(ptr->fs_type, fs))
+   continue;
+   ptr->is_deleted = is_delete;
+   error = 0;
+   goto out;
+   }
+
+   if (is_delete) {
+   error = -ENOENT;
+   goto out;
+   }
+
+   new_entry = tmy_alloc_element(sizeof(*new_entry));
+   if (!new_entry)
+   goto out;
+
+   new_entry->dev_name = dev;
+   new_entry->dir_name = dir;
+   new_entry->fs_type = fs;
+   new_entry->flags = flags;
+   list_add_tail_mb(&new_entry->list, &mount_list);
+   error = 0;
+out: ;
+   mutex_unlock(&mutex);
+   return error;
+}
+
+/* Print error message for mount request. */
+static inline int tmy_mount_perm_error(char *dev_name,
+  char *dir_name,
+  char *type,
+  unsigned long flags,
+  const u8 profile,
+  const unsigned int mode)
+{
+   int error = -EPERM;
+   const char *realname1 = tmy_realpath(dev_name);
+   const char *realname2 = tmy_realpath(dir_name);
+   const char *exename = tmy_get_exe();
+   const bool is_enforce = (mode == 3);
+
+  

[TOMOYO #6 retry 16/21] Signal control functions.

2008-01-08 Thread Kentaro Takeda
TOMOYO Linux checks sending signal by signal number and
the domain of target process. In order to check signal
permission, modification against kernel/signal.c is needed.

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/signal.c |  226 +++
 1 file changed, 226 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/signal.c
@@ -0,0 +1,226 @@
+/*
+ * 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 bool is_granted,
+   const u8 profile,
+   const unsigned int mode)
+{
+   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, profile, mode);
+
+   if (!buf)
+   return -ENOMEM;
+
+   tmy_sncatprintf(buf, len - 1, "%s%d %s\n",
+   TMY_ALLOW_SIGNAL, signal, dest_domain->name);
+
+   return tmy_write_audit_log(buf, is_granted);
+}
+
+/*  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 bool is_delete)
+{
+   struct acl_info *ptr;
+   struct signal_acl *acl;
+   const struct path_info *saved_dest_pattern;
+   int error = -ENOMEM;
+
+   if (!domain)
+   return -EINVAL;
+   if (!dest_pattern ||
+   !tmy_is_correct_domain(dest_pattern, __FUNCTION__))
+   return -EINVAL;
+
+   saved_dest_pattern = tmy_save_name(dest_pattern);
+   if (!saved_dest_pattern)
+   return -ENOMEM;
+
+   mutex_lock(&domain_acl_lock);
+
+   if (is_delete)
+   goto remove;
+
+   list_for_each_entry(ptr, &domain->acl_info_list, list) {
+   acl = container_of(ptr, struct signal_acl, head);
+
+   if (ptr->type == TMY_TYPE_SIGNAL_ACL && acl->sig == sig
+   && ptr->cond == cond
+   && !tmy_pathcmp(acl->domainname, saved_dest_pattern)) {
+   ptr->is_deleted = 0;
+   /* Found. Nothing to do. */
+   error = 0;
+   goto ok;
+   }
+   }
+   /* Not found. Append it to the tail. */
+   acl = tmy_alloc_element(sizeof(*acl));
+   if (!acl)
+   goto ok;
+
+   acl->head.type = TMY_TYPE_SIGNAL_ACL;
+   acl->head.cond = cond;
+   acl->sig = sig;
+   acl->domainname = saved_dest_pattern;
+   error = tmy_add_acl(domain, &acl->head);
+   goto ok;
+remove: ;
+   error = -ENOENT;
+   list_for_each_entry(ptr, &domain->acl_info_list, list) {
+   acl = container_of(ptr, struct signal_acl, head);
+   if (ptr->type != TMY_TYPE_SIGNAL_ACL || ptr->cond != cond ||
+   ptr->is_deleted || acl->sig != sig ||
+   tmy_pathcmp(acl->domainname, saved_dest_pattern))
+   continue;
+   error = tmy_del_acl(ptr);
+   break;
+   }
+
+ok: ;
+   mutex_unlock(&domain_acl_lock);
+
+   return error;
+}
+
+/**
+ * tmy_signal_acl - check permission for kill(2)/tkill(2)/tgkill(2).
+ * @sig:  signal number.
+ * @pid:  pid of destination process.
+ *
+ * Returns zero if permission granted.
+ * Returns nonzero if permission denied.
+ */
+int tmy_signal_acl(const int sig, const int pid)
+{
+   struct domain_info *domain = TMY_SECURITY->domain;
+   struct domain_info *dest = NULL;
+   const char *dest_pattern;
+   struct acl_info *ptr;
+   const u16 hash = sig;
+   const u8 profile = domain->profile;
+   const unsigned int mode = tmy_flags(TMY_MAC_FOR_SIGNAL);
+   const bool is_enforce = (mode == 3);
+   bool found = 0;
+
+   if (!mode)
+   return 0;
+   if (!sig)
+   return 0; /* No check for NULL signal. */
+   if (current->pid == pid) {
+   tmy_audit_signal_log(sig, domain->domain

[TOMOYO #6 retry 13/21] environment variable name check functions.

2008-01-08 Thread Kentaro Takeda
TOMOYO Linux checks environment variable's names passed to execve()
because some envorinment variables affects to the behavior of program
like argv[0].

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/environ.c |  274 ++
 1 file changed, 274 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/environ.c
@@ -0,0 +1,274 @@
+/*
+ * security/tomoyo/environ.c
+ *
+ * Environment variable access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/*  AUDIT FUNCTIONS  */
+
+static int tmy_audit_env_log(const char *env,
+const bool is_granted,
+const u8 profile,
+const unsigned int mode)
+{
+   char *buf;
+   int len;
+
+   if (is_granted) {
+   if (!tmy_audit_grant())
+   return 0;
+   } else {
+   if (!tmy_audit_reject())
+   return 0;
+   }
+
+   len = strlen(env) + 8;
+   buf = tmy_init_audit_log(&len, profile, mode);
+
+   if (!buf)
+   return -ENOMEM;
+
+   tmy_sncatprintf(buf, len - 1, TMY_ALLOW_ENV "%s", env);
+
+   return tmy_write_audit_log(buf, is_granted);
+}
+
+/* The structure for globally usable environments. */
+
+struct globally_usable_env_entry {
+   struct list_head list;
+   const struct path_info *env;
+   bool is_deleted;
+};
+
+/***  GLOBALLY USABLE ENVIRONMENT HANDLER  
/
+
+static LIST_HEAD(globally_usable_env_list);
+
+static int tmy_add_globally_usable_env_entry(const char *env,
+const bool is_delete)
+{
+   struct globally_usable_env_entry *new_entry;
+   struct globally_usable_env_entry *ptr;
+   static DEFINE_MUTEX(lock);
+   const struct path_info *saved_env;
+   int error = -ENOMEM;
+   if (!tmy_correct_path(env, 0, 0, 0, __FUNCTION__))
+   return -EINVAL;
+   saved_env = tmy_save_name(env);
+   if (!saved_env)
+   return -ENOMEM;
+   mutex_lock(&lock);
+   list_for_each_entry(ptr, &globally_usable_env_list, list) {
+   if (ptr->env == saved_env) {
+   ptr->is_deleted = is_delete;
+   error = 0;
+   goto out;
+   }
+   }
+   if (is_delete) {
+   error = -ENOENT;
+   goto out;
+   }
+   new_entry = tmy_alloc_element(sizeof(*new_entry));
+   if (!new_entry)
+   goto out;
+   new_entry->env = saved_env;
+   list_add_tail_mb(&new_entry->list, &globally_usable_env_list);
+   error = 0;
+out:
+   mutex_unlock(&lock);
+   return error;
+}
+
+static bool tmy_is_globally_usable_env(const struct path_info *env)
+{
+   struct globally_usable_env_entry *ptr;
+   list_for_each_entry(ptr, &globally_usable_env_list, list) {
+   if (!ptr->is_deleted && tmy_path_match(env, ptr->env))
+   return 1;
+   }
+   return 0;
+}
+
+int tmy_add_globally_usable_env_policy(char *env, const bool is_delete)
+{
+   return tmy_add_globally_usable_env_entry(env, is_delete);
+}
+
+int tmy_read_globally_usable_env_policy(struct io_buffer *head)
+{
+   struct list_head *pos;
+   list_for_each_cookie(pos, head->read_var2, &globally_usable_env_list) {
+   struct globally_usable_env_entry *ptr;
+   ptr = list_entry(pos, struct globally_usable_env_entry, list);
+   if (ptr->is_deleted)
+   continue;
+   if (tmy_io_printf(head, TMY_ALLOW_ENV "%s\n",
+ ptr->env->name))
+   return -ENOMEM;
+   }
+   return 0;
+}
+
+/**  ENVIRONMENT VARIABLE Checking HANDLER  
***/
+
+static int tmy_add_env_entry(const char *env,
+struct domain_info *domain,
+const struct condition_list *cond,
+const bool is_delete)
+{
+   struct acl_info *ptr;
+   struct env_acl *acl;
+   const struct path_info *saved_env;
+   int error = -ENOMEM;
+
+   if (!tmy_correct_path(env, 0, 0, 0, __FUNCTION__))
+   return -EINVAL;
+
+   saved_env = tmy_save_name(env);
+   if (!saved_env)
+   return -ENOMEM;
+   if (!is_delete && tmy_is_globally_usable_env(saved_env))
+   return 0;
+
+   mutex_lock(&domain_acl_lock);
+
+   

[TOMOYO #6 retry 14/21] Network access control functions.

2008-01-08 Thread Kentaro Takeda
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',
modification against net/socket.c and net/core/datagram.c is needed.

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/net.c |  934 ++
 1 file changed, 934 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/net.c
@@ -0,0 +1,934 @@
+/*
+ * security/tomoyo/net.c
+ *
+ * Network access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/*  AUDIT FUNCTIONS  */
+
+static int tmy_audit_network_log(const bool is_ipv6,
+const char *operation,
+const u8 *address,
+const u16 port,
+const bool is_granted,
+const u8 profile,
+const unsigned int mode)
+{
+   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, profile, mode);
+   if (!buf)
+   return -ENOMEM;
+
+   tmy_sncatprintf(buf, len - 1, TMY_ALLOW_NETWORK "%s ", operation);
+
+   if (is_ipv6)
+   tmy_print_ipv6(buf + strlen(buf), len - strlen(buf),
+  (const struct in6_addr *) address);
+   else {
+   u32 ip = *address;
+   tmy_sncatprintf(buf, len - 1, NIPQUAD_FMT, NIPQUAD(ip));
+   }
+
+   tmy_sncatprintf(buf, len - 1, " %u\n", port);
+
+   return tmy_write_audit_log(buf, is_granted);
+}
+
+/*  UTILITY FUNCTIONS  */
+
+static const struct in6_addr *tmy_save_ipv6_address(const struct in6_addr 
*addr)
+{
+   static const int block_size = 16;
+   struct addr_list {
+   struct in6_addr addr[block_size];
+   struct addr_list *next;
+   u32 in_use_count;
+   };
+   static struct addr_list *list;
+   struct addr_list *ptr;
+   static DEFINE_MUTEX(lock);
+   int i = block_size;
+   if (!addr)
+   return NULL;
+   mutex_lock(&lock);
+   for (ptr = list; ptr; ptr = ptr->next) {
+   for (i = 0; i < ptr->in_use_count; i++)
+   if (memcmp(&ptr->addr[i], addr, sizeof(*addr)) == 0)
+   goto out;
+   if (i < block_size)
+   break;
+   }
+   if (i == block_size) {
+   struct addr_list *p = list;
+   ptr = tmy_alloc_element(sizeof(*ptr));
+   if (!ptr)
+   goto out;
+   if (p) {
+   while (p->next)
+   p = p->next;
+   p->next = ptr;
+   } else
+   list = ptr;
+   i = 0;
+   }
+   ptr->addr[ptr->in_use_count++] = *addr;
+out:
+   mutex_unlock(&lock);
+   return ptr ? &ptr->addr[i] : NULL;
+}
+
+/*  ADDRESS GROUP HANDLER  */
+
+/* List of address group. */
+static LIST_HEAD(address_group_list);
+
+static int tmy_add_address_group_entry(const char *group_name,
+  const bool is_ipv6,
+  const u8 *min_address,
+  const u8 *max_address,
+  const bool is_delete)
+{
+   static DEFINE_MUTEX(mutex);
+   struct address_group_entry *new_group;
+   struct address_group_entry *group;
+   struct address_group_member *new_member;
+   struct address_group_member *member;
+   const struct path_info *saved_group_name;
+   int error = -ENOMEM;
+   bool found = 0;
+   const u32 min_ip = ntohl(*(u32 *) min_address);
+   const u32 max_ip = ntohl(*(u32 *) max_address);
+   const struct in6_addr *saved_min_address = NULL;
+   const struct in6_addr *saved_max_address = NULL;
+   if (is_ipv6) {
+   saved_min_address =
+   tmy_save_ipv6_address((struct in6_addr *) min_address);
+   saved_max_address =
+   tmy_save_ipv6_address((struct in6_addr *) max

[TOMOYO #6 retry 11/21] File access control functions.

2008-01-08 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/file.c | 1468 +
 1 file changed, 1468 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/file.c
@@ -0,0 +1,1468 @@
+/*
+ * 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 list_head list;
+   const struct path_info *filename;
+   bool is_deleted;
+};
+
+/* The structure for filename patterns. */
+
+struct pattern_entry {
+   struct list_head list;
+   const struct path_info *pattern;
+   bool is_deleted;
+};
+
+/* The structure for non-rewritable-by-default file patterns. */
+
+struct no_rewrite_entry {
+   struct list_head list;
+   const struct path_info *pattern;
+   bool 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 */
+   { "mkchar",   1 }, /* TMY_TYPE_MKCHAR_ACL */
+   { "truncate", 1 }, /* TMY_TYPE_TRUNCATE_ACL */
+   { "symlink",  1 }, /* TMY_TYPE_SYMLINK_ACL */
+   { "link", 2 }, /* TMY_TYPE_LINK_ACL */
+   { "rename",   2 }, /* TMY_TYPE_RENAME_ACL */
+   { "rewrite",  1 }, /* TMY_TYPE_REWRITE_ACL */
+   { NULL, 0 }
+};
+
+/*  UTILITY FUNCTIONS  */
+
+/**
+ * tmy_acltype2keyword - get keyword from access control index.
+ * @acl_type: index number.
+ *
+ * Returns keyword that corresponds with @acl_type .
+ */
+const char *tmy_acltype2keyword(const unsigned int acl_type)
+{
+   return (acl_type < ARRAY_SIZE(acl_type_array))
+   ? acl_type_array[acl_type].keyword : NULL;
+}
+
+/**
+ * tmy_acltype2paths - get number of arguments from access control index.
+ * @acl_type: index number.
+ *
+ * Returns number of arguments that corresponds with @acl_type .
+ */
+int tmy_acltype2paths(const unsigned int acl_type)
+{
+   return (acl_type < ARRAY_SIZE(acl_type_array))
+   ? acl_type_array[acl_type].paths : 0;
+}
+
+static int tmy_strendswith(const char *name, const char *tail)
+{
+   int len;
+
+   if (!name || !tail)
+   return 0;
+
+   len = strlen(name) - strlen(tail);
+   return len >= 0 && strcmp(name + len, tail) == 0;
+}
+
+static struct path_info *tmy_get_path(struct dentry *dentry,
+ struct vfsmount *mnt)
+{
+   /* sizeof(struct path_info_with_data) <= PAGE_SIZE */
+   struct path_info_with_data {
+   /* Keep this first, this pointer is passed to tmy_free(). */
+   struct path_info head;
+   char bariier1[16];
+   char body[TMY_MAX_PATHNAME_LEN];
+   char barrier2[16];
+   } *buf = tmy_alloc(sizeof(*buf));
+
+   if (buf) {
+   int error = tmy_realpath_dentry2(dentry,
+mnt,
+buf->body,
+sizeof(buf->body) - 1);
+
+   if (error == 0) {
+   buf->head.name = buf->body;
+   tmy_fill_path_info(&buf->head);
+   return &buf->head;
+   }
+
+   tmy_free(buf);
+   buf = NULL;
+   printk(KERN_INFO "tmy_realpath_dentry = %d\n", error);
+   }
+
+   return NULL;
+}
+
+/*  PROTOTYPES  */
+
+static int tmy_add_double_write_acl(const u8 type,
+   const char *filename1,
+   const char *filename2,
+   struct domain_info * const doma

[TOMOYO #6 retry 12/21] argv0 check functions.

2008-01-08 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/exec.c |  215 +
 1 file changed, 215 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/exec.c
@@ -0,0 +1,215 @@
+/*
+ * 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 bool is_granted,
+  const u8 profile,
+  const unsigned int mode)
+{
+   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, profile, mode);
+
+   if (!buf)
+   return -ENOMEM;
+
+   tmy_sncatprintf(buf, len - 1, TMY_ALLOW_ARGV0 "%s %s",
+   filename->name, argv0);
+
+   return tmy_write_audit_log(buf, is_granted);
+}
+
+/*  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 bool is_delete)
+{
+   struct acl_info *ptr;
+   struct argv0_acl *acl;
+   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, 0, -1, __FUNCTION__) ||
+   strchr(argv0, '/'))
+   return -EINVAL;
+
+   saved_filename = tmy_save_name(filename);
+   saved_argv0 = tmy_save_name(argv0);
+   if (!saved_filename || !saved_argv0)
+   return -ENOMEM;
+
+   mutex_lock(&domain_acl_lock);
+
+   if (is_delete)
+   goto remove;
+
+   list_for_each_entry(ptr, &domain->acl_info_list, list) {
+   acl = container_of(ptr, struct argv0_acl, head);
+   if (ptr->type == TMY_TYPE_ARGV0_ACL && ptr->cond == cond &&
+   acl->filename == saved_filename &&
+   acl->argv0 == saved_argv0) {
+   ptr->is_deleted = 0;
+   /* Found. Nothing to do. */
+   error = 0;
+   goto ok;
+   }
+   }
+
+   /* Not found. Append it to the tail. */
+   acl = tmy_alloc_element(sizeof(*acl));
+   if (!acl)
+   goto ok;
+
+   acl->head.type = TMY_TYPE_ARGV0_ACL;
+   acl->head.cond = cond;
+   acl->filename = saved_filename;
+   acl->argv0 = saved_argv0;
+   error = tmy_add_acl(domain, &acl->head);
+   goto ok;
+remove: ;
+   error = -ENOENT;
+   list_for_each_entry(ptr, &domain->acl_info_list, list) {
+   acl = container_of(ptr, struct argv0_acl, head);
+   if (ptr->type != TMY_TYPE_ARGV0_ACL ||
+   ptr->cond != cond || ptr->is_deleted ||
+   acl->filename != saved_filename ||
+   acl->argv0 != saved_argv0)
+   continue;
+
+   error = tmy_del_acl(ptr);
+   break;
+   }
+ok: ;
+   mutex_unlock(&domain_acl_lock);
+
+   return error;
+}
+
+static int tmy_argv0_acl(const struct path_info *filename,
+const char *argv0_)
+{
+   const struct domain_info *domain = TMY_SECURITY->domain;
+   int error = -EPERM;
+   struct acl_info *ptr;
+   struct path_info argv0;
+
+   if (!tmy_flags(TMY_MAC_FOR_ARGV0))
+   return 0;
+
+   argv0.name = argv0_;
+   tmy_fill_path_info(&argv0);
+
+   list_for_each_entry(ptr, &domain->acl_info_list, list) {
+   struct argv0_acl *acl;
+   acl = container_of(ptr, struct argv0_acl, head);
+
+   if (ptr->type == TMY_TYPE_ARGV0_ACL &&
+   ptr->is_deleted == 0 &&
+   tmy_check_condition(ptr->cond, NULL) == 0 &&
+   tmy

[TOMOYO #6 retry 09/21] Domain transition functions.

2008-01-08 Thread Kentaro Takeda
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 ' /sbin/init /etc/init.d/rc'.
Domain information is stored in task_struct->security.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/domain.c | 1261 +++
 1 file changed, 1261 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/domain.c
@@ -0,0 +1,1261 @@
+/*
+ * security/tomoyo/domain.c
+ *
+ * Domain transition functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/*  VARIABLES  */
+
+/* The initial domain. */
+struct domain_info KERNEL_DOMAIN;
+
+/* Lock for appending domain's ACL. */
+DEFINE_MUTEX(domain_acl_lock);
+
+/* Domain creation lock. */
+static DEFINE_MUTEX(new_domain_assign_lock);
+
+/* The structure for program files to force domain reconstruction. */
+
+struct domain_initializer_entry {
+   struct list_head list;
+   const struct path_info *domainname;/* This may be NULL */
+   const struct path_info *program;
+   bool is_deleted;
+   bool is_not;
+   bool is_last_name;
+};
+
+/* The structure for domains to not to transit domains. */
+
+struct domain_keeper_entry {
+   struct list_head list;
+   const struct path_info *domainname;
+   const struct path_info *program;   /* This may be NULL */
+   bool is_deleted;
+   bool is_not;
+   bool is_last_name;
+};
+
+/* The structure for program files that should be aggregated. */
+
+struct aggregator_entry {
+   struct list_head list;
+   const struct path_info *original_name;
+   const struct path_info *aggregated_name;
+   bool is_deleted;
+};
+
+/* The structure for program files that should be aliased. */
+
+struct alias_entry {
+   struct list_head list;
+   const struct path_info *original_name;
+   const struct path_info *aliased_name;
+   bool is_deleted;
+};
+
+/*  UTILITY FUNCTIONS  */
+
+/**
+ * tmy_is_domain_def - check if the line is likely a domain definition.
+ * @buffer: the line to check.
+ *
+ * Returns true if @buffer is likely a domain definition.
+ * Returns false otherwise.
+ *
+ * For complete validation check, use tmy_is_correct_domain().
+ */
+bool tmy_is_domain_def(const unsigned char *buffer)
+{
+   return strncmp(buffer, TMY_ROOT_NAME, TMY_ROOT_NAME_LEN) == 0;
+}
+
+/**
+ * tmy_add_acl - add an entry to a domain.
+ * @domain: pointer to "struct domain_info".
+ * @acl: pointer to "struct acl_info" to add.
+ *
+ * Returns zero.
+ */
+int tmy_add_acl(struct domain_info *domain,
+   struct acl_info *acl)
+{
+   list_add_tail_mb(&acl->list, &domain->acl_info_list);
+   tmy_update_counter(TMY_UPDATE_DOMAINPOLICY);
+   return 0;
+}
+
+/**
+ * tmy_del_acl - remove an entry from a domain
+ * @ptr: pointer to "struct acl_info" to remove.
+ *
+ * Returns zero.
+ *
+ * TOMOYO Linux doesn't free memory used by policy because policies are not
+ * so frequently changed after entring into enforcing mode.
+ * This makes the code free of read-lock.
+ * The caller uses "down(&domain_acl_lock);" as write-lock.
+ */
+int tmy_del_acl(struct acl_info *ptr)
+{
+   ptr->is_deleted = 1;
+   tmy_update_counter(TMY_UPDATE_DOMAINPOLICY);
+   return 0;
+}
+
+/  DOMAIN INITIALIZER HANDLER  
/
+
+static LIST_HEAD(domain_initializer_list);
+
+/* Update domain initializer list. */
+static int tmy_add_domain_initializer_entry(const char *domainname,
+   const char *program,
+   const bool is_not,
+   const bool is_delete)
+{
+   struct domain_initializer_entry *new_entry;
+   struct domain_initializer_entry *ptr;
+   static DEFINE_MUTEX(mutex);
+   const struct path_info *saved_program;
+   const struct path_info *saved_domainname = NULL;
+   int error = -ENOMEM;
+   bool is_last_name = 0;
+
+   if (!tmy_correct_path(program, 1, -1, -1, __FUNCTION__))
+   return -EINVAL; /* No patterns allowed. */
+
+   if (domainname) {
+   if (!tmy_is_domain_def(domainname) &&
+   tmy_correct_path(domainname, 1, -1, -1, __FUNCTION__))
+   is_last_name = 1;
+
+   else if (!tmy_is_correct_domain(domainname, __FUNCTION__))
+   return -EINVAL;
+
+   saved_domainname = tmy_save_name(domainname);
+   if (!saved_domainname)
+   

[TOMOYO #6 retry 10/21] Auditing interface.

2008-01-08 Thread Kentaro Takeda
TOMOYO Linux uses /sys/kernel/security/tomoyo/ interface
for reporting access logs in domain policy format.
One is 'grant_log', used for auditing accesses which are
granted in the TOMOYO Linux policy.
The other is 'reject_log', used for auditing accesses which
are not granted in the TOMOYO Linux policy.
The userland daemon /usr/lib/ccs/ccs-auditd will save these logs.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/audit.c |  239 
 1 file changed, 239 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/audit.c
@@ -0,0 +1,239 @@
+/*
+ * security/tomoyo/audit.c
+ *
+ * Audit functions for TOMOYO Linux
+ */
+
+#include "tomoyo.h"
+
+#ifdef CONFIG_SECURITY_TOMOYO_USE_AUDITD
+/**
+ * tmy_audit - write audit log.
+ * @fmt:  format strings for printf().
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ *
+ * Write audit log.
+ */
+int tmy_audit(const char *fmt, ...)
+{
+   struct audit_buffer *ab;
+   int len;
+   va_list args;
+   char *buf;
+   char *cp;
+   ab = audit_log_start(current->audit_context, GFP_KERNEL, AUDIT_KERNEL);
+   if (!ab)
+   return -ENOMEM;
+   buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+   if (!buf)
+   goto out;
+   va_start(args, fmt);
+   len = vsnprintf(buf, PAGE_SIZE - 1, fmt, args);
+   va_end(args);
+   if (len > PAGE_SIZE - 1) {
+   kfree(buf);
+   buf = kzalloc(len + 16, GFP_KERNEL);
+   if (!buf)
+   goto out;
+   va_start(args, fmt);
+   vsnprintf(buf, len + 15, fmt, args);
+   va_end(args);
+   }
+   cp = strchr(buf, '\0') - 1;
+   if (cp >= buf && *cp == '\n')
+   *cp = '\0';
+   audit_log_format(ab, "TOMOYO: %s", buf);
+   kfree(buf);
+out: ;
+   audit_log_end(ab);
+   return buf ? 0 : -ENOMEM;
+}
+#endif
+
+static DECLARE_WAIT_QUEUE_HEAD(grant_log_wait);
+static DECLARE_WAIT_QUEUE_HEAD(reject_log_wait);
+
+static DEFINE_SPINLOCK(audit_log_lock);
+
+struct log_entry {
+   struct list_head list;
+   char *log;
+};
+
+static LIST_HEAD(grant_log);
+static LIST_HEAD(reject_log);
+
+static int grant_log_count;
+static int reject_log_count;
+
+/**
+ * tmy_audit_grant - get flags of auditing grant logs.
+ *
+ * Returns current value of auditing grant log flags.
+ */
+bool tmy_audit_grant(void)
+{
+   return grant_log_count < tmy_flags(TMY_MAX_GRANT_LOG);
+}
+
+/**
+ * tmy_audit_reject - get flags of auditing reject logs.
+ *
+ * Returns current value of auditing reject log flags.
+ */
+bool tmy_audit_reject(void)
+{
+   return reject_log_count < tmy_flags(TMY_MAX_REJECT_LOG);
+}
+
+/**
+ * tmy_init_audit_log - allocate and initialize audit buffer.
+ * @len: pointer to length of requested size.
+ * @profile: profile number for this log.
+ * @mode: profile value for this log.
+ *
+ * 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, const u8 profile, const unsigned int mode)
+{
+   char *buf;
+   struct timeval tv;
+   struct task_struct *task = current;
+   const char *domainname = TMY_SECURITY->domain->domainname->name;
+   do_gettimeofday(&tv);
+   *len += strlen(domainname) + 256;
+   buf = tmy_alloc(*len);
+   if (!buf)
+   return NULL;
+   snprintf(buf, (*len) - 1, "#timestamp=%lu profile=%u mode=%u "
+"pid=%d uid=%d gid=%d euid=%d egid=%d "
+"suid=%d sgid=%d fsuid=%d fsgid=%d \n%s\n",
+tv.tv_sec, profile, mode,
+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?
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ *
+ * Write audit log.
+ * Caller must allocate @buf with tmy_init_audit_log().
+ */
+int tmy_write_audit_log(char *buf, const bool is_granted)
+{
+   struct log_entry *new_entry;
+   new_entry = tmy_alloc(sizeof(*new_entry));
+   if (!new_entry) {
+   tmy_free(buf);
+   return -ENOMEM;
+   }
+   INIT_LIST_HEAD(&new_entry->list);
+   new_entry->log = buf;
+   /* CRITICAL SECTION START */
+   spin_lock(&audit_log_lock);
+   if (is_granted) {
+   list_add_tail(&new_entry->list, &grant_log);
+   grant_log_count+

[TOMOYO #6 retry 07/21] Memory and pathname management functions.

2008-01-08 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/realpath.c |  659 +
 1 file changed, 659 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/realpath.c
@@ -0,0 +1,659 @@
+/*
+ * security/tomoyo/realpath.c
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.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_path - return the realpath of a dentry.
+ * @dentry: pointer to "struct dentry".
+ * @vfsmnt: pointer to "struct vfsmount" to which the @dentry belongs.
+ * @buffer: size of buffer to save the result.
+ * @buflen: size of @buffer .
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ *
+ * Caller holds the dcache_lock.
+ * Based on __d_path() in fs/dcache.c
+ *
+ * Unlike d_path(), this function traverses upto the root directory of
+ * process's namespace.
+ *
+ * If @dentry is a directory, trailing '/' is appended.
+ * Characters other than ' ' < c < 127 are converted to \ooo style octal 
string.
+ * Character \ is converted to \\ string.
+ */
+static int tmy_get_absolute_path(struct dentry *dentry,
+struct vfsmount *vfsmnt,
+char *buffer,
+int buflen)
+{
+   char *start = buffer;
+   char *end = buffer + buflen;
+   bool is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
+   const char *sp;
+   const char *cp;
+
+   if (buflen < 256)
+   goto out;
+
+   *--end = '\0';
+   buflen--;
+
+   while (1) {
+   struct dentry *parent;
+
+   if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+   /* Global root? */
+   spin_lock(&vfsmount_lock);
+   if (vfsmnt->mnt_parent == vfsmnt) {
+   spin_unlock(&vfsmount_lock);
+   break;
+   }
+   dentry = vfsmnt->mnt_mountpoint;
+   vfsmnt = vfsmnt->mnt_parent;
+   spin_unlock(&vfsmount_lock);
+   continue;
+   }
+
+   if (is_dir) {
+   is_dir = 0;
+   *--end = '/';
+   buflen--;
+   }
+
+   parent = dentry->d_parent;
+   sp = dentry->d_name.name;
+   cp = sp + dentry->d_name.len - 1;
+
+   /* Exception: Use /proc/self/ rather than */
+   /* /proc/\$/ for current process. */
+   if (IS_ROOT(parent) &&
+   *sp > '0' && *sp <= '9' && parent->d_sb &&
+   parent->d_sb->s_magic == PROC_SUPER_MAGIC) {
+
+   char *ep;
+   const pid_t pid = (pid_t) simple_strtoul(sp, &ep, 10);
+
+   if (!*ep && pid == current->tgid) {
+   sp = "self";
+   cp = sp + 3;
+   }
+
+   }
+
+   if (tmy_print_ascii(sp, cp, &buflen, &

[TOMOYO #6 retry 05/21] Add packet filtering based on processs security context.

2008-01-08 Thread Kentaro Takeda
This patch allows LSM modules filter incoming connections/datagrams
based on the process's security context who is attempting to pick up.

There are already hooks to filter incoming connections/datagrams
based on the socket's security context, but these hooks are not
applicable when one wants to do TCP Wrapper-like filtering
(e.g. App1 is permitted to accept TCP connections from 192.168.0.0/16).

Precautions: This approach has a side effect which unlikely occurs.

If a socket is shared by multiple processes with differnt policy,
the process who should be able to accept this connection
will not be able to accept this connection
because socket_post_accept() aborts this connection.
But if socket_post_accept() doesn't abort this connection,
the process who must not be able to accept this connection
will repeat accept() forever, which is a worse side effect.

Similarly, if a socket is shared by multiple processes with differnt policy,
the process who should be able to pick up this datagram
will not be able to pick up this datagram
because socket_post_recv_datagram() discards this datagram.
But if socket_post_recv_datagram() doesn't discard this datagram,
the process who must not be able to pick up this datagram
will repeat recvmsg() forever, which is a worse side effect.

So, don't give different permissions between processes who shares one socket.
Otherwise, some connections/datagrams cannot be delivered to intended process.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/security.h |   34 +-
 net/core/datagram.c  |   29 -
 net/socket.c |7 +--
 security/dummy.c |   13 ++---
 security/security.c  |   10 --
 5 files changed, 80 insertions(+), 13 deletions(-)

--- linux-2.6-mm.orig/include/linux/security.h
+++ linux-2.6-mm/include/linux/security.h
@@ -795,8 +795,12 @@ struct request_sock;
  * @socket_post_accept:
  * This hook allows a security module to copy security
  * information into the newly created socket's inode.
+ * This hook also allows a security module to filter connections
+ * from unwanted peers based on the process accepting this connection.
+ * The connection will be aborted if this hook returns nonzero.
  * @sock contains the listening socket structure.
  * @newsock contains the newly created server socket for connection.
+ * Return 0 if permission is granted.
  * @socket_sendmsg:
  * Check permission before transmitting a message to another socket.
  * @sock contains the socket structure.
@@ -810,6 +814,15 @@ struct request_sock;
  * @size contains the size of message structure.
  * @flags contains the operational flags.
  * Return 0 if permission is granted.  
+ * @socket_post_recv_datagram:
+ * Check permission after receiving a datagram.
+ * This hook allows a security module to filter packets
+ * from unwanted peers based on the process receiving this datagram.
+ * The packet will be discarded if this hook returns nonzero.
+ * @sk contains the socket.
+ * @skb contains the socket buffer.
+ * @flags contains the operational flags.
+ * Return 0 if permission is granted.
  * @socket_getsockname:
  * Check permission before the local address (name) of the socket object
  * @sock is retrieved.
@@ -1417,12 +1430,13 @@ struct security_operations {
   struct sockaddr * address, int addrlen);
int (*socket_listen) (struct socket * sock, int backlog);
int (*socket_accept) (struct socket * sock, struct socket * newsock);
-   void (*socket_post_accept) (struct socket * sock,
-   struct socket * newsock);
+   int (*socket_post_accept) (struct socket *sock, struct socket *newsock);
int (*socket_sendmsg) (struct socket * sock,
   struct msghdr * msg, int size);
int (*socket_recvmsg) (struct socket * sock,
   struct msghdr * msg, int size, int flags);
+   int (*socket_post_recv_datagram) (struct sock *sk, struct sk_buff *skb,
+ unsigned int flags);
int (*socket_getsockname) (struct socket * sock);
int (*socket_getpeername) (struct socket * sock);
int (*socket_getsockopt) (struct socket * sock, int level, int optname);
@@ -2343,10 +2357,12 @@ int security_socket_bind(struct socket *
 int security_socket_connect(struct socket *sock, struct sockaddr *address, int 
addrlen);
 int security_socket_listen(struct socket *sock, int backlog);
 int security_socket_accept(struct socket *sock, struct socket *newsock);
-void security_socket_post_accept(struct socket *sock, struct socket *newsock);
+int security_socket_post_accept(struct socket *sock, struct socket *newsock);
 int security_

[TOMOYO #6 retry 06/21] Data structures and prototype defitions.

2008-01-08 Thread Kentaro Takeda
Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/include/realpath.h |   45 ++
 security/tomoyo/include/tomoyo.h   |  695 +
 2 files changed, 740 insertions(+)

--- /dev/null
+++ linux-2.6-mm/security/tomoyo/include/realpath.h
@@ -0,0 +1,45 @@
+/*
+ * security/tomoyo/include/realpath.h
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO.
+ */
+
+#ifndef _TMY_REALPATH_H
+#define _TMY_REALPATH_H
+
+#include "tomoyo.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);
+
+#endif
--- /dev/null
+++ linux-2.6-mm/security/tomoyo/include/tomoyo.h
@@ -0,0 +1,695 @@
+/*
+ * security/tomoyo/include/tomoyo.h
+ *
+ * Header for TOMOYO Linux.
+ */
+
+#ifndef _TOMOYO_H
+#define _TOMOYO_H
+
+#define TOMOYO_VERSION_CODE "2.1.2-pre"
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * 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;
+   new->next = next;
+   new->prev = prev;
+   mb(); /* Avoid out-of-order execution. */
+   next->prev = new;
+   prev->next = new;
+}
+
+extern struct seq_operations mounts_op;
+extern struct mutex domain_acl_lock;
+extern bool sbin_init_started;
+
+struct tmy_security {
+   struct domain_info *domain;
+   struct domain_info *prev_domain;
+   u32 flags;
+};
+
+#define TMY_SECURITY ((struct tmy_security *) current->security)
+
+struct path_info {
+   const char *name;
+   u32 hash;/* = full_name_hash(name, strlen(name)) */
+   u16 total_len;   /* = strlen(name)   */
+   u16 const_len;   /* = tmy_const_part_length(name)*/
+   bool is_dir;   /* = tmy_strendswith(name, "/") */
+   bool is_patterned; /* = PathContainsPattern(name)  */
+   u16 depth;   /* = tmy_path_depth(name)   */
+};
+
+#define TMY_MAX_PATHNAME_LEN 4000
+
+struct path_group_member {
+   struct list_head list;
+   const struct path_info *member_name;
+   bool is_deleted;
+};
+
+struct path_group_entry {
+   struct list_head list;
+   const struct path_info *group_name;
+   struct list_head path_group_member_list;
+};
+
+
+struct mini_stat {
+   uid_t uid;
+   gid_t gid;
+   ino_t ino;
+};
+

[TOMOYO #6 retry 03/21] Add wrapper functions for VFS helper functions.

2008-01-08 Thread Kentaro Takeda
This patch allows LSM hooks refer previously associated "struct vfsmount"
parameter so that they can calculate pathname of given "struct dentry".

AppArmor's approach is to add "struct vfsmount" parameter to all related
functions, while my approach is to store "struct vfsmount" parameter
in "struct task_struct". My approach resembles to "syscall auditing" because
"syscall auditing" saves parameters at the entrance of a system call
in "struct audit_context" of "struct task_struct"
instead of adding parameters needed for auditing to all functions.

Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/fs.h |  138 +
 1 file changed, 138 insertions(+)

--- linux-2.6-mm.orig/include/linux/fs.h
+++ linux-2.6-mm/include/linux/fs.h
@@ -1081,6 +1081,116 @@ extern int vfs_rmdir(struct inode *, str
 extern int vfs_unlink(struct inode *, struct dentry *);
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct 
dentry *);
 
+#include 
+#include 
+
+static inline int vfs_create2(struct inode *dir, struct dentry *dentry,
+ int mode, struct nameidata *nd)
+{
+   int ret;
+   struct vfsmount *mnt = nd ? nd->path.mnt : NULL;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_create(dir, dentry, mode, nd);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_mkdir2(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, int mode)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_mkdir(dir, dentry, mode);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_mknod2(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, int mode, dev_t dev)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_mknod(dir, dentry, mode, dev);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_symlink2(struct inode *dir, struct dentry *dentry,
+  struct vfsmount *mnt, const char *oldname,
+  int mode)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_symlink(dir, dentry, oldname, mode);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_link2(struct dentry *old_dentry, struct inode *dir,
+   struct dentry *new_dentry, struct vfsmount *mnt)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_link(old_dentry, dir, new_dentry);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_rmdir2(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_rmdir(dir, dentry);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_unlink2(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_unlink(dir, dentry);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
+static inline int vfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry,
+ struct vfsmount *mnt)
+{
+   int ret;
+   struct task_struct *task = current;
+   struct vfsmount *prev_mnt = task->last_vfsmount;
+   task->last_vfsmount = mntget(mnt);
+   ret = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
+   task->last_vfsmount = prev_mnt;
+   mntput(mnt);
+   return ret;
+}
+
 /*
  * VFS dentry helper functions.
  */
@@ -1558,6 +1668,21 @@ static inline int break_lease(struct ino
 
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
   struct file *filp);
+
+static inline int do_truncate2(struct dentry *dentry, struct v

[TOMOYO #6 retry 04/21] Replace VFS with wrapper functions.

2008-01-08 Thread Kentaro Takeda
This patch replaces VFS helper function calls caused by
userland process's request with VFS wrapper functions call.
I don't have a plan to control VFS helper function calls
caused by the kernel. Therefore, this patch doesn't modify
individual filesystems in fs/*/ directory.

I need to know the vfsmount parameter from LSM hooks so that
I can calculate the pathname of a given dentry.

Scanning the caller process's namespace list cannot reliably
determine which vfsmount the given dentry belongs to
because the corresponding vfsmount parameter appears for
multiple times when bind mounts are used.

What is worse, accessing namespace_sem from LSM hooks triggers
AB-BA deadlock. Therefore, I definitely need either AppArmor's
"Add struct vfsmount parameter to ..." patches or this patch.

Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 fs/namei.c |   34 +++---
 fs/open.c  |   23 +--
 net/unix/af_unix.c |3 ++-
 3 files changed, 34 insertions(+), 26 deletions(-)

--- linux-2.6-mm.orig/fs/open.c
+++ linux-2.6-mm/fs/open.c
@@ -271,7 +271,8 @@ static long do_sys_truncate(const char _
error = locks_verify_truncate(inode, NULL, length);
if (!error) {
DQUOT_INIT(inode);
-   error = do_truncate(nd.path.dentry, length, 0, NULL);
+   error = do_truncate2(nd.path.dentry, nd.path.mnt, length, 0,
+NULL);
}
 
 put_write_and_out:
@@ -326,7 +327,8 @@ static long do_sys_ftruncate(unsigned in
 
error = locks_verify_truncate(inode, file, length);
if (!error)
-   error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, 
file);
+   error = do_truncate2(dentry, file->f_path.mnt, length,
+ATTR_MTIME|ATTR_CTIME, file);
 out_putf:
fput(file);
 out:
@@ -589,7 +591,7 @@ asmlinkage long sys_fchmod(unsigned int 
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-   err = notify_change(dentry, &newattrs);
+   err = notify_change2(dentry, file->f_path.mnt, &newattrs);
mutex_unlock(&inode->i_mutex);
 
 out_drop_write:
@@ -626,7 +628,7 @@ asmlinkage long sys_fchmodat(int dfd, co
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-   error = notify_change(nd.path.dentry, &newattrs);
+   error = notify_change2(nd.path.dentry, nd.path.mnt, &newattrs);
mutex_unlock(&inode->i_mutex);
 
 out_drop_write:
@@ -642,7 +644,8 @@ asmlinkage long sys_chmod(const char __u
return sys_fchmodat(AT_FDCWD, filename, mode);
 }
 
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
+   uid_t user, gid_t group)
 {
struct inode * inode;
int error;
@@ -669,7 +672,7 @@ static int chown_common(struct dentry * 
newattrs.ia_valid |=
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
mutex_lock(&inode->i_mutex);
-   error = notify_change(dentry, &newattrs);
+   error = notify_change2(dentry, mnt, &newattrs);
mutex_unlock(&inode->i_mutex);
 out:
return error;
@@ -686,7 +689,7 @@ asmlinkage long sys_chown(const char __u
error = mnt_want_write(nd.path.mnt);
if (error)
goto out_release;
-   error = chown_common(nd.path.dentry, user, group);
+   error = chown_common(nd.path.dentry, nd.path.mnt, user, group);
mnt_drop_write(nd.path.mnt);
 out_release:
path_put(&nd.path);
@@ -711,7 +714,7 @@ asmlinkage long sys_fchownat(int dfd, co
error = mnt_want_write(nd.path.mnt);
if (error)
goto out_release;
-   error = chown_common(nd.path.dentry, user, group);
+   error = chown_common(nd.path.dentry, nd.path.mnt, user, group);
mnt_drop_write(nd.path.mnt);
 out_release:
path_put(&nd.path);
@@ -730,7 +733,7 @@ asmlinkage long sys_lchown(const char __
error = mnt_want_write(nd.path.mnt);
if (error)
goto out_release;
-   error = chown_common(nd.path.dentry, user, group);
+   error = chown_common(nd.path.dentry, nd.path.mnt, user, group);
mnt_drop_write(nd.path.mnt);
 out_release:
path_put(&nd.path);
@@ -754,7 +757,7 @@ asmlinkage long sys_fchown(unsigned int 
goto out_fput;
dentry = file->f_path.dentry;
audit_inode(NULL, dentry);
-   error = chown_common(dentry, user, group);
+   error = chown_common(dentry, file->f_vfsmnt, user, group);
mnt_drop_write(file->f_vfsmnt);
 out_fput:
fput(file);
--- linux-2.6-mm.orig/fs/namei.c
+++ linux-2.6-mm/fs/namei.c
@@ -1663,7 

[TOMOYO #6 retry 02/21] Add struct vfsmount to struct task_struct.

2008-01-08 Thread Kentaro Takeda
This patch allows VFS wrapper functions associate "struct vfsmount"
with "struct task_struct" so that LSM hooks can calculate
pathname of given "struct dentry".

Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/init_task.h |1 +
 include/linux/sched.h |2 ++
 2 files changed, 3 insertions(+)

--- linux-2.6-mm.orig/include/linux/init_task.h
+++ linux-2.6-mm/include/linux/init_task.h
@@ -187,6 +187,7 @@ extern struct group_info init_groups;
.dirties = INIT_PROP_LOCAL_SINGLE(dirties), \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP\
+   .last_vfsmount  = NULL, \
 }
 
 
--- linux-2.6-mm.orig/include/linux/sched.h
+++ linux-2.6-mm/include/linux/sched.h
@@ -1238,6 +1238,8 @@ struct task_struct {
int make_it_fail;
 #endif
struct prop_local_single dirties;
+   /* vfsmount info for LSM hooks. */
+   struct vfsmount *last_vfsmount;
 };
 
 /*

-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO #6 retry 01/21] TOMOYO Linux documentation.

2008-01-08 Thread Kentaro Takeda
Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
Signed-off-by: Toshiharu Harada <[EMAIL PROTECTED]>
---
 Documentation/TOMOYO.txt |  266 +++
 1 file changed, 266 insertions(+)

--- /dev/null
+++ linux-2.6-mm/Documentation/TOMOYO.txt
@@ -0,0 +1,266 @@
+Subject: TOMOYO Linux Security Goal
+
+This document is intended to specify the security goal that TOMOYO Linux is
+trying to achieve, so that users can evaluate whether TOMOYO Linux will meet
+their needs, and kernel developers can evaluate whether TOMOYO Linux deserved
+to be in-tree.
+
+1. About TOMOYO Linux
+
+Project Homepage: http://tomoyo.sourceforge.jp/index.html.en
+Project Wiki: http://elinux.org/TomoyoLinux
+
+TOMOYO Linux is a DIY tool for understanding and protecting your system.
+TOMOYO Linux policy definitions are absolutely readable to Linux users, and
+TOMOYO Linux supports unique policy learning mechanism which automatically
+gathers information and arranges the results as policy definitions.
+These things made it possible for users to write policy from scratch.
+Troubleshooting can be done by users.
+
+We put some TOMOYO Linux policy examples on our web site.
+http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/etch/domain_policy.conf?v=policy-sample
+
+Here's our version of Linux security comparison table.
+http://tomoyo.sourceforge.jp/wiki-e/?WhatIs#comparison
+
+2. TOMOYO Linux Security Goal
+
+The TOMOYO Linux's security goal is to provide "MAC that covers practical
+requirements for most users and keeps usable for most administrators".
+TOMOYO Linux is not a tool for security professional but for average users
+and administrators. We keep TOMOYO Linux understandable and customizable
+so that end users (i.e. administrators) can configure policy for their systems.
+
+TOMOYO Linux can authorize part of kernel resources which SELinux can
+and part of other resources which SELinux can't.
+
+Currently, TOMOYO Linux can authorize
+
+  * execve() of programs.
+  * open() of files for reading/writing.
+  * creat()/link()/rename()/unlink()/symlink()/mkfifo()/mksock()/mkblock()/
+mkchar()/truncate()/mkdir()/rmdir() of files and directries
+that are visible to userland process's namespace.
+  * namespace manipulation. (i.e. mount()/umount()/pivot_root())
+  * TCP/IP networking operations based on IPv4/v6 addresses and port numbers.
+(Need to add LSM hooks for incoming connections/packets.)
+  * booleans for some operations. (Part of POSIX capability and TOMOYO Linux's
+original capability.)
+  * signal transmissions. (Needs to add LSM hooks.)
+  * argv[0] passed to execve().
+  * environment variables' names passed to execve().
+
+TOMOYO Linux is purely restrictive. No requests which are denied by existent
+access control mechanisms (e.g. DAC) will be reversed by TOMOYO Linux.
+
+TOMOYO Linux is not intended to provide information flow control.
+Analyzing and restricting how information propagates are not the region of
+interest for TOMOYO Linux.
+
+3. Our Approach
+
+To meet the above goal, TOMOYO Linux attempts to make the system where
+everything is prearranged in an easy-to-understand way.
+
+  * Make the all subject's all access requests that will occur at least once
+during the lifetime of the kernel known in advance.
+
+  * Let the administrator understand what access requests will each subject
+raise in his/her system and write policy which only allows expected and
+desirable access requests for his/her needs.
+
+Unlike AppArmor, TOMOYO Linux is intended to protect the whole system from
+attackers exploiting vulnerabilities in applications that the system hosts.
+The threat is that an attacker can cause a vulnerable application to do
+something unexpected and undesirable. TOMOYO Linux addresses this threat by
+recording all applications' behaviors in the test environment and forcing
+all applications behave within recorded behaviors in the production 
environment.
+
+TOMOYO Linux has a unique concept of "process invocation history"
+(in short, PIH). The PIH is a developmental lineage of a process.
+When a process executes a program, the process creates a copy with fork() and
+replace the copy with execve().
+TOMOYO Linux appends the pathname of the executed program to the PIH of
+the replaced process, and associates process's PIH (stored in task_struct)
+with a domain.
+As a result, the context switching (a.k.a. domain transition) is 
unidirectional.
+This rule allows administrator distinguish and manage fine-grained context.
+Domain transition forms tree structure like a directory tree of filesystems.
+Each domain has different set of permissions that are essential for that 
domain.
+
+TOMOYO Linux's region of interest is how to minimize means granted to each PIH,
+although not all permissions TOMOYO Linux can authorize.
+
+The &qu

[TOMOYO #6 retry 00/21] TOMOYO Linux - MAC based on process invocation history.

2008-01-08 Thread Kentaro Takeda
"TOMOYO Linux" is our work in the field of security enhancement for Linux.
This is the 6th submission of TOMOYO Linux.
(http://tomoyo.sourceforge.jp/wiki-e/?WhatIs#mainlining)

Changes since previous (November 17th) submission:

* Added security goal document. (Documentation/TOMOYO.txt)
   This document is intended to specify the security goal that TOMOYO
   Linux is trying to achieve. Thread URL:
 http://lkml.org/lkml/2007/12/25/18

* Added environment variable name control functionality.
   Users can restrict the environment variable's names passed to
   execve() for each domain.

* Refreshed patches for the latest -mm tree.
   Patches are for 2.6.24-rc6-mm1

The possibility of AB-BA deadlock has been pointed out and argued in
http://lkml.org/lkml/2007/11/5/388 .
We believe that LSM functions shouldn't access namespace_sem, so
we chose to write a set of wrapper functions to pass "struct vfsmount" to
LSM functions using "struct task_struct". This method is suggested at
http://www.mail-archive.com/[EMAIL PROTECTED]/msg01712.html .

We wish Linux to merge either AppArmor's "Pass struct vfsmount to ..." patches 
or
our patches marked as [02/21], [03/21], [04/21] into mainline kernel
so that AppArmor and TOMOYO Linux can safely access "struct vfsmount" from LSM.

Patches consist of five types.
 * [TOMOYO 01/21]:Documentation.
 * [TOMOYO 02-05/21]: Essential modifications against -mm kernel.
 * [TOMOYO 06-19/21]: LSM implementation of TOMOYO Linux.
 * [TOMOYO 20/21]:Makefile and Kconfig.
 * [TOMOYO 21/21]:Optional modifications against -mm kernel.

We are trying to make a fair ¡Èsecure Linux¡É comparison table, it should
explain the differences between TOMOYO Linux and AppArmor.
(http://tomoyo.sourceforge.jp/wiki-e/?WhatIs#comparison)

We would like TOMOYO Linux to be added into -mm tree so that more
people can try. Any kind of feedbacks for the patches and the table
would be appreciated.
-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO #6 00/21] TOMOYO Linux - MAC based on process invocation history.

2008-01-08 Thread Kentaro Takeda
I'm sorry. I sent inlined patches with quilt,
but MTA converted them to attached files.
I'll retry soon.

Regards,
Kentaro Takeda

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO #6 11/21] File access control functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-file.patch
Description: application/octect-stream


[TOMOYO #6 06/21] Data structures and prototype defitions.

2008-01-08 Thread Kentaro Takeda


tomoyo-headers.patch
Description: application/octect-stream


[TOMOYO #6 09/21] Domain transition functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-domain.patch
Description: application/octect-stream


[TOMOYO #6 14/21] Network access control functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-net.patch
Description: application/octect-stream


[TOMOYO #6 18/21] LSM adapter functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-hooks.patch
Description: application/octect-stream


[TOMOYO #6 15/21] Namespace manipulation control functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-mount.patch
Description: application/octect-stream


[TOMOYO #6 01/21] TOMOYO Linux documentation.

2008-01-08 Thread Kentaro Takeda


tomoyo-documentation.patch
Description: application/octect-stream


[TOMOYO #6 05/21] Add packet filtering based on processs security context.

2008-01-08 Thread Kentaro Takeda


add-packet-filtering-based-on-process-security-context.patch
Description: application/octect-stream


[TOMOYO #6 21/21] Add signal hooks at sleepable location.

2008-01-08 Thread Kentaro Takeda


add-signal-hooks-at-sleepable-locations.patch
Description: application/octect-stream


[TOMOYO #6 13/21] environment variable name check functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-environ.patch
Description: application/octect-stream


[TOMOYO #6 12/21] argv0 check functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-exec.patch
Description: application/octect-stream


[TOMOYO #6 19/21] Conditional permission support.

2008-01-08 Thread Kentaro Takeda


tomoyo-condition.patch
Description: application/octect-stream


[TOMOYO #6 07/21] Memory and pathname management functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-realpath.patch
Description: application/octect-stream


[TOMOYO #6 04/21] Replace VFS with wrapper functions.

2008-01-08 Thread Kentaro Takeda


replace-vfs-with-wrapper-functions.patch
Description: application/octect-stream


[TOMOYO #6 17/21] Capability access control functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-capability.patch
Description: application/octect-stream


[TOMOYO #6 10/21] Auditing interface.

2008-01-08 Thread Kentaro Takeda


tomoyo-audit.patch
Description: application/octect-stream


[TOMOYO #6 16/21] Signal control functions.

2008-01-08 Thread Kentaro Takeda


tomoyo-signal.patch
Description: application/octect-stream


[TOMOYO #6 03/21] Add wrapper functions for VFS helper functions.

2008-01-08 Thread Kentaro Takeda


add-wrapper-functions-for-vfs-helper-functions.patch
Description: application/octect-stream


[TOMOYO #6 20/21] Kconfig and Makefile

2008-01-08 Thread Kentaro Takeda


tomoyo-kconfig.patch
Description: application/octect-stream


[TOMOYO #6 00/21] TOMOYO Linux - MAC based on process invocation history.

2008-01-08 Thread Kentaro Takeda
"TOMOYO Linux" is our work in the field of security enhancement for Linux.
This is the 6th submission of TOMOYO Linux.
(http://tomoyo.sourceforge.jp/wiki-e/?WhatIs#mainlining)

Changes since previous (November 17th) submission:

* Added security goal document. (Documentation/TOMOYO.txt)
   This document is intended to specify the security goal that TOMOYO
   Linux is trying to achieve. Thread URL:
 http://lkml.org/lkml/2007/12/25/18

* Added environment variable name control functionality.
   Users can restrict the environment variable's names passed to
   execve() for each domain.

* Refreshed patches for the latest -mm tree.
   Patches are for 2.6.24-rc6-mm1

The possibility of AB-BA deadlock has been pointed out and argued in
http://lkml.org/lkml/2007/11/5/388 .
We believe that LSM functions shouldn't access namespace_sem, so
we chose to write a set of wrapper functions to pass "struct vfsmount" to
LSM functions using "struct task_struct". This method is suggested at
http://www.mail-archive.com/[EMAIL PROTECTED]/msg01712.html .

We wish Linux to merge either AppArmor's "Pass struct vfsmount to ..." patches 
or
our patches marked as [02/21], [03/21], [04/21] into mainline kernel
so that AppArmor and TOMOYO Linux can safely access "struct vfsmount" from LSM.

Patches consist of five types.
 * [TOMOYO 01/21]:Documentation.
 * [TOMOYO 02-05/21]: Essential modifications against -mm kernel.
 * [TOMOYO 06-19/21]: LSM implementation of TOMOYO Linux.
 * [TOMOYO 20/21]:Makefile and Kconfig.
 * [TOMOYO 21/21]:Optional modifications against -mm kernel.

We are trying to make a fair ¡Èsecure Linux¡É comparison table, it should
explain the differences between TOMOYO Linux and AppArmor.
(http://tomoyo.sourceforge.jp/wiki-e/?WhatIs#comparison)

We would like TOMOYO Linux to be added into -mm tree so that more
people can try. Any kind of feedbacks for the patches and the table
would be appreciated.
-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO #6 02/21] Add struct vfsmount to struct task_struct.

2008-01-08 Thread Kentaro Takeda


add-struct-vfsmount-to-struct-task_struct.patch
Description: application/octect-stream


[TOMOYO 03/15](repost) Memory and pathname management functions.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/realpath.c |  697 +
 1 files changed, 697 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/realpath.c2007-10-02 11:26:21.0 
+0900
@@ -0,0 +1,697 @@
+/*
+ * security/tomoyo/realpath.c
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#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_path - return the realpath of a dentry.
+ * @dentry: pointer to "struct dentry".
+ * @vfsmnt: pointer to "struct vfsmount" to which the @dentry belongs.
+ * @buffer: size of buffer to save the result.
+ * @buflen: size of @buffer .
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ *
+ * Caller holds the dcache_lock.
+ * Based on __d_path() in fs/dcache.c
+ *
+ * Unlike d_path(), this function traverses upto the root directory of
+ * process's namespace.
+ *
+ * If @dentry is a directory, trailing '/' is appended.
+ * Characters other than ' ' < c < 127 are converted to \ooo style octal 
string.
+ * Character \ is converted to \\ string.
+ */
+static int tmy_get_absolute_path(struct dentry *dentry,
+struct vfsmount *vfsmnt,
+char *buffer,
+int buflen)
+{
+   char *start = buffer;
+   char *end = buffer + buflen;
+   u8 is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
+   const char *sp;
+   const char *cp;
+
+   if (buflen < 256)
+   goto out;
+
+   *--end = '\0';
+   buflen--;
+
+   while (1) {
+   struct dentry *parent;
+
+   if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+   /* Global root? */
+   spin_lock(&vfsmount_lock);
+   if (vfsmnt->mnt_parent == vfsmnt) {
+   spin_unlock(&vfsmount_lock);
+   break;
+   }
+   dentry = vfsmnt->mnt_mountpoint;
+   vfsmnt = vfsmnt->mnt_parent;
+   spin_unlock(&vfsmount_lock);
+   continue;
+   }
+
+   if (is_dir) {
+   is_dir = 0;
+   *--end = '/';
+   buflen--;
+   }
+
+   parent = dentry->d_parent;
+   sp = dentry->d_name.name;
+   cp = sp + dentry->d_name.len - 1;
+
+   /* Exception: Use /proc/self/ rather than */
+   /* /proc/\$/ for current process. */
+   if (IS_ROOT(parent) &&
+   *sp > '0' && *sp <= '9' && parent->d_sb &&
+   parent->d_sb->s_magic == PROC_SUPER_MAGIC) {
+
+   char *ep;
+   const pid_t pid = (pid_t) simple_strtoul(sp, &ep, 10);
+
+   if (!*e

[TOMOYO 00/15](repost) TOMOYO Linux - MAC based on process invocation history.

2007-10-02 Thread Kentaro Takeda
pply access control not only over files but
  also over networking, signals, namespace manipulations.
* TOMOYO Linux can accumulate ACL in real-time using
  "learning mode".

* TOMOYO Linux allows the administrator to switch the access
  control mode on a per-domain and per-functionality basis.
* TOMOYO Linux allows the administrator to judge (grant/reject)
  requests which that violated ACL manually while operating in
  "enforcing mode" without once rejecting these requests.
* TOMOYO Linux supports conditional ACL (e.g. owner of
  process/files etc.).

Documents about installing and experiencing TOMOYO Linux are available
at http://tomoyo.sourceforge.jp/en/2.1.x/ . Please try TOMOYO Linux.
Feedbacks are most welcome.


<>

OLS BoF material: 
http://sourceforge.jp/projects/tomoyo/document/ols2007-tomoyo-20070629.pdf
Previous submissions: http://lkml.org/lkml/2007/6/13/58 , 
http://lkml.org/lkml/2007/6/14/55, http://lkml.org/lkml/2007/8/24/116

Kentaro Takeda
NTT DATA CORPORATION

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 02/15](repost) Data structures and prototypes definition.

2007-10-02 Thread Kentaro Takeda
Data structures and prototype defitions for TOMOYO Linux.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 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.0 +
+++ linux-2.6/security/tomoyo/include/realpath.h2007-10-02 
11:26:21.0 +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   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/include/tomoyo.h  2007-10-02 11:26:21.0 
+0900
@@ -0,0 +1,517 @@
+/*
+ * security/tomoyo/include/tomoyo.h
+ *
+ * Header for TOMOYO Linux.
+ */
+
+#ifndef _TOMOYO_H
+#define _TOMOYO_H
+
+#define TOMOYO_VERSION_CODE "2.1.0-rc4"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+extern struct rw_semaphore namespace_sem;
+extern struct semaphore domain_acl_lock;
+extern int sbin_init_started;
+
+struct tmy_security {
+   struct domain_info *domain;
+   struct domain_info *prev_domain;
+   u32 flags;
+};
+
+#define TMY_SECURITY ((struct tmy_security *) current->security)
+
+struct path_info {
+   const char *name;
+   u32 hash;/* = full_name_hash(name, strlen(name)) */
+   u16 total_len;   /* = strlen(name)   */
+   u16 const_len;   /* = tmy_const_part_length(name)*/
+   u8 is_dir;   /* = tmy_strendswith(name, "/") */
+   u8 is_patterned; /* = PathContainsPattern(name)  */
+   u16 depth;   /* = tmy_path_depth(name)   */
+};
+
+#define TMY_MAX_PATHNAME_LEN 4000
+
+struct group_member {
+   struct group_member *next;
+   const struct path_info *member_name;
+   u8 is_deleted;
+};
+
+struct group_entry {
+   struct group_entry *next;
+   const struct path_info *group_name;
+   struct group_member *first_member;
+};
+
+
+struct mini_stat {
+   uid_t uid;
+   gid_t gid;
+   ino_t ino;
+};
+struct dentry;
+struct vfsmount;
+struct obj_info {
+   u8 validate_done;
+   u8 path1_valid;
+   u8 path1_parent_valid;
+   u8 path2_parent_valid;
+   struct dentry *path1_dentry;
+   struct vfsmount *path1_vfsmnt;
+   struct dentry *path2_dentry;
+   struct vfsmount *path2_vfsmnt;
+   struct mini_stat path1_stat;
+   /* I don't handle path2_stat for rename operation. */
+   struct mini_stat path1_parent_stat;
+   struct mini_stat path2_parent_stat;
+};
+struct condition_list;
+
+struct linux_binprm;
+struct pt_regs;
+
+/*
+ *  TOMOYO uses the following structures.
+ *  Memory allocated for these structures are never kfree()ed.
+ *  Since no locks are used for reading,
+ *  assignment must be performed atomically.
+ */
+
+/  The structure for domains.  
/
+
+struct acl_info {
+   struct acl_info *next;
+   const struct condition_list *cond;
+   u8 type;
+   u8 is_deleted;
+} __attribute__((__packed__));
+
+struct domain_info {
+   struct domain_info *next;   /* NULL if none. */
+   struct acl_info *first_acl_ptr; /* NULL if none. */
+   const struct path_info *domainname; /* Never NULL.   */
+   u8 profile;
+   u8 is_deleted;
+   u8 quot

[TOMOYO 01/15](repost) Allow use of namespace_sem from LSM module.

2007-10-02 Thread Kentaro Takeda
TOMOYO Linux uses pathnames for auditing and controlling file access.
Therefore, namespace_sem is needed.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 fs/namespace.c |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- linux-2.6.orig/fs/namespace.c   2007-10-02 11:11:53.0 +0900
+++ linux-2.6/fs/namespace.c2007-10-02 11:26:21.0 +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);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO 00/15](repost) TOMOYO Linux - MAC based on process invocation history.

2007-10-02 Thread Kentaro Takeda
> 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.

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 unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO 00/15](repost) TOMOYO Linux - MAC based on process invocation history.

2007-10-02 Thread Kentaro Takeda
On 2007/08/27 21:11, Kyle Moffett wrote:
>This is probably not acceptable; I doubt there's a chance in hell
>that TOMOYO will get merged as long as it has text-based-language
>parsing in the kernel.  You also have $NEW_RANDOM_ABUSE_OF_PROCFS and
>$PATH_BASED_LSM_ISSUES.  See the long flamewars on AppArmor for
>discussion on the latter.

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 .

On 2007/08/27 23:49, Paul Moore wrote:
>This has been discussed several times on various lists and is not considered 
>an acceptable solution to blocking incoming stream connection attempts.  
>Please take a look at the existing LSM stream connection request hooks as 
>well as how SELinux makes use of them.
(snip)
>Can you explain to me why this is not possible using the existing 
>security_socket_sock_rcv_skb() LSM hook?

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 unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 15/15](repost) Kconfig and Makefile for TOMOYO Linux.

2007-10-02 Thread Kentaro Takeda
Kconfig and Makefile for TOMOYO Linux.
TOMOYO Linux is placed in security/tomoyo .

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 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.0 +0900
+++ linux-2.6/security/Kconfig  2007-10-02 11:26:21.0 +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/Makefile2007-10-02 11:11:53.0 +0900
+++ linux-2.6/security/Makefile 2007-10-02 11:26:21.0 +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.0 +
+++ linux-2.6/security/tomoyo/Kconfig   2007-10-02 11:26:21.0 +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.0 +
+++ linux-2.6/security/tomoyo/Makefile  2007-10-02 11:26:21.0 +0900
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo.o tomoyo_func.o
+tomoyo_func-objs := domain.o common.o realpath.o audit.o file.o exec.o net.o 
mount.o signal.o condition.o
+EXTRA_CFLAGS += -Isecurity/tomoyo/include


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 14/15](repost) LSM expansion for TOMOYO Linux.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 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.0 
+0900
+++ linux-2.6/include/linux/security.h  2007-10-02 11:26:23.0 +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 process to reap a child process @p
  * and collect its status information.
@@ -749,8 +765,12 @@ struct request_sock;
  * @socket_post_accept:
  * This hook allows a security module to copy security
  * information into the newly created socket's inode.
+ * This hook also allows a security module to filter connections
+ * from unwanted peers.
+ * The connection will be aborted if this hook returns nonzero.
  * @sock contains the listening socket structure.
  * @newsock contains the newly created server socket for connection.
+ * Return 0 if permission is granted.
  * @socket_sendmsg:
  * Check permission before transmitting a message to another socket.
  * @sock contains the socket structure.
@@ -764,6 +784,11 @@ struct request_sock;
  * @size contains the size of message structure.
  * @flags contains the operational flags.
  * Return 0 if permission is granted.  
+ * @post_recv_datagram:
+ * Check permission after receiving a datagram.
+ * @sk contains the socket.
+ * @skb contains the socket buffer (may be NULL).
+ * @flags contains the operational flags.
  * @socket_getsockname:
  * Check permission before the local address (name) of the socket object
  * @sock is retrieved.
@@ -1279,6 +1304,9 @@ struct security_operations {
int (*task_movememory) (struct task_struct * p);
int (*task_kill) (struct task_struct * p,
  struct siginfo * info, int sig, u32 secid);
+   int (*task_kill_unlocked) (int pid, int sig);
+   int (*task_tkill_unlocked) (int pid, int sig);
+   int (*task_tgkill_unlocked) (int tgid, int pid, int sig);
int (*task_wait) (struct task_struct * p);
int (*task_prctl) (int option, unsigned long arg2,
   unsigned long arg3, unsigned long arg4,
@@ -1346,12 +1374,16 @@ struct security_operations {
   struct sockaddr * address, int addrlen);
int (*socket_listen) (struct socket * sock, int backlog);
int (*socket_accept) (struct socket * sock, struct socket * newsock);
-   void (*socket_post_accept) (struct socket * sock,
-   struct socket * newsock);
+#define TMY_LSM_EXPANSION
+   int (*socket_post_accept) (struct socket *sock,
+  struct socket *newsock);
int (*socket_sendmsg) (struct socket * sock,
   struct msghdr * msg, int size);
int (*socket_recvmsg) (struct socket * sock,
   struct msghdr * msg, int size, int flags);
+   int (*post_recv_datagram) (struct sock *sk,
+  struct sk_buff *skb,
+  unsigned int flags);
int (*socket_getsockname) (struct socket * sock);
int (*socket_getpeername) (struct socket * sock);
int (*socket_gets

[TOMOYO 13/15](repost) Conditional permission support.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/condition.c |  680 
 1 files changed, 680 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/condition.c   2007-10-02 11:26:22.0 
+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 buffer_len,
+   const unsigned long value, const int type)
+{
+   if (type == VALUE_TYPE_DECIMAL)
+   snprintf(buffer, buffer_len, "%lu", value);
+   else if (type == VALUE_TYPE_OCTAL)
+   snprintf(buffer, buffer_len, "0%lo", value);
+   else
+   snprintf(buffer, buffer_len, "0x%lX", value);
+}
+
+/* List of conditins. */
+static struct condition_list {
+   struct condition_list *next;
+   int length;
+   /* "unsigned long condition[length]" comes here.*/
+} head;
+
+#define TASK_UID  0
+#define TASK_EUID 1
+#define TASK_SUID 2
+#define TASK_FSUID3
+#define TASK_GID  4
+#define TASK_EGID 5
+#define TASK_SGID 6
+#define TASK_FSGID7
+#define TASK_PID  8
+#define TASK_PPID 9
+#define PATH1_UID10
+#define PATH1_GID11
+#define PATH1_INO12
+#define PATH1_PARENT_UID 13
+#define PATH1_PARENT_GID 14
+#define PATH1_PARENT_INO 15
+#define PATH2_PARENT_UID 16
+#define PATH2_PARENT_GID 17
+#define PATH2_PARENT_INO 18
+#define MAX_KEYWORD  19
+
+static struct {
+   const char *keyword;
+   const int keyword_len; /* strlen(keyword) */
+} cc_keyword[MAX_KEYWORD] = {
+   [TASK_UID] = { "task.uid",   8 },
+   [TASK_EUID]= { "task.euid",  9 },
+   [TASK_SUID]= { "task.suid",  9 },
+   [TASK_FSUID]   = { "task.fsuid",10 },
+   [TASK_GID] = { "task.gid",   8 },
+   [TASK_EGID]= { "task.egid",  9 },
+   [TASK_SGID]= { "task.sgid",  9 },
+   [TASK_FSGID]   = { "task.fsgid",10 },
+   [TASK_PID] = { "task.pid",   8 },
+   [TASK_PPID]= { "task.ppid",  9 },
+   [PATH1_UID]= { "path1.uid",  9 },
+   [PATH1_GID]= { "path1.gid",  9 },
+   [PATH1_INO]= { "path1.ino",  9 },
+   [PATH1_PARENT_UID] = { "path1.parent.uid",  16 },
+   [PATH1_PARENT_GID] = { "path1.parent.gid",  16 },
+   [PATH1_PARENT_INO] = { "path1.parent.ino",  16 },
+   [PATH2_PARENT_UID] = { "path2.parent.uid",  16 },
+   [PATH2_PARENT_GID] = { "path2.parent.gid",  16 },
+   [PATH2_PARENT_INO] = { "path2.parent.ino",  16 }
+};
+
+/**
+ * tmy_assign_condition - create condition part.
+ * @condi

[TOMOYO 12/15](repost) LSM adapter for TOMOYO.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/tomoyo.c |  748 +++
 1 files changed, 748 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/tomoyo.c  2007-10-02 11:26:22.0 +0900
@@ -0,0 +1,748 @@
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * LSM hooks for TOMOYO Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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 linux_binprm *bprm)
+{
+   struct domain_info *next_domain = NULL;
+   int retval = 0;
+
+   tmy_load_policy(bprm->filename);
+
+   /*
+* TMY_CHECK_READ_FOR_OPEN_EXEC bit indicates whether this function is
+* called by do_execve() or not.
+* If called by do_execve(), I do domain transition.
+*/
+   if (!(TMY_SECURITY->flags
+ & TMY_CHECK_READ_FOR_OPEN_EXEC)) {
+   retval = tmy_find_next_domain(bprm, &next_domain);
+   if (retval == 0) {
+   TMY_SECURITY->domain = next_domain;
+   TMY_SECURITY->flags |=
+   TMY_CHECK_READ_FOR_OPEN_EXEC;
+   }
+   }
+
+   return retval;
+}
+
+static void tmy_bprm_post_apply_creds(struct linux_binprm *bprm)
+{
+   TMY_SECURITY->prev_domain = TMY_SECURITY->domain;
+}
+
+static void tmy_bprm_free_security(struct linux_binprm *bprm)
+{
+   TMY_SECURITY->domain = TMY_SECURITY->prev_domain;
+   TMY_SECURITY->flags &= ~TMY_CHECK_READ_FOR_OPEN_EXEC;
+}
+
+static int tmy_sysctl(struct ctl_table *table, int op)
+{
+   int error;
+   char *name;
+
+   if ((op & 6) == 0)
+   return 0;
+
+   name = sysctlpath_from_table(table);
+   if (!name)
+   return -ENOMEM;
+
+   error = tmy_file_perm(name, op & 6, "sysctl");
+   tmy_free(name);
+
+   return error;
+}
+
+static int tmy_inode_permission(struct inode *inode,
+   int mask,
+   struct nameidata *nd)
+{
+   int flag = 0;
+
+   if (S_ISDIR(inode->i_mode)) /* ignore because inode is directory */
+   return 0;
+   if (!nd || !nd->dentry || !nd->mnt)
+   return 0;
+   /*
+* If called by other than do_execve(), I check for read permission of
+* interpreter.
+* Unlike DAC, I don't check for read permission of pathname passed to
+* do_execve().
+* TOMOYO Linux checks for program's execute permission and
+* interpreter's read permission.
+*/
+   if ((mask == MAY_EXEC) &&
+   (TMY_SECURITY->flags & TMY_CHECK_READ_FOR_OPEN_EXEC))
+   mask = MAY_READ;
+   if ((mask == MAY_EXEC) || (mask == 0))
+   return 0;
+
+   if (mask == (MAY_READ | MAY_EXEC))
+   flag |= O_RDONLY + 1;
+   else {
+   if (mask & MAY_READ)
+   flag |= O_RDONLY + 1;
+   if (mask & MAY_WRITE)
+   flag |= O_WRONLY + 1;
+   if ((mask & MAY_APPEND))
+   flag |= O_APPEND;
+   }
+
+   return tmy_open_perm(nd->dentry, nd->mnt, flag);
+}
+
+static int tmy_do_single_write_perm(int operation, struct dentry *dentry)
+{
+   struct mnt_namespace *namespace = current->nsproxy->mnt_ns;
+   struct list_head *p;
+   int ret = 0;
+   int error = 0;
+   int index = 0;
+   int index2 = 0;
+
+   if (!dentry || !namespace)

[TOMOYO 11/15](repost) Signal transmission control functions.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/signal.c |  229 +++
 1 files changed, 229 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/signal.c  2007-10-02 11:26:22.0 +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, __FUNCTION__))
+   return -EINVAL;
+
+   saved_dest_pattern = tmy_save_name(dest_pattern);
+   if (!saved_dest_pattern)
+   return -ENOMEM;
+
+   down(&domain_acl_lock);
+
+   if (is_delete)
+   goto remove;
+
+   ptr = domain->first_acl_ptr;
+   if (!ptr)
+   goto first_entry;
+
+   while (1) {
+   struct signal_acl *acl = (struct signal_acl *) ptr;
+
+   if (ptr->type == TMY_TYPE_SIGNAL_ACL && acl->sig == sig
+   && ptr->cond == cond
+   && !tmy_pathcmp(acl->domainname, saved_dest_pattern)) {
+   ptr->is_deleted = 0;
+   /* Found. Nothing to do. */
+   error = 0;
+   break;
+   }
+
+   if (ptr->next) {
+   ptr = ptr->next;
+   continue;
+   }
+
+first_entry: ;
+   /* Not found. Append it to the tail. */
+   acl = tmy_alloc_element(sizeof(*acl));
+   if (!acl)
+   break;
+
+   acl->head.type = TMY_TYPE_SIGNAL_ACL;
+   acl->head.cond = cond;
+   acl->sig = sig;
+   acl->domainname = saved_dest_pattern;
+   error = tmy_add_acl(ptr, domain, (struct acl_info *) acl);
+   break;
+   }
+   goto ok;
+remove: ;
+   error = -ENOENT;
+   for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+   struct signal_acl *acl = (struct signal_acl *) ptr;
+   if (ptr->type != TMY_TYPE_SIGNAL_ACL || ptr->cond != cond ||
+   ptr->is_deleted || acl->sig != sig ||
+   tmy_pathcmp(acl->domainname, saved_dest_pattern))
+   continue;
+   error = tmy_del_acl(ptr);
+   break;
+   }
+
+ok: ;
+   up(&domain_acl_lock);
+
+   return error;
+}
+
+/**
+ * tmy_signal_acl - check permission for kill(2)/tkill(2)/tgkill(2).
+ * @sig:  signal number.
+ * @pid:  pid of destination process.
+ *
+ * Returns zero if permission granted.
+ * Returns nonzero if permission denied.
+ */
+int tmy_signal_acl(const int sig, const int pid)
+{
+   struct domain_info *domain = TMY_SECURITY->domain;
+   struct domain_info *dest = NULL;
+   const char *dest_pattern;
+   struct acl_info *ptr;
+   const u16 hash = sig;
+   const u8 is_enforce = tmy_enforce(TMY_MAC_FO

[TOMOYO 10/15](repost) Namespace manipulation control functions.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/mount.c | 1019 
 1 files changed, 1019 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/mount.c   2007-10-02 11:26:22.0 +0900
@@ -0,0 +1,1019 @@
+/*
+ * security/tomoyo/mount.c
+ *
+ * Mount access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+#include 
+
+/* 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(printf, 3, 4)));
+
+static int tmy_audit_mount_log(const u8 is_granted,
+  const u8 is_enforce,
+  const char *fmt, ...)
+{
+   char *buf1;
+   char *buf2;
+   unsigned int len;
+   va_list args;
+
+   if (is_granted) {
+   if (!tmy_audit_grant())
+   return 0;
+   } else {
+   if (!tmy_audit_reject())
+   return 0;
+   }
+
+   buf1 = tmy_alloc(PAGE_SIZE);
+
+   if (!buf1)
+   return -ENOMEM;
+
+   va_start(args, fmt);
+   len = vsnprintf(buf1, PAGE_SIZE, fmt, args);
+   va_end(args);
+
+   if (len >= PAGE_SIZE) {
+   tmy_free(buf1);
+   return -ENOMEM;
+   }
+
+   buf2 = tmy_init_audit_log(&len);
+
+   if (!buf2) {
+   tmy_free(buf1);
+   return -ENOMEM;
+   }
+
+   snprintf(buf2 + strlen(buf2),
+len - strlen(buf2),
+"%s", buf1);
+
+   tmy_free(buf1);
+
+   return tmy_write_audit_log(buf2, is_granted, is_enforce);
+}
+
+/  MOUNT RESTRICTION HANDLER  /
+
+static void put_filesystem(struct file_system_type *fs)
+{
+   module_put(fs->owner);
+}
+
+static struct mount_entry *mount_list;
+
+/* Add or remove a mount entry. */
+static int tmy_add_mount_acl(const char *dev_name,
+const char *dir_name,
+const char *fs_type,
+const unsigned int flags,
+const u8 is_delete)
+{
+   struct mount_entry *new_entry;
+   struct mount_entry  *ptr;
+   const struct path_info *fs;
+   const struct path_info *dev;
+   const struct path_info *dir;
+   static DECLARE_MUTEX(lock);
+   int error = -ENOMEM;
+
+   fs = tmy_save_name(fs_type);
+   if (!fs)
+   return -EINVAL;
+
+   if (!dev_name)
+   /* Map dev_name to "" for if no dev_name given. */
+   dev_name = "";
+   if (strcmp(fs->name, MOUNT_REMOUNT_KEYWORD) == 0)
+   /* Fix dev_name to "any" for remount permission. */
+   dev_name = "any";
+   if (strcmp(fs->name, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0)
+   dev_name = "any";
+
+   if (!tmy_correct_path(dev_name, 0, 0, 0, __FUNCTION__) ||
+   !tmy_correct_path(dir_name, 1, 0, 1, __FUNCTION__))
+   return -EINVAL;
+
+   dev = tmy_save_name(dev_name);
+   if (!dev)
+   return

[TOMOYO 09/15](repost) Networking access control functions.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/net.c |  975 ++
 1 files changed, 975 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/net.c 2007-10-02 11:26:22.0 +0900
@@ -0,0 +1,975 @@
+/*
+ * security/tomoyo/net.c
+ *
+ * Network access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+
+/*  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);
+}
+
+/*  ADDRESS GROUP HANDLER  */
+
+/* List of address group. */
+static struct addr_group_entry *group_list;
+
+static int tmy_add_addr_group_entry(const char *group_name,
+   const u8 is_ipv6,
+   const u16 *min_address,
+   const u16 *max_address,
+   const u8 is_delete)
+{
+   static DECLARE_MUTEX(lock);
+   struct addr_group_entry *new_group;
+   struct addr_group_entry *group;
+   struct addr_group_member *new_member;
+   struct addr_group_member *member;
+   const struct path_info *saved_group_name;
+   int error = -ENOMEM;
+
+   if (!tmy_correct_path(group_name, 0, 0, 0, __FUNCTION__) ||
+   !group_name[0])
+   return -EINVAL;
+
+   saved_group_name = tmy_save_name(group_name);
+   if (!saved_group_name)
+   return -ENOMEM;
+
+   down(&lock);
+
+   for (group = group_list; group; group = group->next) {
+
+   if (saved_group_name != group->group_name)
+   continue;
+
+   for (member = group->first_member;
+member;
+member = member->next) {
+
+   if (member->is_ipv6 != is_ipv6)
+   continue;
+
+   if (is_ipv6) {
+   if (memcmp(member->min.ipv6, min_address, 16) ||
+   memcmp(member->max.ipv6, max_address, 16))
+   continue;
+   } else {
+   if (member->min.ipv4 != *(u32 *) min_address ||
+   member->max.ipv4 != *(u32 *) max_address)
+   continue;
+   }
+
+   member->is_deleted = is_delete;
+   error = 0;
+   goto out;
+   }
+   break;
+   }
+
+   if (is_delete) {
+   error = -ENOENT;
+   goto out;
+   }
+
+   if (!group) {
+   new_group = tmy_alloc_element(sizeof(*new_group));
+   if (!new_group)
+   goto out;
+   new_group->group_name = saved_group_name;
+   mb(); /* Instead of using spinlock. */
+   group = group_list;
+   if (group) {
+

[TOMOYO 08/15](repost) Argv[0] access control functions.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/exec.c |  222 +
 1 files changed, 222 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/exec.c2007-10-02 11:26:22.0 +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, 0, -1, __FUNCTION__) ||
+   strchr(argv0, '/'))
+   return -EINVAL;
+
+   saved_filename = tmy_save_name(filename);
+   saved_argv0 = tmy_save_name(argv0);
+   if (!saved_filename || !saved_argv0)
+   return -ENOMEM;
+
+   down(&domain_acl_lock);
+
+   if (is_delete)
+   goto remove;
+
+   ptr = domain->first_acl_ptr;
+   if (!ptr)
+   goto first_entry;
+   while (1) {
+   struct argv0_acl *acl = (struct argv0_acl *) ptr;
+
+   if (ptr->type == TMY_TYPE_ARGV0_ACL && ptr->cond == cond &&
+   acl->filename == saved_filename &&
+   acl->argv0 == saved_argv0) {
+   ptr->is_deleted = 0;
+   /* Found. Nothing to do. */
+   error = 0;
+   break;
+   }
+
+   if (ptr->next) {
+   ptr = ptr->next;
+   continue;
+   }
+
+first_entry: ;
+   /* Not found. Append it to the tail. */
+   acl = tmy_alloc_element(sizeof(*acl));
+   if (!acl)
+   break;
+
+   acl->head.type = TMY_TYPE_ARGV0_ACL;
+   acl->head.cond = cond;
+   acl->filename = saved_filename;
+   acl->argv0 = saved_argv0;
+   error = tmy_add_acl(ptr, domain,
+   (struct acl_info *) acl);
+
+   break;
+   }
+   goto ok;
+remove: ;
+   error = -ENOENT;
+   for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+   struct argv0_acl *acl = (struct argv0_acl *) ptr;
+
+   if (ptr->type != TMY_TYPE_ARGV0_ACL ||
+   ptr->cond != cond || ptr->is_deleted ||
+   acl->filename != saved_filename ||
+   acl->argv0 != saved_argv0)
+   continue;
+
+   error = tmy_del_acl(ptr);
+   break;
+   }
+ok: ;
+   up(&domain_acl_lock);
+
+   return error;
+}
+
+static int tmy_argv0_acl(const struct path_info *filename,
+const char *argv0_)
+{
+   const struct domain_info *domain = TMY_SECURITY->domain;
+   int error = -EPERM;
+   struct acl_info *ptr;
+   struct path_info argv0;
+
+   if (!tmy_flags(TMY_MAC_FOR_ARGV0))
+   return 0;
+
+   argv0.name = argv0_;
+   tmy_fill_path_info(&argv0

[TOMOYO 07/15](repost) File access control functions.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/file.c | 1544 +
 1 files changed, 1544 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/file.c2007-10-02 11:26:22.0 +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 */
+   { "mkchar",   1 }, /* TMY_TYPE_MKCHAR_ACL */
+   { "truncate", 1 }, /* TMY_TYPE_TRUNCATE_ACL */
+   { "symlink",  1 }, /* TMY_TYPE_SYMLINK_ACL */
+   { "link", 2 }, /* TMY_TYPE_LINK_ACL */
+   { "rename",   2 }, /* TMY_TYPE_RENAME_ACL */
+   { "rewrite",  1 }, /* TMY_TYPE_REWRITE_ACL */
+   { NULL, 0 }
+};
+
+/*  UTILITY FUNCTIONS  */
+
+/**
+ * tmy_acltype2keyword - get keyword from access control index.
+ * @acl_type: index number.
+ *
+ * Returns keyword that corresponds with @acl_type .
+ */
+const char *tmy_acltype2keyword(const unsigned int acl_type)
+{
+   return (acl_type < ARRAY_SIZE(acl_type_array))
+   ? acl_type_array[acl_type].keyword : NULL;
+}
+
+/**
+ * tmy_acltype2paths - get number of arguments from access control index.
+ * @acl_type: index number.
+ *
+ * Returns number of arguments that corresponds with @acl_type .
+ */
+int tmy_acltype2paths(const unsigned int acl_type)
+{
+   return (acl_type < ARRAY_SIZE(acl_type_array))
+   ? acl_type_array[acl_type].paths : 0;
+}
+
+static int tmy_strendswith(const char *name, const char *tail)
+{
+   int len;
+
+   if (!name || !tail)
+   return 0;
+
+   len = strlen(name) - strlen(tail);
+   return len >= 0 && strcmp(name + len, tail) == 0;
+}
+
+static struct path_info *tmy_get_path(struct dentry *dentry,
+ struct vfsmount *mnt)
+{
+   /* sizeof(struct path_info_with_data) <= PAGE_SIZE */
+   struct path_info_with_data {
+   /* Keep this first, this pointer is passed to tmy_free(). */
+   struct path_info head;
+   char bariier1[16];
+   char body[TMY_MAX_PATHNAME_LEN];
+   char barrier2[16];
+   } *buf = tmy_alloc(sizeof(*buf));
+
+   if (buf) {
+   int error = tmy_realpath_dentry2(dentry,
+mnt,
+buf->body,
+sizeof(buf->body) - 1);
+
+   if (error == 0) {
+   buf->head.name = buf->body;
+   tmy_fill_path_info(&buf->head);
+   return &buf->head;
+   }
+
+   tmy_free(buf);
+   buf = NULL;
+   printk(KERN_INFO "tmy_realpath_dentry = %d\n", error);
+   }
+
+   return NULL;
+}
+
+/*  PROTOTYPES  */
+
+static int tmy_add_double_write_acl(const u8 type,
+   const char *filename1,
+  

[TOMOYO 06/15](repost) Auditing interface.

2007-10-02 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/audit.h   |3 ++
 security/tomoyo/audit.c |   68 
 2 files changed, 71 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/audit.c   2007-10-02 11:26:22.0 +0900
@@ -0,0 +1,68 @@
+/*
+ * security/tomoyo/audit.c
+ *
+ * Audit functions for TOMOYO Linux
+ */
+
+#include "tomoyo.h"
+#include 
+
+/**
+ * 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.
+ *
+ * Write audit log.
+ * Caller must allocate @buf with tmy_init_audit_log().
+ */
+int tmy_write_audit_log(char *buf, const u8 is_granted, const u8 is_enforce)
+{
+   struct audit_buffer *ab;
+   int type = is_granted ? AUDIT_TMY_GRANTED : AUDIT_TMY_REJECTED;
+
+   ab = audit_log_start(current->audit_context, GFP_KERNEL, type);
+   if (ab) {
+   const char *msg
+   = is_granted ? "granted" : is_enforce ?
+   "error" : "warning";
+   audit_log_format(ab, "TOMOYO %s: %s", msg, buf);
+   audit_log_end(ab);
+   }
+
+   tmy_free(buf);
+   return ab ? 0 : -ENOMEM;
+}
--- linux-2.6.orig/include/linux/audit.h2007-10-02 11:11:52.0 
+0900
+++ linux-2.6/include/linux/audit.h 2007-10-02 11:26:22.0 +0900
@@ -120,6 +120,9 @@
 
 #define AUDIT_KERNEL   2000/* Asynchronous audit record. NOT A 
REQUEST. */
 
+#define AUDIT_TMY_GRANTED  2001 /* TOMOYO Linux audit granted */
+#define AUDIT_TMY_REJECTED 2002 /* TOMOYO Linux audit rejected */
+
 /* Rule flags */
 #define AUDIT_FILTER_USER  0x00/* Apply rule to user-generated 
messages */
 #define AUDIT_FILTER_TASK  0x01/* Apply rule at task creation (not 
syscall) */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2007-10-02 Thread Kentaro Takeda
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 ' /sbin/init /etc/init.d/rc'.
Domain information is stored in task_struct->security.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/domain.c | 1256 +++
 1 files changed, 1256 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/domain.c  2007-10-02 11:26:21.0 +0900
@@ -0,0 +1,1256 @@
+/*
+ * security/tomoyo/domain.c
+ *
+ * Domain transition functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+#include 
+
+/*  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_deleted;
+};
+
+/* The structure for program files that should be aliased. */
+
+struct alias_entry {
+   struct alias_entry *next;
+   const struct path_info *original_name;
+   const struct path_info *aliased_name;
+   u8 is_deleted;
+};
+
+/*  UTILITY FUNCTIONS  */
+
+/**
+ * tmy_is_domain_def - check if the line is likely a domain definition.
+ * @buffer: the line to check.
+ *
+ * Returns nonzero if @buffer is likely a domain definition.
+ * Returns zero otherwise.
+ *
+ * For complete validation check, use tmy_is_correct_domain().
+ */
+int tmy_is_domain_def(const unsigned char *buffer)
+{
+   return strncmp(buffer, TMY_ROOT_NAME, TMY_ROOT_NAME_LEN) == 0;
+}
+
+/**
+ * tmy_add_acl - add an entry to a domain.
+ * @ptr: pointer to the last "struct acl_info" of @domain. May be NULL.
+ * @domain: pointer to "struct domain_info".
+ * @new_ptr: pointer to "struct acl_info" to add.
+ *
+ * Returns zero.
+ *
+ * To be honest, I can calculate @ptr from @domain.
+ * But since the caller knows @ptr, I use it.
+ */
+int tmy_add_acl(struct acl_info *ptr,
+   struct domain_info *domain,
+   struct acl_info *new_ptr)
+{
+   mb(); /* Instead of using spinlock. */
+
+   if (!ptr)
+   domain->first_acl_ptr = (struct acl_info *) new_ptr;
+   else
+   ptr->next = (struct acl_info *) new_ptr;
+
+   tmy_update_counter(TMY_UPDATE_DOMAINPOLICY);
+   return 0;
+}
+
+/**
+ * tmy_del_acl - remove an entry from a domain
+ * @ptr: pointer to "struct acl_info" to remove.
+ *
+ * Returns zero.
+ *
+ * TOMOYO Linux doesn't free memory used by policy because policies are not
+ * so frequently changed after entring into enforcing mode.
+ * This makes the code free of read-lock.
+ * The caller uses "down(&domain_acl_lock);" as write-lock.
+ */
+int tmy_del_acl(struct acl_info *ptr)
+{
+   ptr->is_deleted = 1;
+   tmy_update_counter(TMY_UPDATE_DOMAINPOLICY);
+   return 0;
+}
+
+/  DOMAIN INITIALIZER HANDLER  
/
+
+static struct domain_initializer_entry *domain_initializer_list;
+
+/* Update domain initializer list. */
+static int tmy_add_domain_initializer_entry(const char *domainname,
+   const char *program,
+   const u8 is_not,
+   const u8 is_delete)
+{
+   struct domain_initializer_entry *new_entry;
+   struct domain_initializer_entry *ptr;
+   static DECLARE_MUTEX(lock);
+   const struct path_info *saved_program;
+   const struct path_info *saved_domainname = NULL;
+   int error = -ENOMEM;
+   u8 is_last_name = 0;
+
+   if (!tmy_correct_path(program, 1, -1, -1, __FUNCTION__))
+   

[TOMOYO 15/15] LSM expansion for TOMOYO Linux.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/security.h |   91 +++
 kernel/signal.c  |   17 
 net/core/datagram.c  |7 +++
 net/socket.c |7 ++-
 security/dummy.c |   32 ++--
 5 files changed, 142 insertions(+), 12 deletions(-)

--- linux-2.6.orig/include/linux/security.h 2007-08-23 21:25:04.0 
+0900
+++ linux-2.6/include/linux/security.h  2007-08-24 15:51:39.0 +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 process to reap a child process @p
  * and collect its status information.
@@ -749,8 +765,12 @@ struct request_sock;
  * @socket_post_accept:
  * This hook allows a security module to copy security
  * information into the newly created socket's inode.
+ * This hook also allows a security module to filter connections
+ * from unwanted peers.
+ * The connection will be aborted if this hook returns nonzero.
  * @sock contains the listening socket structure.
  * @newsock contains the newly created server socket for connection.
+ * Return 0 if permission is granted.
  * @socket_sendmsg:
  * Check permission before transmitting a message to another socket.
  * @sock contains the socket structure.
@@ -764,6 +784,11 @@ struct request_sock;
  * @size contains the size of message structure.
  * @flags contains the operational flags.
  * Return 0 if permission is granted.  
+ * @post_recv_datagram:
+ * Check permission after receiving a datagram.
+ * @sk contains the socket.
+ * @skb contains the socket buffer (may be NULL).
+ * @flags contains the operational flags.
  * @socket_getsockname:
  * Check permission before the local address (name) of the socket object
  * @sock is retrieved.
@@ -1279,6 +1304,9 @@ struct security_operations {
int (*task_movememory) (struct task_struct * p);
int (*task_kill) (struct task_struct * p,
  struct siginfo * info, int sig, u32 secid);
+   int (*task_kill_unlocked) (int pid, int sig);
+   int (*task_tkill_unlocked) (int pid, int sig);
+   int (*task_tgkill_unlocked) (int tgid, int pid, int sig);
int (*task_wait) (struct task_struct * p);
int (*task_prctl) (int option, unsigned long arg2,
   unsigned long arg3, unsigned long arg4,
@@ -1346,12 +1374,16 @@ struct security_operations {
   struct sockaddr * address, int addrlen);
int (*socket_listen) (struct socket * sock, int backlog);
int (*socket_accept) (struct socket * sock, struct socket * newsock);
-   void (*socket_post_accept) (struct socket * sock,
-   struct socket * newsock);
+#define TMY_LSM_EXPANSION
+   int (*socket_post_accept) (struct socket *sock,
+  struct socket *newsock);
int (*socket_sendmsg) (struct socket * sock,
   struct msghdr * msg, int size);
int (*socket_recvmsg) (struct socket * sock,
   struct msghdr * msg, int size, int flags);
+   int (*post_recv_datagram) (struct sock *sk,
+  struct sk_buff *skb,
+  unsigned int flags);
int (*socket_getsockname) (struct socket * sock);
int (*socket_getpeername) (struct socket * sock);
int (*socket_getsockopt)

[TOMOYO 13/15] LSM adapter for TOMOYO.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/tomoyo.c |  745 +++
 1 files changed, 745 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/tomoyo.c  2007-08-24 15:51:38.0 +0900
@@ -0,0 +1,745 @@
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * LSM hooks for TOMOYO Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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 linux_binprm *bprm)
+{
+   struct domain_info *next_domain = NULL;
+   int retval = 0;
+
+   tmy_load_policy(bprm->filename);
+
+   /*
+* TMY_CHECK_READ_FOR_OPEN_EXEC bit indicates whether this function is
+* called by do_execve() or not.
+* If called by do_execve(), I do domain transition.
+*/
+   if (!(TMY_SECURITY->flags
+ & TMY_CHECK_READ_FOR_OPEN_EXEC)) {
+   retval = tmy_find_next_domain(bprm, &next_domain);
+   if (retval == 0) {
+   TMY_SECURITY->domain = next_domain;
+   TMY_SECURITY->flags |=
+   TMY_CHECK_READ_FOR_OPEN_EXEC;
+   }
+   }
+
+   return retval;
+}
+
+static void tmy_bprm_post_apply_creds(struct linux_binprm *bprm)
+{
+   TMY_SECURITY->prev_domain = TMY_SECURITY->domain;
+}
+
+static void tmy_bprm_free_security(struct linux_binprm *bprm)
+{
+   TMY_SECURITY->domain = TMY_SECURITY->prev_domain;
+   TMY_SECURITY->flags &= ~TMY_CHECK_READ_FOR_OPEN_EXEC;
+}
+
+static int tmy_sysctl(struct ctl_table *table, int op)
+{
+   int error;
+   char *name;
+
+   if ((op & 6) == 0)
+   return 0;
+
+   name = sysctlpath_from_table(table);
+   if (!name)
+   return -ENOMEM;
+
+   error = tmy_file_perm(name, op & 6, "sysctl");
+   tmy_free(name);
+
+   return error;
+}
+
+static int tmy_inode_permission(struct inode *inode,
+   int mask,
+   struct nameidata *nd)
+{
+   int flag = 0;
+
+   if (S_ISDIR(inode->i_mode)) /* ignore because inode is directory */
+   return 0;
+   if (!nd || !nd->dentry || !nd->mnt)
+   return 0;
+   /*
+* If called by other than do_execve(), I check for read permission of
+* interpreter.
+* Unlike DAC, I don't check for read permission of pathname passed to
+* do_execve().
+* TOMOYO Linux checks for program's execute permission and
+* interpreter's read permission.
+*/
+   if ((mask == MAY_EXEC) &&
+   (TMY_SECURITY->flags & TMY_CHECK_READ_FOR_OPEN_EXEC))
+   mask = MAY_READ;
+   if ((mask == MAY_EXEC) || (mask == 0))
+   return 0;
+
+   if (mask == (MAY_READ | MAY_EXEC))
+   flag |= O_RDONLY + 1;
+   else {
+   if (mask & MAY_READ)
+   flag |= O_RDONLY + 1;
+   if (mask & MAY_WRITE)
+   flag |= O_WRONLY + 1;
+   if ((mask & MAY_APPEND))
+   flag |= O_APPEND;
+   }
+
+   return tmy_open_perm(nd->dentry, nd->mnt, flag);
+}
+
+static int tmy_do_single_write_perm(int operation, struct dentry *dentry)
+{
+   struct mnt_namespace *namespace = current->nsproxy->mnt_ns;
+   struct list_head *p;
+   int ret = 0;
+   int error = 0;
+   int index = 0;
+   int index2 = 0;
+
+   

[TOMOYO 14/15] Conditional permission support.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/condition.c |  680 
 1 files changed, 680 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/condition.c   2007-08-24 15:51:39.0 
+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 buffer_len,
+   const unsigned long value, const int type)
+{
+   if (type == VALUE_TYPE_DECIMAL)
+   snprintf(buffer, buffer_len, "%lu", value);
+   else if (type == VALUE_TYPE_OCTAL)
+   snprintf(buffer, buffer_len, "0%lo", value);
+   else
+   snprintf(buffer, buffer_len, "0x%lX", value);
+}
+
+/* List of conditins. */
+static struct condition_list {
+   struct condition_list *next;
+   int length;
+   /* "unsigned long condition[length]" comes here.*/
+} head;
+
+#define TASK_UID  0
+#define TASK_EUID 1
+#define TASK_SUID 2
+#define TASK_FSUID3
+#define TASK_GID  4
+#define TASK_EGID 5
+#define TASK_SGID 6
+#define TASK_FSGID7
+#define TASK_PID  8
+#define TASK_PPID 9
+#define PATH1_UID10
+#define PATH1_GID11
+#define PATH1_INO12
+#define PATH1_PARENT_UID 13
+#define PATH1_PARENT_GID 14
+#define PATH1_PARENT_INO 15
+#define PATH2_PARENT_UID 16
+#define PATH2_PARENT_GID 17
+#define PATH2_PARENT_INO 18
+#define MAX_KEYWORD  19
+
+static struct {
+   const char *keyword;
+   const int keyword_len; /* strlen(keyword) */
+} cc_keyword[MAX_KEYWORD] = {
+   [TASK_UID] = { "task.uid",   8 },
+   [TASK_EUID]= { "task.euid",  9 },
+   [TASK_SUID]= { "task.suid",  9 },
+   [TASK_FSUID]   = { "task.fsuid",10 },
+   [TASK_GID] = { "task.gid",   8 },
+   [TASK_EGID]= { "task.egid",  9 },
+   [TASK_SGID]= { "task.sgid",  9 },
+   [TASK_FSGID]   = { "task.fsgid",10 },
+   [TASK_PID] = { "task.pid",   8 },
+   [TASK_PPID]= { "task.ppid",  9 },
+   [PATH1_UID]= { "path1.uid",  9 },
+   [PATH1_GID]= { "path1.gid",  9 },
+   [PATH1_INO]= { "path1.ino",  9 },
+   [PATH1_PARENT_UID] = { "path1.parent.uid",  16 },
+   [PATH1_PARENT_GID] = { "path1.parent.gid",  16 },
+   [PATH1_PARENT_INO] = { "path1.parent.ino",  16 },
+   [PATH2_PARENT_UID] = { "path2.parent.uid",  16 },
+   [PATH2_PARENT_GID] = { "path2.parent.gid",  16 },
+   [PATH2_PARENT_INO] = { "path2.parent.ino",  16 }
+};
+
+/**
+ * tmy_assign_condition - create condition part.
+ * @condi

[TOMOYO 11/15] Namespace manipulation control functions.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/mount.c | 1019 
 1 files changed, 1019 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/mount.c   2007-08-24 15:51:37.0 +0900
@@ -0,0 +1,1019 @@
+/*
+ * security/tomoyo/mount.c
+ *
+ * Mount access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+#include 
+
+/* 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. */
+   int is_deleted;
+};
+
+struct no_umount_entry {
+   struct no_umount_entry *next; /* NULL if none. */
+   const struct path_info *dir;
+   int is_deleted;
+};
+
+/*  AUDIT FUNCTIONS  */
+
+static int tmy_audit_mount_log(const int is_granted,
+  const int is_enforce,
+  const char *fmt, ...)
+   __attribute__((format(printf, 3, 4)));
+
+static int tmy_audit_mount_log(const int is_granted,
+  const int is_enforce,
+  const char *fmt, ...)
+{
+   char *buf1;
+   char *buf2;
+   unsigned int len;
+   va_list args;
+
+   if (is_granted) {
+   if (!tmy_audit_grant())
+   return 0;
+   } else {
+   if (!tmy_audit_reject())
+   return 0;
+   }
+
+   buf1 = tmy_alloc(PAGE_SIZE);
+
+   if (!buf1)
+   return -ENOMEM;
+
+   va_start(args, fmt);
+   len = vsnprintf(buf1, PAGE_SIZE, fmt, args);
+   va_end(args);
+
+   if (len >= PAGE_SIZE) {
+   tmy_free(buf1);
+   return -ENOMEM;
+   }
+
+   buf2 = tmy_init_audit_log(&len);
+
+   if (!buf2) {
+   tmy_free(buf1);
+   return -ENOMEM;
+   }
+
+   snprintf(buf2 + strlen(buf2),
+len - strlen(buf2),
+"%s", buf1);
+
+   tmy_free(buf1);
+
+   return tmy_write_audit_log(buf2, is_granted, is_enforce);
+}
+
+/  MOUNT RESTRICTION HANDLER  /
+
+static void put_filesystem(struct file_system_type *fs)
+{
+   module_put(fs->owner);
+}
+
+static struct mount_entry *mount_list;
+
+/* Add or remove a mount entry. */
+static int tmy_add_mount_acl(const char *dev_name,
+const char *dir_name,
+const char *fs_type,
+const unsigned int flags,
+const int is_delete)
+{
+   struct mount_entry *new_entry;
+   struct mount_entry  *ptr;
+   const struct path_info *fs;
+   const struct path_info *dev;
+   const struct path_info *dir;
+   static DECLARE_MUTEX(lock);
+   int error = -ENOMEM;
+
+   fs = tmy_save_name(fs_type);
+   if (!fs)
+   return -EINVAL;
+
+   if (!dev_name)
+   /* Map dev_name to "" for if no dev_name given. */
+   dev_name = "";
+   if (strcmp(fs->name, MOUNT_REMOUNT_KEYWORD) == 0)
+   /* Fix dev_name to "any" for remount permission. */
+   dev_name = "any";
+   if (strcmp(fs->name, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 ||
+   strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0)
+   dev_name = "any";
+
+   if (!tmy_correct_path(dev_name, 0, 0, 0, __FUNCTION__) ||
+   !tmy_correct_path(dir_name, 1, 0, 1, __FUNCTION__))
+   return -EINVAL;
+
+   dev = tmy_save_name(dev_name);
+   if (!dev)

[TOMOYO 12/15] Signal transmission control functions.

2007-08-24 Thread Kentaro Takeda
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 expantion patch [TOMOYO /] is needed.

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/signal.c |  238 +++
 1 files changed, 238 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/signal.c  2007-08-24 15:51:38.0 +0900
@@ -0,0 +1,238 @@
+/*
+ * 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 int is_granted,
+   const int 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  */
+
+/*
+ * @is_add:   1  add this entry if not quota exceeded
+ *   -1  always add this entry
+ *0  remove this entry
+ */
+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_add)
+{
+   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, __FUNCTION__))
+   return -EINVAL;
+
+   saved_dest_pattern = tmy_save_name(dest_pattern);
+   if (!saved_dest_pattern)
+   return -ENOMEM;
+
+   down(&domain_acl_lock);
+
+   if (!is_add)
+   goto remove;
+
+   ptr = domain->first_acl_ptr;
+   if (!ptr)
+   goto first_entry;
+
+   while (1) {
+   struct signal_acl *acl = (struct signal_acl *) ptr;
+
+   if (ptr->type == TMY_TYPE_SIGNAL_ACL && acl->sig == sig
+   && ptr->cond == cond
+   && !tmy_pathcmp(acl->domainname, saved_dest_pattern)) {
+   ptr->is_deleted = 0;
+   /* Found. Nothing to do. */
+   error = 0;
+   break;
+   }
+
+   if (ptr->next) {
+   ptr = ptr->next;
+   continue;
+   }
+
+first_entry: ;
+   if (is_add == 1 && tmy_too_many_acl(domain))
+   break;
+   /* Not found. Append it to the tail. */
+   acl = tmy_alloc_element(sizeof(*acl));
+   if (!acl)
+   break;
+
+   acl->head.type = TMY_TYPE_SIGNAL_ACL;
+   acl->head.cond = cond;
+   acl->sig = sig;
+   acl->domainname = saved_dest_pattern;
+   error = tmy_add_acl(ptr, domain, (struct acl_info *) acl);
+   break;
+   }
+
+   goto ok;
+
+remove: ;
+   error = -ENOENT;
+   for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+   struct signal_acl *acl = (struct signal_acl *) ptr;
+   if (ptr->type != TMY_TYPE_SIGNAL_ACL || ptr->cond != cond ||
+   ptr->is_deleted || acl->sig != sig ||
+   tmy_pathcmp(acl->domainname, saved_dest_pattern))
+   continue;
+   error = tmy_del_acl(ptr);
+   break;
+   }
+
+ok: ;
+   up(&domain_acl_lock);
+
+   return error;
+}
+
+/**
+ * tmy_signal_acl - check permission for kill(2)/tkill(2)/tgkill(2).
+ * @sig:  signal number.
+ * @pid:  pid of destination process.
+ *
+ * Returns zero if permission granted.
+ * Returns nonzero if permission denied.
+ */
+int tmy_signal_acl(const int sig, const int pid)
+{
+   struct dom

[TOMOYO 10/15] Networking access control functions.

2007-08-24 Thread Kentaro Takeda
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 accept'(recv),
LSM expansion patch ([TOMOYO /]) is needed.

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/net.c |  983 ++
 1 files changed, 983 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/net.c 2007-08-24 15:51:37.0 +0900
@@ -0,0 +1,983 @@
+/*
+ * security/tomoyo/net.c
+ *
+ * Network access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+
+/*  AUDIT FUNCTIONS  */
+
+static int tmy_audit_network_log(const int is_ipv6,
+const char *operation,
+const u32 *address,
+const u16 port,
+const int is_granted,
+const int 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);
+}
+
+/*  ADDRESS GROUP HANDLER  */
+
+/* List of address group. */
+static struct addr_group_entry *group_list;
+
+static int tmy_add_addr_group_entry(const char *group_name,
+   const u8 is_ipv6,
+   const u16 *min_address,
+   const u16 *max_address,
+   const int is_delete)
+{
+   static DECLARE_MUTEX(lock);
+   struct addr_group_entry *new_group;
+   struct addr_group_entry *group;
+   struct addr_group_member *new_member;
+   struct addr_group_member *member;
+   const struct path_info *saved_group_name;
+   int error = -ENOMEM;
+
+   if (!tmy_correct_path(group_name, 0, 0, 0, __FUNCTION__) ||
+   !group_name[0])
+   return -EINVAL;
+
+   saved_group_name = tmy_save_name(group_name);
+   if (!saved_group_name)
+   return -ENOMEM;
+
+   down(&lock);
+
+   for (group = group_list; group; group = group->next) {
+
+   if (saved_group_name != group->group_name)
+   continue;
+
+   for (member = group->first_member;
+member;
+member = member->next) {
+
+   if (member->is_ipv6 != is_ipv6)
+   continue;
+
+   if (is_ipv6) {
+   if (memcmp(member->min.ipv6, min_address, 16) ||
+   memcmp(member->max.ipv6, max_address, 16))
+   continue;
+   } else {
+   if (member->min.ipv4 != * (u32 *) min_address ||
+   member->max.ipv4 != * (u32 *) max_address)
+   continue;
+   }
+
+   member->is_deleted = is_delete;
+   error = 0;
+   goto out;
+   }
+   break;
+   }
+
+   if (is_delete) {
+   error = -ENOENT;
+   goto out;
+   }
+
+   if (!group) {
+   new_group = tmy_alloc_element(sizeof(*new_group));
+   if (!new_group)
+   goto out;
+   new_group->group_name = saved_group_name;
+   mb(); /* Instead of using spinlock. */
+   group = group_list;
+   if (group) {
+

[TOMOYO 09/15] Argv[0] access control functions.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/exec.c |  230 +
 1 files changed, 230 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/exec.c2007-08-24 15:51:37.0 +0900
@@ -0,0 +1,230 @@
+/*
+ * 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 int is_granted,
+  const int 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  */
+
+/*
+ * @is_add:   1  add this entry if not quota exceeded
+ *   -1  always add this entry
+ *0  remove this entry
+ */
+static int tmy_add_argv0_entry(const char *filename,
+  const char *argv0,
+  struct domain_info *domain,
+  const struct condition_list *cond,
+  const u8 is_add)
+{
+   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, 0, -1, __FUNCTION__) ||
+   strchr(argv0, '/'))
+   return -EINVAL;
+
+   saved_filename = tmy_save_name(filename);
+   saved_argv0 = tmy_save_name(argv0);
+   if (!saved_filename || !saved_argv0)
+   return -ENOMEM;
+
+   down(&domain_acl_lock);
+
+   if (!is_add)
+   goto remove;
+
+   ptr = domain->first_acl_ptr;
+   if (!ptr)
+   goto first_entry;
+   while (1) {
+   struct argv0_acl *acl = (struct argv0_acl *) ptr;
+
+   if (ptr->type == TMY_TYPE_ARGV0_ACL && ptr->cond == cond &&
+   acl->filename == saved_filename &&
+   acl->argv0 == saved_argv0) {
+   ptr->is_deleted = 0;
+   /* Found. Nothing to do. */
+   error = 0;
+   break;
+   }
+
+   if (ptr->next) {
+   ptr = ptr->next;
+   continue;
+   }
+
+first_entry: ;
+   if (is_add == 1 && tmy_too_many_acl(domain))
+   break;
+
+   /* Not found. Append it to the tail. */
+   acl = tmy_alloc_element(sizeof(*acl));
+   if (!acl)
+   break;
+
+   acl->head.type = TMY_TYPE_ARGV0_ACL;
+   acl->head.cond = cond;
+   acl->filename = saved_filename;
+   acl->argv0 = saved_argv0;
+   error = tmy_add_acl(ptr, domain,
+   (struct acl_info *) acl);
+
+   break;
+   }
+   goto ok;
+remove: ;
+   error = -ENOENT;
+   for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+   struct argv0_acl *acl = (struct argv0_acl *) ptr;
+
+   if (ptr->type != TMY_TYPE_ARGV0_ACL ||
+   ptr->cond != cond || ptr->is_deleted ||
+   acl->filename != saved_filename ||
+   acl->argv0 != saved_argv0)
+   continue;
+
+   error = tmy_del_acl(ptr);
+   break;
+   }
+ok: ;
+   up(&domain_acl_lock);
+
+   return error;
+}
+
+static int tmy_argv0_acl(const struct path_info *filename,
+const char *argv0_)
+{
+   const struct domain_info *domain = TMY_SECURITY

[TOMOYO 08/15] File access control functions.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/file.c | 1565 +
 1 files changed, 1565 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/file.c2007-08-24 15:51:36.0 +0900
@@ -0,0 +1,1565 @@
+/*
+ * 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;
+   int is_deleted;
+};
+
+/* The structure for filename patterns. */
+
+struct pattern_entry {
+   struct pattern_entry *next;
+   const struct path_info *pattern;
+   int 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;
+   int 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 */
+   { "mkchar",   1 }, /* TMY_TYPE_MKCHAR_ACL */
+   { "truncate", 1 }, /* TMY_TYPE_TRUNCATE_ACL */
+   { "symlink",  1 }, /* TMY_TYPE_SYMLINK_ACL */
+   { "link", 2 }, /* TMY_TYPE_LINK_ACL */
+   { "rename",   2 }, /* TMY_TYPE_RENAME_ACL */
+   { "rewrite",  1 }, /* TMY_TYPE_REWRITE_ACL */
+   { NULL, 0 }
+};
+
+/*  UTILITY FUNCTIONS  */
+
+/**
+ * tmy_acltype2keyword - get keyword from access control index.
+ * @acl_type: index number.
+ *
+ * Returns keyword that corresponds with @acl_type .
+ */
+const char *tmy_acltype2keyword(const unsigned int acl_type)
+{
+   return (acl_type < ARRAY_SIZE(acl_type_array))
+   ? acl_type_array[acl_type].keyword : NULL;
+}
+
+/**
+ * tmy_acltype2paths - get number of arguments from access control index.
+ * @acl_type: index number.
+ *
+ * Returns number of arguments that corresponds with @acl_type .
+ */
+int tmy_acltype2paths(const unsigned int acl_type)
+{
+   return (acl_type < ARRAY_SIZE(acl_type_array))
+   ? acl_type_array[acl_type].paths : 0;
+}
+
+static int tmy_strendswith(const char *name, const char *tail)
+{
+   int len;
+
+   if (!name || !tail)
+   return 0;
+
+   len = strlen(name) - strlen(tail);
+   return len >= 0 && strcmp(name + len, tail) == 0;
+}
+
+static struct path_info *tmy_get_path(struct dentry *dentry,
+ struct vfsmount *mnt)
+{
+   /* sizeof(struct path_info_with_data) <= PAGE_SIZE */
+   struct path_info_with_data {
+   /* Keep this first, this pointer is passed to tmy_free(). */
+   struct path_info head;
+   char bariier1[16];
+   char body[TMY_MAX_PATHNAME_LEN];
+   char barrier2[16];
+   } *buf = tmy_alloc(sizeof(*buf));
+
+   if (buf) {
+   int error = tmy_realpath_dentry2(dentry,
+mnt,
+buf->body,
+sizeof(buf->body) - 1);
+
+   if (error == 0) {
+   buf->head.name = buf->body;
+   tmy_fill_path_info(&buf->head);
+   return &buf->head;
+   }
+
+   tmy_free(buf);
+   buf = NULL;
+   printk(KERN_INFO "tmy_realpath_dentry = %d\n", error);
+   }
+
+   return NULL;
+}
+
+/*  PROTOTYPES  */
+
+static int tmy_add_double_write_acl(const u8 type,
+   const char *filename1,
+  

[TOMOYO 07/15] Auditing interface.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 include/linux/audit.h   |3 ++
 security/tomoyo/audit.c |   68 
 2 files changed, 71 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/audit.c   2007-08-24 15:51:36.0 +0900
@@ -0,0 +1,68 @@
+/*
+ * security/tomoyo/audit.c
+ *
+ * Audit functions for TOMOYO Linux
+ */
+
+#include "tomoyo.h"
+#include 
+
+/**
+ * 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.
+ *
+ * Write audit log.
+ * Caller must allocate @buf with tmy_init_audit_log().
+ */
+int tmy_write_audit_log(char *buf, const int is_granted, const int is_enforce)
+{
+   struct audit_buffer *ab;
+   int type = is_granted ? AUDIT_TMY_GRANTED : AUDIT_TMY_REJECTED;
+
+   ab = audit_log_start(current->audit_context, GFP_KERNEL, type);
+   if (ab) {
+   const char *msg
+   = is_granted ? "granted" : is_enforce ?
+   "error" : "warning";
+   audit_log_format(ab, "TOMOYO %s: %s", msg, buf);
+   audit_log_end(ab);
+   }
+
+   tmy_free(buf);
+   return ab ? 0 : -ENOMEM;
+}
--- linux-2.6.orig/include/linux/audit.h2007-08-23 21:25:55.0 
+0900
+++ linux-2.6/include/linux/audit.h 2007-08-24 15:51:36.0 +0900
@@ -120,6 +120,9 @@
 
 #define AUDIT_KERNEL   2000/* Asynchronous audit record. NOT A 
REQUEST. */
 
+#define AUDIT_TMY_GRANTED  2001 /* TOMOYO Linux audit granted */
+#define AUDIT_TMY_REJECTED 2002 /* TOMOYO Linux audit rejected */
+
 /* Rule flags */
 #define AUDIT_FILTER_USER  0x00/* Apply rule to user-generated 
messages */
 #define AUDIT_FILTER_TASK  0x01/* Apply rule at task creation (not 
syscall) */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 06/15] Domain transition handler functions.

2007-08-24 Thread Kentaro Takeda
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 ' /sbin/init /etc/init.d/rc'.
Domain information is stored in task_struct->security.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/domain.c | 1291 +++
 1 files changed, 1291 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/domain.c  2007-08-24 15:51:36.0 +0900
@@ -0,0 +1,1291 @@
+/*
+ * security/tomoyo/domain.c
+ *
+ * Domain transition functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+#include 
+
+/*  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;
+   int is_deleted;
+};
+
+/* The structure for program files that should be aliased. */
+
+struct alias_entry {
+   struct alias_entry *next;
+   const struct path_info *original_name;
+   const struct path_info *aliased_name;
+   int is_deleted;
+};
+
+/*  UTILITY FUNCTIONS  */
+
+/**
+ * tmy_is_domain_def - check if the line is likely a domain definition.
+ * @buffer: the line to check.
+ *
+ * Returns nonzero if @buffer is likely a domain definition.
+ * Returns zero otherwise.
+ *
+ * For complete validation check, use tmy_is_correct_domain().
+ */
+int tmy_is_domain_def(const unsigned char *buffer)
+{
+   return strncmp(buffer, TMY_ROOT_NAME, TMY_ROOT_NAME_LEN) == 0;
+}
+
+/**
+ * tmy_add_acl - add an entry to a domain.
+ * @ptr: pointer to the last "struct acl_info" of @domain. May be NULL.
+ * @domain: pointer to "struct domain_info".
+ * @new_ptr: pointer to "struct acl_info" to add.
+ *
+ * Returns zero.
+ *
+ * To be honest, I can calculate @ptr from @domain.
+ * But since the caller knows @ptr, I use it.
+ */
+int tmy_add_acl(struct acl_info *ptr,
+   struct domain_info *domain,
+   struct acl_info *new_ptr)
+{
+   mb(); /* Instead of using spinlock. */
+
+   if (!ptr)
+   domain->first_acl_ptr = (struct acl_info *) new_ptr;
+   else
+   ptr->next = (struct acl_info *) new_ptr;
+
+   tmy_update_counter(TMY_UPDATE_DOMAINPOLICY);
+   return 0;
+}
+
+/**
+ * tmy_del_acl - remove an entry from a domain
+ * @ptr: pointer to "struct acl_info" to remove.
+ *
+ * Returns zero.
+ *
+ * TOMOYO Linux doesn't free memory used by policy because policies are not
+ * so frequently changed after entring into enforcing mode.
+ * This makes the code free of read-lock.
+ * The caller uses "down(&domain_acl_lock);" as write-lock.
+ */
+int tmy_del_acl(struct acl_info *ptr)
+{
+   ptr->is_deleted = 1;
+   tmy_update_counter(TMY_UPDATE_DOMAINPOLICY);
+   return 0;
+}
+
+/**
+ * tmy_too_many_acl - check quota for a domain.
+ * @domain: pointer to "struct domain_info" to examine.
+ *
+ * Returns nonzero if quota exceeded.
+ * Returns zero otherwise.
+ *
+ * This is a safeguard for "learning mode", for appending entries
+ * without limit dulls the system response and consumes much memory.
+ */
+int tmy_too_many_acl(struct domain_info * const domain)
+{
+   unsigned int count = 0;
+   struct acl_info *ptr;
+
+   for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+   if (!ptr->is_deleted)
+   count++;
+   }
+   /* If there are so many entries, don't append if accept mode. */
+   if (count < tmy_flags(TMY_MAX_ACCEPT_ENTRY))
+   return 0;
+
+   if (!domain->quota_war

[TOMOYO 04/15] Memory and pathname management functions.

2007-08-24 Thread Kentaro Takeda
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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/realpath.c |  697 +
 1 files changed, 697 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/realpath.c2007-08-24 15:51:35.0 
+0900
@@ -0,0 +1,697 @@
+/*
+ * security/tomoyo/realpath.c
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#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_path - return the realpath of a dentry.
+ * @dentry: pointer to "struct dentry".
+ * @vfsmnt: pointer to "struct vfsmount" to which the @dentry belongs.
+ * @buffer: size of buffer to save the result.
+ * @buflen: size of @buffer .
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ *
+ * Caller holds the dcache_lock.
+ * Based on __d_path() in fs/dcache.c
+ *
+ * Unlike d_path(), this function traverses upto the root directory of
+ * process's namespace.
+ *
+ * If @dentry is a directory, trailing '/' is appended.
+ * Characters other than ' ' < c < 127 are converted to \ooo style octal 
string.
+ * Character \ is converted to \\ string.
+ */
+static int tmy_get_absolute_path(struct dentry *dentry,
+struct vfsmount *vfsmnt,
+char *buffer,
+int buflen)
+{
+   char *start = buffer;
+   char *end = buffer + buflen;
+   int is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
+   const char *sp;
+   const char *cp;
+
+   if (buflen < 256)
+   goto out;
+
+   *--end = '\0';
+   buflen--;
+
+   while (1) {
+   struct dentry *parent;
+
+   if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+   /* Global root? */
+   spin_lock(&vfsmount_lock);
+   if (vfsmnt->mnt_parent == vfsmnt) {
+   spin_unlock(&vfsmount_lock);
+   break;
+   }
+   dentry = vfsmnt->mnt_mountpoint;
+   vfsmnt = vfsmnt->mnt_parent;
+   spin_unlock(&vfsmount_lock);
+   continue;
+   }
+
+   if (is_dir) {
+   is_dir = 0;
+   *--end = '/';
+   buflen--;
+   }
+
+   parent = dentry->d_parent;
+   sp = dentry->d_name.name;
+   cp = sp + dentry->d_name.len - 1;
+
+   /* Exception: Use /proc/self/ rather than */
+   /* /proc/\$/ for current process. */
+   if (IS_ROOT(parent) &&
+   *sp > '0' && *sp <= '9' && parent->d_sb &&
+   parent->d_sb->s_magic == PROC_SUPER_MAGIC) {
+
+   char *ep;
+   const pid_t pid = (pid_t) simple_strtoul(sp, &ep, 10);
+
+   if (!*e

[TOMOYO 03/15] Data structures and prototypes definition.

2007-08-24 Thread Kentaro Takeda
Data structures and prototype defitions for TOMOYO Linux.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 security/tomoyo/include/realpath.h |   44 +++
 security/tomoyo/include/tomoyo.h   |  516 +
 2 files changed, 560 insertions(+)

--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/include/realpath.h2007-08-24 
15:51:34.0 +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   1970-01-01 00:00:00.0 +
+++ linux-2.6/security/tomoyo/include/tomoyo.h  2007-08-24 15:51:34.0 
+0900
@@ -0,0 +1,516 @@
+/*
+ * security/tomoyo/include/tomoyo.h
+ *
+ * Header for TOMOYO Linux.
+ */
+
+#ifndef _TOMOYO_H
+#define _TOMOYO_H
+
+#define TOMOYO_VERSION_CODE "2.1.0-rc3"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+extern struct semaphore domain_acl_lock;
+extern int sbin_init_started;
+
+struct tmy_security {
+   struct domain_info *domain;
+   struct domain_info *prev_domain;
+   u32 flags;
+};
+
+#define TMY_SECURITY ((struct tmy_security *) current->security)
+
+struct path_info {
+   const char *name;
+   u32 hash;/* = full_name_hash(name, strlen(name)) */
+   u16 total_len;   /* = strlen(name)   */
+   u16 const_len;   /* = tmy_const_part_length(name)*/
+   u8 is_dir;   /* = tmy_strendswith(name, "/") */
+   u8 is_patterned; /* = PathContainsPattern(name)  */
+   u16 depth;   /* = tmy_path_depth(name)   */
+};
+
+#define TMY_MAX_PATHNAME_LEN 4000
+
+struct group_member {
+   struct group_member *next;
+   const struct path_info *member_name;
+   int is_deleted;
+};
+
+struct group_entry {
+   struct group_entry *next;
+   const struct path_info *group_name;
+   struct group_member *first_member;
+};
+
+
+struct mini_stat {
+   uid_t uid;
+   gid_t gid;
+   ino_t ino;
+};
+struct dentry;
+struct vfsmount;
+struct obj_info {
+   u8 validate_done;
+   u8 path1_valid;
+   u8 path1_parent_valid;
+   u8 path2_parent_valid;
+   struct dentry *path1_dentry;
+   struct vfsmount *path1_vfsmnt;
+   struct dentry *path2_dentry;
+   struct vfsmount *path2_vfsmnt;
+   struct mini_stat path1_stat;
+   /* I don't handle path2_stat for rename operation. */
+   struct mini_stat path1_parent_stat;
+   struct mini_stat path2_parent_stat;
+};
+struct condition_list;
+
+/*
+ *  TOMOYO uses the following structures.
+ *  Memory allocated for these structures are never kfree()ed.
+ *  Since no locks are used for reading,
+ *  assignment must be performed atomically.
+ */
+
+/  The structure for domains.  
/
+
+struct acl_info {
+   struct acl_info *next;
+   const struct condition_list *cond;
+   u8 type;
+   u8 is_deleted;
+} __attribute__((__packed__));
+
+struct domain_info {
+   struct domain_info *next;   /* NULL if none. */
+   struct acl_info *first_acl_ptr; /* NULL if none. */
+   const struct path_info *domainname; /* Never NULL.   */
+   u8 profile;
+   u8 is_deleted;
+   u8 quota_warned;
+};
+
+#define TMY_MAX_PROFILES 256
+
+struct file_acl {
+   /* t

[TOMOYO 02/15] Kconfig and Makefile for TOMOYO Linux.

2007-08-24 Thread Kentaro Takeda
Kconfig and Makefile for TOMOYO Linux.
TOMOYO Linux is placed in security/tomoyo .

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 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-08-23 21:25:12.0 +0900
+++ linux-2.6/security/Kconfig  2007-08-24 15:51:34.0 +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/Makefile2007-08-23 21:25:12.0 +0900
+++ linux-2.6/security/Makefile 2007-08-24 15:51:34.0 +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.0 +
+++ linux-2.6/security/tomoyo/Kconfig   2007-08-24 15:51:34.0 +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.0 +
+++ linux-2.6/security/tomoyo/Makefile  2007-08-24 15:51:34.0 +0900
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo.o tomoyo_func.o
+tomoyo_func-objs := domain.o common.o realpath.o audit.o file.o exec.o net.o 
mount.o signal.o condition.o
+EXTRA_CFLAGS += -Isecurity/tomoyo/include

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 01/15] Allow use of namespace_sem from LSM module.

2007-08-24 Thread Kentaro Takeda
TOMOYO Linux uses pathnames for auditing and controlling file access.
Therefore, namespace_sem is needed.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>
---
 fs/namespace.c|2 +-
 include/linux/mnt_namespace.h |2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

--- linux-2.6.orig/fs/namespace.c   2007-08-23 21:25:13.0 +0900
+++ linux-2.6/fs/namespace.c2007-08-24 15:51:34.0 +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);
--- linux-2.6.orig/include/linux/mnt_namespace.h2007-08-23 
21:25:13.0 +0900
+++ linux-2.6/include/linux/mnt_namespace.h 2007-08-24 15:51:34.0 
+0900
@@ -6,6 +6,8 @@
 #include 
 #include 
 
+extern struct rw_semaphore namespace_sem;
+
 struct mnt_namespace {
atomic_tcount;
struct vfsmount *   root;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 00/15] TOMOYO Linux - MAC based on process invocation histroy

2007-08-24 Thread Kentaro Takeda
s the administrator to judge (grant/reject)
  requests which that violated ACL manually while operating in
  "enforcing mode" without once rejecting these requests.
* TOMOYO Linux supports conditional ACL (e.g. owner of
  process/files etc.).

Documents about installing and experiencing TOMOYO Linux are available
at http://tomoyo.sourceforge.jp/en/2.1.x/ . Please try TOMOYO Linux.
Feedbacks are most welcome.


<>

OLS BoF material: 
http://sourceforge.jp/projects/tomoyo/document/ols2007-tomoyo-20070629.pdf
Previous submission: http://lkml.org/lkml/2007/6/13/58 , 
http://lkml.org/lkml/2007/6/14/55

Kentaro Takeda
NTT DATA CORPORATION
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO 1/9] Allow use of namespace_sem from LSM module.

2007-06-14 Thread Kentaro Takeda
> Looks whitespace-damaged to me.
>   Pavel
Oops, I sent patches with "Content-type: format=flowed" header.
I think your mail client converted tabs into spaces.
The orignal patches themselves are not whitespace-damaged.

http://kb.mozillazine.org/Plain_text_e-mail_(Thunderbird)

Kentaro Takeda

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [TOMOYO 0/9] TOMOYO Linux security module.

2007-06-14 Thread Kentaro Takeda

Uh, can we get some docs? Like how this is better than selinux, what
it does, how is it configured...?
Pavel


That message and its children were meant to be put
under the bellow message. Sorry for the confusion.
http://lkml.org/lkml/2007/6/13/58

Kentaro Takeda

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 5/9] Memory and pathname management functions.

2007-06-14 Thread Kentaro Takeda

We limit the maximum length of any string data (such as domainname and 
pathnames)
to TOMOYO_MAX_PATHNAME_LEN (which is 4000) bytes to fit within a single page.

Userland programs can obtain the amount of RAM currently used by TOMOYO from 
/proc interface.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/include/realpath.h |   46 +
security/tomoyo/realpath.c |  445 
+
2 files changed, 491 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/include/realpath.h 
linux-2.6.21.5-tomoyo/security/tomoyo/include/realpath.h
--- linux-2.6.21.5/security/tomoyo/include/realpath.h   1970-01-01 
09:00:00.0 +0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/include/realpath.h2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,46 @@
+/*
+ * security/tomoyo/include/realpath.h
+ *
+ * Get the canonicalized absolute pathnames. The basis for TOMOYO.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ *
+ */
+
+#ifndef _TOMOYO_REALPATH_H
+#define _TOMOYO_REALPATH_H
+
+struct path_info;
+
+/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
+int tomoyo_realpath_from_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 tomoyo_alloc(), so caller must tomoyo_free() */
+/* if these functions didn't return NULL. */
+char *tomoyo_realpath(const char *pathname);
+char *tomoyo_realpath_nofollow(const char *pathname);
+char *tomoyo_realpath_from_dentry(struct dentry *dentry, struct vfsmount *mnt);
+
+/* Allocate memory for structures. */
+/* The RAM is chunked, so NEVER try to kfree() the returned pointer. */
+void *tomoyo_alloc_element(const unsigned int size);
+
+/* Get used RAM size for tomoyo_alloc_elements(). */
+unsigned int tomoyo_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 *tomoyo_save_name(const char *name);
+
+/* Get used RAM size for tomoyo_save_name(). */
+unsigned int tomoyo_get_memory_used_for_save_name(void);
+
+unsigned int tomoyo_get_memory_used_for_dynamic(void);
+
+#endif
diff -ubBpErN linux-2.6.21.5/security/tomoyo/realpath.c 
linux-2.6.21.5-tomoyo/security/tomoyo/realpath.c
--- linux-2.6.21.5/security/tomoyo/realpath.c   1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/realpath.c2007-06-14 
15:06:37.0 +0900
@@ -0,0 +1,445 @@
+/*
+ * security/tomoyo/realpath.c
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "realpath.h"
+#include "tomoyo.h"
+
+extern int sbin_init_started;
+
+/* realpath handler */
+
+/*
+ * tomoyo_get_absolute_path - return the path of a dentry but ignores 
chroot'ed root.
+ * @dentry: dentry to report
+ * @vfsmnt: vfsmnt to which the dentry belongs
+ * @buffer: buffer to return value in
+ * @buflen: buffer length
+ *
+ * Caller holds the dcache_lock.
+ * Based on __d_path() in fs/dcache.c
+ *
+ * If dentry is a directory, trailing '/' is appended.
+ * Characters other than ' ' < c < 127 are converted to \ooo style octal 
string.
+ * Character \ is converted to \\ string.
+ */
+static int tomoyo_get_absolute_path(struct dentry *dentry,
+struct vfsmount *vfsmnt,
+char *buffer,
+int buflen)
+{
+   char *start = buffer;
+   char *end = buffer + buflen;
+   int is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
+
+   if (buflen < 256) goto out;
+
+   *--end = '\0';
+   buflen--;
+
+   for (;;) {
+   struct dentry *parent;
+
+   if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+   /* Global root? */
+   spin_lock(&vfsmount_lock);
+   if (vfsmnt->mnt_parent == vfsmnt) {
+   spin_unlock(&vfsmount_lock);
+   break;
+   }
+   dentry = vfsmnt->mnt_mountpoint;
+   vfsmnt = vfsmnt->mnt_parent;
+   spin_unlock(&vfsmount_lock);
+   continue;
+   }
+ 

[TOMOYO 6/9] Utility functions and /proc interface for policy manipulation.

2007-06-14 Thread Kentaro Takeda

This file contains utility functions for TOMOYO.

Any string data in TOMOYO Linux consists with ASCII printable characters (0x21 
to 0x7E)
so that userland application can separate monotonically using whitespaces and 
carrige returns.
Any wildcard character consists with "\" + one ASCII printable character,
so that wildcard characters can be expanded without changing existing names.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/common.c | 1576 
+++
1 file changed, 1576 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/common.c 
linux-2.6.21.5-tomoyo/security/tomoyo/common.c
--- linux-2.6.21.5/security/tomoyo/common.c 1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/common.c  2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,1576 @@
+/*
+ * security/tomoyo/common.c
+ *
+ * Common functions for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "realpath.h"
+#include "tomoyo.h"
+
+#if defined (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY)
+#define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY)
+#else
+#define MAX_ACCEPT_ENTRY 2048
+#endif
+
+static int tomoyo_read_control(struct file *file, char __user *buffer, const 
int buffer_len);
+
+/*  VARIABLES  */
+
+/* /sbin/init started? */
+int sbin_init_started = 0;
+
+const char *ccs_log_level = KERN_DEBUG;
+
+static struct {
+   const char *keyword;
+   unsigned int current_value;
+   const unsigned int max_value;
+} ccs_control_array[TOMOYO_MAX_CONTROL_INDEX] = {
+   [TOMOYO_PROFILE_COMMENT] = { "COMMENT", 0, 0 }, /* 
Reserved for string. */
+   [TOMOYO_MAC_FOR_FILE]= { "MAC_FOR_FILE",0, 3 },
+   [TOMOYO_MAX_ACCEPT_ENTRY]= { "MAX_ACCEPT_ENTRY",
MAX_ACCEPT_ENTRY, INT_MAX },
+   [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE",  1, 1 },
+   [TOMOYO_ALLOW_ENFORCE_GRACE] = { "ALLOW_ENFORCE_GRACE", 0, 1 },
+};
+
+struct profile {
+   unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
+   const struct path_info *comment;
+};
+
+static struct profile *profile_ptr[TOMOYO_MAX_PROFILES];
+
+/*  UTILITY FUNCTIONS  */
+
+static int  tomoyo_quiet_setup(char *str)
+{
+   ccs_control_array[TOMOYO_VERBOSE].current_value = 0;
+   return 0;
+}
+
+__setup("TOMOYO_QUIET", tomoyo_quiet_setup);
+
+/* Am I root? */
+static int tomoyo_is_root(void)
+{
+   return !current->uid && !current->euid;
+}
+
+/*
+ * Format string.
+ * Leading and trailing whitespaces are removed.
+ * Multiple whitespaces are packed into single space.
+ */
+static void tomoyo_normalize_line(unsigned char *buffer)
+{
+   unsigned char *sp = buffer, *dp = buffer;
+   int first = 1;
+   while (*sp && (*sp <= ' ' || *sp >= 127)) sp++;
+   while (*sp) {
+   if (!first) *dp++ = ' ';
+   first = 0;
+   while (*sp > ' ' && *sp < 127) *dp++ = *sp++;
+   while (*sp && (*sp <= ' ' || *sp >= 127)) sp++;
+   }
+   *dp = '\0';
+}
+
+/*
+ *  Check whether the given filename follows the naming rules.
+ *  Returns nonzero if follows, zero otherwise.
+ */
+int tomoyo_is_correct_path(const char *filename,
+   const int start_type,
+   const int pattern_type,
+   const int end_type,
+   const char *function)
+{
+   int contains_pattern = 0;
+   char c, d, e;
+   const char *original_filename = filename;
+   if (!filename) goto out;
+   c = *filename;
+   if (start_type == 1) { /* Must start with '/' */
+   if (c != '/') goto out;
+   } else if (start_type == -1) { /* Must not start with '/' */
+   if (c == '/') goto out;
+   }
+   if (c) c = * (strchr(filename, '\0') - 1);
+   if (end_type == 1) { /* Must end with '/' */
+   if (c != '/') goto out;
+   } else if (end_type == -1) { /* Must not end with '/' */
+   if (c == '/') goto out;
+   }
+   while ((c = *filename++) != '\0') {
+   if (c == '\\') {
+   switch ((c = *filename++)) {
+   case '\\':  /* "\\" */
+   continue;
+   case 

[TOMOYO 4/9] LSM adapter for TOMOYO.

2007-06-14 Thread Kentaro Takeda

This file contains wrapper functions for TOMOYO's file access control functions.
The main job is to find "struct vfsmount" that corresponds to "struct dentry"
passed to LSM hooks.

Since "struct vfsmount" is not passed to LSM hooks,
TOMOYO can't determine which pathnames was requested by the process
if bind mounts are used.

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 <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/tomoyo.c |  283 
+++
1 file changed, 283 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/tomoyo.c 
linux-2.6.21.5-tomoyo/security/tomoyo/tomoyo.c
--- linux-2.6.21.5/security/tomoyo/tomoyo.c 1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/tomoyo.c  2007-06-14 
15:11:57.0 +0900
@@ -0,0 +1,283 @@
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * LSM hooks for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tomoyo.h"
+
+/* The initial domain. */
+struct domain_info KERNEL_DOMAIN = { NULL, NULL, NULL, 0, 0, 0 };
+extern struct rw_semaphore namespace_sem;
+
+static struct kmem_cache *tomoyo_cachep = NULL;
+
+static int tomoyo_task_alloc_security(struct task_struct *p)
+{
+   struct tomoyo_security *ptr = kmem_cache_alloc(tomoyo_cachep, 
GFP_KERNEL);
+   if (!ptr)
+   return -ENOMEM;
+   memcpy(ptr, current->security, sizeof(*ptr));
+   p->security = ptr;
+   return 0;
+}
+
+static void tomoyo_task_free_security(struct task_struct *p)
+{
+   kmem_cache_free(tomoyo_cachep, p->security);
+}
+
+static int tomoyo_bprm_alloc_security(struct linux_binprm *bprm)
+{
+   bprm->security = ((struct tomoyo_security *) 
current->security)->domain_info;
+   return 0;
+}
+
+static int tomoyo_bprm_check_security(struct linux_binprm * bprm)
+{
+   struct domain_info *next_domain = NULL;
+   int retval = 0;
+   extern void tomoyo_load_policy(const char *filename);
+   extern int tomoyo_find_next_domain(struct linux_binprm *, struct 
domain_info **);
+   tomoyo_load_policy(bprm->filename);
+   if (!(((struct tomoyo_security *) current->security)->flags
+ & TOMOYO_CHECK_READ_FOR_OPEN_EXEC)) {
+   retval = tomoyo_find_next_domain(bprm, &next_domain);
+   if (retval == 0) {
+   ((struct tomoyo_security *) 
current->security)->domain_info = next_domain;
+   ((struct tomoyo_security *) current->security)->flags |=
+   TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
+   }
+   }
+   
+   return retval;
+}
+
+static void tomoyo_bprm_post_apply_creds(struct linux_binprm * bprm)
+{
+   bprm->security = ((struct tomoyo_security *) 
current->security)->domain_info;
+}
+
+static void tomoyo_bprm_free_security(struct linux_binprm * bprm)
+{
+   ((struct tomoyo_security *) current->security)->domain_info =
+   (struct domain_info *) bprm->security;
+   ((struct tomoyo_security *) current->security)->flags &=
+   ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
+}
+
+static int tomoyo_inode_permission(struct inode *inode, int mask, struct 
nameidata *nd)
+{
+   int flag = 0;
+   if (S_ISDIR(inode->i_mode)) /* ignore because inode is directory */
+   return 0;
+   if (!nd || !nd->dentry || !nd->mnt)
+   return 0;
+   if ((mask == MAY_EXEC) && (((struct tomoyo_security *) 
current->security)->flags &
+  TOMOYO_CHECK_READ_FOR_OPEN_EXEC))
+   mask = MAY_READ;
+   if ((mask == MAY_EXEC) || (mask == 0))
+   return 0;
+
+   if (mask == (MAY_READ | MAY_EXEC)) {
+   flag |= O_RDONLY + 1;
+   } else {
+   if (mask & MAY_READ)
+   flag |= O_RDONLY + 1;
+   if (mask & MAY_WRITE)
+   flag |= O_WRONLY + 1;
+   if ((mask & MAY_APPEND))
+   flag |= O_APPEND;
+   }
+   return tomoyo_check_open_permission(nd->dentry, nd->mnt, flag);
+}
+
+static int tomoyo_do_check_single_write_permission(int operation, struct 
dentry *dentry)
+{
+   struct mnt_namespace *namespace = current->nsproxy->mnt_ns;
+   struct

[TOMOYO 2/9] Kconfig and Makefile for TOMOYO Linux.

2007-06-14 Thread Kentaro Takeda

TOMOYO Linux 2.0 is implemented using LSM and auditing subsystem.
When you use TOMOYO, you need to enable auditing support and disable all 
features
(other than TOMOYO Linux) that use LSM because TOMOYO Linux 2.0 has to be 
built-in.
If you don't want to disable any features that use LSM, please use TOMOYO Linux 
1.4.1 instead.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/Kconfig |1 +
security/Makefile|1 +
security/tomoyo/Kconfig  |   22 ++
security/tomoyo/Makefile |3 +++
4 files changed, 27 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/Kconfig 
linux-2.6.21.5-tomoyo/security/Kconfig
--- linux-2.6.21.5/security/Kconfig 2007-06-12 03:37:06.0 +0900
+++ linux-2.6.21.5-tomoyo/security/Kconfig  2007-06-14 15:02:38.0 
+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

diff -ubBpErN linux-2.6.21.5/security/Makefile 
linux-2.6.21.5-tomoyo/security/Makefile
--- linux-2.6.21.5/security/Makefile2007-06-12 03:37:06.0 +0900
+++ linux-2.6.21.5-tomoyo/security/Makefile 2007-06-14 15:02:38.0 
+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/
diff -ubBpErN linux-2.6.21.5/security/tomoyo/Kconfig 
linux-2.6.21.5-tomoyo/security/tomoyo/Kconfig
--- linux-2.6.21.5/security/tomoyo/Kconfig  1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/Kconfig   2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,22 @@
+config SECURITY_TOMOYO
+   bool "TOMOYO Linux support"
+   depends on SECURITY && AUDIT
+   help
+ Say Y here to support TOMOYO Linux.
+
+ TOMOYO Linux is applicable to figuring out the system's behavior,
+ for TOMOYO uses the canonicalized absolute pathnames and
+ TreeView style domain transitions.
+
+config TOMOYO_MAX_ACCEPT_ENTRY
+   int "Default maximal count for accept mode"
+   default 2048
+   range 0 2147483647
+   depends on SECURITY_TOMOYO
+   help
+ This is the default value for maximal ACL entries
+ that are automatically appended into policy at "accept mode".
+ Some programs access thousands of objects, so running
+ such programs in "accept mode" dulls the system response
+ and consumes much memory.
+ This is the safeguard for such programs.
diff -ubBpErN linux-2.6.21.5/security/tomoyo/Makefile 
linux-2.6.21.5-tomoyo/security/tomoyo/Makefile
--- linux-2.6.21.5/security/tomoyo/Makefile 1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/Makefile  2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo.o tomoyo_func.o
+tomoyo_func-objs := domain.o common.o realpath.o file.o audit.o
+EXTRA_CFLAGS += -Isecurity/tomoyo/include
---

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 1/9] Allow use of namespace_sem from LSM module.

2007-06-14 Thread Kentaro Takeda

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

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
fs/namespace.c |2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff -ubBpErN linux-2.6.21.5/fs/namespace.c linux-2.6.21.5-tomoyo/fs/namespace.c
--- linux-2.6.21.5/fs/namespace.c   2007-06-12 03:37:06.0 +0900
+++ linux-2.6.21.5-tomoyo/fs/namespace.c2007-06-14 15:02:38.0 
+0900
@@ -37,7 +37,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);
---

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 3/9] Data structures and prototypes definition.

2007-06-14 Thread Kentaro Takeda

This is prototypes and structures definition.

Many of structures are single-linked list and memory allocated for them are 
never freed,
because entries used for access control needn't to be removed from the list so 
frequently
compared to general other entries in the kernel. This saves the amount of 
memory needed by TOMOYO.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/include/tomoyo.h |  319 
+++
1 file changed, 319 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/include/tomoyo.h 
linux-2.6.21.5-tomoyo/security/tomoyo/include/tomoyo.h
--- linux-2.6.21.5/security/tomoyo/include/tomoyo.h 1970-01-01 
09:00:00.0 +0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/include/tomoyo.h  2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,319 @@
+/*
+ * security/tomoyo/include/tomoyo.h
+ *
+ * Implementation of the Domain-Based Mandatory Access Control.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ *
+ */
+#ifndef _TOMOYO_H
+#define _TOMOYO_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* TOMOYO Linux start. */
+
+struct tomoyo_security {
+   struct domain_info *domain_info;
+   u32 flags;
+};
+
+struct path_info {
+   const char *name;
+   u32 hash;/* = full_name_hash(name, strlen(name)) */
+   u16 total_len;   /* = strlen(name)   */
+   u16 const_len;   /* = tomoyo_const_part_length(name)*/
+   u8 is_dir;   /* = tomoyo_strendswith(name, "/") */
+   u8 is_patterned; /* = PathContainsPattern(name)  */
+   u16 depth;   /* = tomoyo_path_depth(name)*/
+};
+
+#define TOMOYO_MAX_PATHNAME_LEN 4000
+
+struct group_member {
+   struct group_member *next;
+   const struct path_info *member_name;
+   int is_deleted;
+};
+
+struct group_entry {
+   struct group_entry *next;
+   const struct path_info *group_name;
+   struct group_member *first_member;
+};
+
+/*
+ *  TOMOYO uses the following structures.
+ *  Memory allocated for these structures are never kfree()ed.
+ *  Since no locks are used for reading, assignment must be performed 
atomically.
+ */
+
+/*  The structure for domains.  
*/
+
+struct acl_info {
+   struct acl_info *next;
+   u8 type;
+   u8 is_deleted;
+   union {
+   u16 w;
+   u8 b[2];
+   } u;
+};
+
+struct domain_info {
+   struct domain_info *next;   /* Pointer to next record. NULL if 
none. */
+   struct acl_info *first_acl_ptr; /* Pointer to first acl. NULL if 
none.   */
+   const struct path_info *domainname; /* Name of this domain. Never NULL. 
 */
+   u8 profile; /* Profile to use.  
 */
+   u8 is_deleted;  /* Delete flag. 
 */
+   u8 quota_warned;/* Quota warnning done flag.
 */
+};
+
+#define TOMOYO_MAX_PROFILES 256
+
+struct file_acl_record {
+   struct acl_info head; /* type = TOMOYO_TYPE_FILE_ACL, b[0] = perm, b[1] 
= u_is_group */
+   union {
+   const struct path_info *filename;   /* Pointer to single 
pathname. */
+   const struct group_entry *group;/* Pointer to pathname 
group.  */
+   } u;
+};
+
+struct single_acl_record {
+   struct acl_info head; /* type = TOMOYO_TYPE_*, w = 
u_is_group */
+   union {
+   const struct path_info *filename; /* Pointer to single 
pathname. */
+   const struct group_entry *group;  /* Pointer to pathname group. 
 */
+   } u;
+};
+
+struct double_acl_record {
+   /* type = TOMOYO_TYPE_RENAME_ACL or TOMOYO_TYPE_LINK_ACL, */
+   /* b[0] = u1_is_group, b[1] = u2_is_group */
+   struct acl_info head;
+   union {
+   const struct path_info *filename1;  /* Pointer to single 
pathname. */
+   const struct group_entry *group1;   /* Pointer to pathname 
group.  */
+   } u1;
+   union {
+   const struct path_info *filename2;  /* Pointer to single 
pathname. */
+   const struct group_entry *group2;   /* Pointer to pathname 
group.  */
+   } u2;
+};
+
+/*  Keywords for ACLs.  */
+
+#define TOMOYO_KEYWORD_AGGREGATOR   "aggregator "
+#define TOMOYO_KEYWORD_AGGREGATOR_LEN   
(sizeof(TOMOYO_KEYWORD_AGGREGATOR) - 1)
+#define TOMOYO_KEYWORD_ALIAS"alias "
+#define TOMOYO_KEYWORD_ALIAS_LEN(sizeof(TOMOYO_KEYWORD_ALIAS) 
- 1)
+#define TOMOYO_KEYWORD_

[TOMOYO 9/9] Domain transition handler functions.

2007-06-14 Thread Kentaro Takeda

This is the main part for domain transition.
In TOMOYO Linux, domains are automatically created at runtime.

To make discussion smooth by reducing the amount of patches,
we pruned argv[0] checks (although we referred the need of argv[0] checking
at AppArmor's thread, http://lkml.org/lkml/2007/5/26/52 ).

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/domain.c |  782 
+++
1 file changed, 782 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/domain.c 
linux-2.6.21.5-tomoyo/security/tomoyo/domain.c
--- linux-2.6.21.5/security/tomoyo/domain.c 1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/domain.c  2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,782 @@
+/*
+ * security/tomoyo/domain.c
+ *
+ * Domain transition functions for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#include 
+#include 
+
+#ifndef for_each_process
+#define for_each_process for_each_task
+#endif
+
+/*  VARIABLES  */
+
+/* /sbin/init started? */
+extern int sbin_init_started;
+
+/* Lock for appending domain's ACL. */
+DECLARE_MUTEX(domain_acl_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;
+   u8 is_oldstyle;
+};
+
+/* 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;
+   int is_deleted;
+};
+
+/* The structure for program files that should be aliased. */
+
+struct alias_entry {
+   struct alias_entry *next;
+   const struct path_info *original_name;
+   const struct path_info *aliased_name;
+   int is_deleted;
+};
+
+/*  VARIABLES  */
+
+/* Domain creation lock. */
+static DECLARE_MUTEX(new_domain_assign_lock);
+
+/*  UTILITY FUNCTIONS  */
+
+int tomoyo_is_domain_def(const unsigned char *buffer)
+{
+   /* while (*buffer && (*buffer <= ' ' || *buffer >= 127)) buffer++; */
+   return strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN) == 0;
+}
+
+const char *tomoyo_get_last_name(const struct domain_info *domain)
+{
+   const char *cp0 = domain->domainname->name, *cp1;
+   if ((cp1 = strrchr(cp0, ' ')) != NULL) return cp1 + 1;
+   return cp0;
+}
+
+int tomoyo_read_self_domain(struct io_buffer *head)
+{
+   if (!head->read_eof) {
+   tomoyo_io_printf(head,
+"%s",
+((struct tomoyo_security *) 
current->security)->domain_info->domainname->name);
+   head->read_eof = 1;
+   }
+   return 0;
+}
+
+int tomoyo_add_domain_acl(struct acl_info *ptr, struct domain_info *domain, 
struct acl_info *new_ptr)
+{
+   mb(); /* Instead of using spinlock. */
+   if (!ptr) domain->first_acl_ptr = (struct acl_info *) new_ptr;
+   else ptr->next = (struct acl_info *) new_ptr;
+   tomoyo_update_counter(TOMOYO_UPDATES_COUNTER_DOMAIN_POLICY);
+   return 0;
+}
+
+int tomoyo_del_domain_acl(struct acl_info *ptr)
+{
+   ptr->is_deleted = 1;
+   tomoyo_update_counter(TOMOYO_UPDATES_COUNTER_DOMAIN_POLICY);
+   return 0;
+}
+
+int tomoyo_too_many_domain_acl(struct domain_info * const domain) {
+   unsigned int count = 0;
+   struct acl_info *ptr;
+   for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+   if (!ptr->is_deleted) count++;
+   }
+   /* If there are so many entries, don't append if accept mode. */
+   if (count < tomoyo_check_flags(TOMOYO_MAX_ACCEPT_ENTRY)) return 0;
+   if (!domain->quota_warned) {
+   printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. "
+  "Stopped auto-append mode.\n", domain->domainname->name);
+   domain->quota_warned = 1;
+   }
+

[TOMOYO 8/9] File access control functions.

2007-06-14 Thread Kentaro Takeda

This is the main part for profiling and controlling file access.
We thought checking old pathname and new pathname separately
for rename() and link() operation is a too rough access control
and we are checking both pathnames using tomoyo_check_double_write_acl().

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/file.c | 1126 
+
1 file changed, 1126 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/file.c 
linux-2.6.21.5-tomoyo/security/tomoyo/file.c
--- linux-2.6.21.5/security/tomoyo/file.c   1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/file.c2007-06-05 
00:00:00.0 +0900
@@ -0,0 +1,1126 @@
+/*
+ * security/tomoyo/file.c
+ *
+ * File access control functions for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
+
+/*  VARIABLES  */
+
+extern struct semaphore domain_acl_lock;
+
+/* The structure for globally readable files. */
+
+struct globally_readable_file_entry {
+   struct globally_readable_file_entry *next;
+   const struct path_info *filename;
+   int is_deleted;
+};
+
+/* The structure for filename patterns. */
+
+struct pattern_entry {
+   struct pattern_entry *next;
+   const struct path_info *pattern;
+   int 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;
+   int is_deleted;
+};
+
+/* The structure for detailed write operations. */
+
+static struct {
+   const char *keyword;
+   const int paths;
+   int check_type;
+} acl_type_array[] = { /* mapping.txt */
+   { "create",   1, 1 }, /* TOMOYO_TYPE_CREATE_ACL */
+   { "unlink",   1, 1 }, /* TOMOYO_TYPE_UNLINK_ACL */
+   { "mkdir",1, 1 }, /* TOMOYO_TYPE_MKDIR_ACL */
+   { "rmdir",1, 1 }, /* TOMOYO_TYPE_RMDIR_ACL */
+   { "mkfifo",   1, 1 }, /* TOMOYO_TYPE_MKFIFO_ACL */
+   { "mksock",   1, 1 }, /* TOMOYO_TYPE_MKSOCK_ACL */
+   { "mkblock",  1, 1 }, /* TOMOYO_TYPE_MKBLOCK_ACL */
+   { "mkchar",   1, 1 }, /* TOMOYO_TYPE_MKCHAR_ACL */
+   { "truncate", 1, 1 }, /* TOMOYO_TYPE_TRUNCATE_ACL */
+   { "symlink",  1, 1 }, /* TOMOYO_TYPE_SYMLINK_ACL */
+   { "link", 2, 1 }, /* TOMOYO_TYPE_LINK_ACL */
+   { "rename",   2, 1 }, /* TOMOYO_TYPE_RENAME_ACL */
+   { "rewrite",  1, 1 }, /* TOMOYO_TYPE_REWRITE_ACL */
+   { NULL, 0, 0 }
+};
+
+/*  UTILITY FUNCTIONS  */
+
+const char *tomoyo_acltype2keyword(const unsigned int acl_type)
+{
+   return (acl_type < sizeof(acl_type_array) / sizeof(acl_type_array[0]))
+   ? acl_type_array[acl_type].keyword : NULL;
+}
+
+int tomoyo_acltype2paths(const unsigned int acl_type)
+{
+   return (acl_type < sizeof(acl_type_array) / sizeof(acl_type_array[0]))
+   ? acl_type_array[acl_type].paths : 0;
+}
+
+static unsigned int tomoyo_check_acl_flags(const unsigned int index)
+{
+   if (index < (sizeof(acl_type_array) / sizeof(acl_type_array[0])) - 1)
+   return acl_type_array[index].check_type;
+   printk("%s: Index %u is out of range. Fix the kernel source.\n", 
__FUNCTION__, index);
+   return 0;
+}
+
+static int tomoyo_strendswith(const char *name, const char *tail)
+{
+   int len;
+   if (!name || !tail) return 0;
+   len = strlen(name) - strlen(tail);
+   return len >= 0 && strcmp(name + len, tail) == 0;
+}
+
+static struct path_info *tomoyo_get_path(struct dentry *dentry, struct 
vfsmount *mnt)
+{
+   struct path_info_with_data { /* sizeof(struct path_info_with_data) <= 
PAGE_SIZE */
+   struct path_info head; /* Keep this first, this pointer is 
passed to tomoyo_free(). */
+   char bariier1[16];
+   char body[TOMOYO_MAX_PATHNAME_LEN];
+   char barrier2[16];
+   } *buf = tomoyo_alloc(sizeof(*buf));
+   if (buf) {
+   int error;
+   if ((error = tomoyo_realpath_from_dentry2(dentry,
+ mnt,
+ buf->body,
+ sizeof(buf->body) - 
1)) == 0) {
+   buf->head.name = buf->body;
+   tomoyo_fill_path_info(&buf->

[TOMOYO 7/9] Auditing interface.

2007-06-14 Thread Kentaro Takeda

This patch makes access logs sent to auditing subsystem.
Although TOMOYO Linux has /proc interface for access logs,
we were advised to use auditing subsystem (after we introduced
TOMOYO Linux 1.0 on December 2005, http://lkml.org/lkml/2005/12/21/63 )
and we did so in TOMOYO Linux 2.0.

Signed-off-by: Kentaro Takeda <[EMAIL PROTECTED]>
Signed-off-by: Tetsuo Handa <[EMAIL PROTECTED]>

---
security/tomoyo/audit.c |   52 

1 file changed, 52 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/audit.c 
linux-2.6.21.5-tomoyo/security/tomoyo/audit.c
--- linux-2.6.21.5/security/tomoyo/audit.c  1970-01-01 09:00:00.0 
+0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/audit.c   2007-06-14 
15:06:10.0 +0900
@@ -0,0 +1,52 @@
+/*
+ * security/tomoyo/audit.c
+ *
+ * Audit functions for TOMOYO Linux
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include "tomoyo.h"
+#include 
+
+/* move to include/linux/audit.h */
+#define AUDIT_TOMOYO 2001
+
+char *tomoyo_init_audit_log(int *len)
+{
+   char *buf;
+   struct timeval tv;
+   struct task_struct *task = current;
+   const char *domainname =
+   ((struct tomoyo_security *) 
current->security)->domain_info->domainname->name;
+   do_gettimeofday(&tv);
+   *len += strlen(domainname) + 256;
+   if ((buf = tomoyo_alloc(*len)) != NULL)
+   snprintf(buf,
+(*len) - 1,
+"#timestamp=%lu pid=%d uid=%d gid=%d euid=%d egid=%d "
+"suid=%d sgid=%d fsuid=%d fsgid=%d\n%s\n",
+tv.tv_sec, task->pid, task->uid, task->gid, task->euid, 
task->egid,
+task->suid, task->sgid, task->fsuid, task->fsgid, 
domainname);
+   return buf;
+}
+
+/*
+ * Write audit log.
+ * Caller must allocate buf with tomoyo_init_audit_log().
+ */
+int tomoyo_write_audit_log(char *buf, const int is_granted)
+{
+   struct audit_buffer *ab;
+   ab = audit_log_start(current->audit_context, GFP_KERNEL, AUDIT_TOMOYO);
+   if (ab) {
+   audit_log_format(ab,
+"%s\n%s",
+is_granted ? "TOMOYO_GRANT_LOG" : 
"TOMOYO_REJECT_LOG", buf);
+   audit_log_end(ab);
+   }
+   tomoyo_free(buf);
+   return ab ? 0 : -ENOMEM;
+}
---

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[TOMOYO 0/9] TOMOYO Linux security module.

2007-06-14 Thread Kentaro Takeda

The following patches are TOMOYO Linux 2.0.
TOMOYO Linux 2.0 is implemented as a LSM module.

If you want to use older kernel, please download from
http://osdn.dl.sourceforge.jp/tomoyo/25693/tomoyo-lsm-2.0-20070605.tar.gz
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/