From: Kentaro Takeda <takedakn@nttdata.co.jp>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org,
Kentaro Takeda <takedakn@nttdata.co.jp>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: [TOMOYO #6 retry 19/21] Conditional permission support.
Date: Wed, 09 Jan 2008 09:53:39 +0900 [thread overview]
Message-ID: <20080109005427.328134504@nttdata.co.jp> (raw)
In-Reply-To: 20080109005320.323184643@nttdata.co.jp
This patch allows administrators use conditional permission.
TOMOYO Linux supports conditional permission based on
process's UID,GID etc. and/or requested pathname's UID/GID.
Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/condition.c | 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_FSUID 3
+#define TASK_GID 4
+#define TASK_EGID 5
+#define TASK_SGID 6
+#define TASK_FSGID 7
+#define TASK_PID 8
+#define TASK_PPID 9
+#define PATH1_UID 10
+#define PATH1_GID 11
+#define PATH1_INO 12
+#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 condition part.
+ *
+ * Returns pointer to "struct condition_list" on success.
+ * Returns NULL on failure.
+ */
+const struct condition_list *tmy_assign_condition(const char *condition)
+{
+ const char *start;
+ struct condition_list *ptr;
+ struct condition_list *new_ptr;
+ unsigned long *ptr2;
+ int counter = 0;
+ int size;
+ int left;
+ int right;
+ unsigned long left_min = 0;
+ unsigned long left_max = 0;
+ unsigned long right_min = 0;
+ unsigned long right_max = 0;
+ if (strncmp(condition, "if ", 3))
+ return NULL;
+ condition += 3;
+ start = condition;
+ while (*condition) {
+ if (*condition == ' ')
+ condition++;
+ for (left = 0; left < MAX_KEYWORD; left++) {
+ if (strncmp(condition, cc_keyword[left].keyword,
+ cc_keyword[left].keyword_len))
+ continue;
+ condition += cc_keyword[left].keyword_len;
+ break;
+ }
+ if (left == MAX_KEYWORD) {
+ if (!tmy_parse_ulong(&left_min, &condition))
+ goto out;
+ counter++; /* body */
+ if (*condition != '-')
+ goto not_range1;
+ condition++;
+ if (!tmy_parse_ulong(&left_max, &condition)
+ || left_min > left_max)
+ goto out;
+ counter++; /* body */
+not_range1: ;
+ }
+ if (strncmp(condition, "!=", 2) == 0)
+ condition += 2;
+ else if (*condition == '=')
+ condition++;
+ else
+ goto out;
+ counter++; /* header */
+ for (right = 0; right < MAX_KEYWORD; right++) {
+ if (strncmp(condition, cc_keyword[right].keyword,
+ cc_keyword[right].keyword_len))
+ continue;
+ condition += cc_keyword[right].keyword_len;
+ break;
+ }
+ if (right == MAX_KEYWORD) {
+ if (!tmy_parse_ulong(&right_min, &condition))
+ goto out;
+ counter++; /* body */
+ if (*condition != '-')
+ goto not_range2;
+ condition++;
+ if (!tmy_parse_ulong(&right_max, &condition)
+ || right_min > right_max)
+ goto out;
+ counter++; /* body */
+not_range2: ;
+ }
+ }
+ size = sizeof(*new_ptr) + counter * sizeof(unsigned long);
+ new_ptr = tmy_alloc(size);
+ if (!new_ptr)
+ return NULL;
+ new_ptr->length = counter;
+ ptr2 = (unsigned long *) (((u8 *) new_ptr) + sizeof(*new_ptr));
+ condition = start;
+ while (*condition) {
+ unsigned int match = 0;
+ if (*condition == ' ')
+ condition++;
+ for (left = 0; left < MAX_KEYWORD; left++) {
+ if (strncmp(condition, cc_keyword[left].keyword,
+ cc_keyword[left].keyword_len))
+ continue;
+ condition += cc_keyword[left].keyword_len;
+ break;
+ }
+ if (left == MAX_KEYWORD) {
+ match |= tmy_parse_ulong(&left_min, &condition) << 2;
+ counter--; /* body */
+ if (*condition != '-')
+ goto not_range3;
+ condition++;
+ match |= tmy_parse_ulong(&left_max, &condition) << 4;
+ counter--; /* body */
+ left++;
+not_range3: ;
+ }
+ if (strncmp(condition, "!=", 2) == 0)
+ condition += 2;
+ else if (*condition == '=') {
+ match |= 1;
+ condition++;
+ } else
+ goto out2;
+ counter--; /* header */
+ for (right = 0; right < MAX_KEYWORD; right++) {
+ if (strncmp(condition, cc_keyword[right].keyword,
+ cc_keyword[right].keyword_len))
+ continue;
+ condition += cc_keyword[right].keyword_len;
+ break;
+ }
+ if (right == MAX_KEYWORD) {
+ match |= tmy_parse_ulong(&right_min, &condition) << 6;
+ counter--; /* body */
+ if (*condition != '-')
+ goto not_range4;
+ condition++;
+ match |= tmy_parse_ulong(&right_max, &condition) << 8;
+ counter--; /* body */
+ right++;
+not_range4: ;
+ }
+ if (counter < 0)
+ goto out2;
+ *ptr2++ = (match << 16) | (left << 8) | right;
+ if (left >= MAX_KEYWORD)
+ *ptr2++ = left_min;
+ if (left == MAX_KEYWORD + 1)
+ *ptr2++ = left_max;
+ if (right >= MAX_KEYWORD)
+ *ptr2++ = right_min;
+ if (right == MAX_KEYWORD + 1)
+ *ptr2++ = right_max;
+ }
+ {
+ static DEFINE_MUTEX(mutex);
+ struct condition_list *prev = NULL;
+ mutex_lock(&mutex);
+ for (ptr = &head; ptr; prev = ptr, ptr = ptr->next) {
+ /* Don't compare if size differs. */
+ if (ptr->length != new_ptr->length)
+ continue;
+ /*
+ * Compare ptr and new_ptr
+ * except ptr->next and new_ptr->next .
+ */
+ if (memcmp(((u8 *) ptr) + sizeof(ptr->next),
+ ((u8 *) new_ptr) + sizeof(new_ptr->next),
+ size - sizeof(ptr->next)))
+ continue;
+ /* Same entry found. Share this entry. */
+ tmy_free(new_ptr);
+ new_ptr = ptr;
+ goto ok;
+ }
+ /* Same entry not found. Save this entry. */
+ ptr = tmy_alloc_element(size);
+ if (ptr)
+ memmove(ptr, new_ptr, size);
+ tmy_free(new_ptr);
+ new_ptr = ptr;
+ /* Append to chain. */
+ prev->next = new_ptr;
+ok: ;
+ mutex_unlock(&mutex);
+ }
+ return new_ptr;
+out2: ;
+ tmy_free(new_ptr);
+out: ;
+ return NULL;
+}
+
+/* Get inode's attribute information. */
+static void tmy_get_attributes(struct obj_info *obj)
+{
+ struct vfsmount *mnt;
+ struct dentry *dentry;
+ struct inode *inode;
+ struct kstat stat;
+
+ mnt = obj->path1_vfsmnt;
+ dentry = obj->path1_dentry;
+ inode = dentry->d_inode;
+ if (inode) {
+ if (!inode->i_op || vfs_getattr(mnt, dentry, &stat)) {
+ /* Nothing to do. */
+ } else {
+ obj->path1_stat.uid = stat.uid;
+ obj->path1_stat.gid = stat.gid;
+ obj->path1_stat.ino = stat.ino;
+ obj->path1_valid = 1;
+ }
+ }
+
+ dentry = dget_parent(obj->path1_dentry);
+ inode = dentry->d_inode;
+ if (inode) {
+ if (!inode->i_op || vfs_getattr(mnt, dentry, &stat)) {
+ /* Nothing to do. */
+ } else {
+ obj->path1_parent_stat.uid = stat.uid;
+ obj->path1_parent_stat.gid = stat.gid;
+ obj->path1_parent_stat.ino = stat.ino;
+ obj->path1_parent_valid = 1;
+ }
+ }
+ dput(dentry);
+
+ mnt = obj->path2_vfsmnt;
+ if (mnt) {
+ dentry = dget_parent(obj->path2_dentry);
+ inode = dentry->d_inode;
+ if (inode) {
+ if (!inode->i_op || vfs_getattr(mnt, dentry, &stat)) {
+ /* Nothing to do. */
+ } else {
+ obj->path2_parent_stat.uid = stat.uid;
+ obj->path2_parent_stat.gid = stat.gid;
+ obj->path2_parent_stat.ino = stat.ino;
+ obj->path2_parent_valid = 1;
+ }
+ }
+ dput(dentry);
+ }
+}
+
+/**
+ * tmy_check_condition - check condition part.
+ * @ptr: pointer to "struct condition_list".
+ * @obj: pointer to "struct obj_info". May be NULL.
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ */
+int tmy_check_condition(const struct condition_list *ptr, struct obj_info *obj)
+{
+ struct task_struct *task = current;
+ int i;
+ unsigned long left_min = 0;
+ unsigned long left_max = 0;
+ unsigned long right_min = 0;
+ unsigned long right_max = 0;
+ const unsigned long *ptr2;
+ if (!ptr)
+ return 0;
+ ptr2 = (unsigned long *) (((u8 *) ptr) + sizeof(*ptr));
+ for (i = 0; i < ptr->length; i++) {
+ const bool match = ((*ptr2) >> 16) & 1;
+ const u8 left = (*ptr2) >> 8;
+ const u8 right = *ptr2;
+ ptr2++;
+ if ((left >= PATH1_UID && left < MAX_KEYWORD)
+ || (right >= PATH1_UID && right < MAX_KEYWORD)) {
+ if (!obj)
+ goto out;
+ if (!obj->validate_done) {
+ tmy_get_attributes(obj);
+ obj->validate_done = 1;
+ }
+ }
+ switch (left) {
+ case TASK_UID:
+ left_min = task->uid;
+ left_max = left_min;
+ break;
+ case TASK_EUID:
+ left_min = task->euid;
+ left_max = left_min;
+ break;
+ case TASK_SUID:
+ left_min = task->suid;
+ left_max = left_min;
+ break;
+ case TASK_FSUID:
+ left_min = task->fsuid;
+ left_max = left_min;
+ break;
+ case TASK_GID:
+ left_min = task->gid;
+ left_max = left_min;
+ break;
+ case TASK_EGID:
+ left_min = task->egid;
+ left_max = left_min;
+ break;
+ case TASK_SGID:
+ left_min = task->sgid;
+ left_max = left_min;
+ break;
+ case TASK_FSGID:
+ left_min = task->fsgid;
+ left_max = left_min;
+ break;
+ case TASK_PID:
+ left_min = task->pid;
+ left_max = left_min;
+ break;
+ case TASK_PPID:
+ left_min = sys_getppid();
+ left_max = left_min;
+ break;
+ case PATH1_UID:
+ if (!obj->path1_valid)
+ goto out;
+ left_min = obj->path1_stat.uid;
+ left_max = left_min;
+ break;
+ case PATH1_GID:
+ if (!obj->path1_valid)
+ goto out;
+ left_min = obj->path1_stat.gid;
+ left_max = left_min;
+ break;
+ case PATH1_INO:
+ if (!obj->path1_valid)
+ goto out;
+ left_min = obj->path1_stat.ino;
+ left_max = left_min;
+ break;
+ case PATH1_PARENT_UID:
+ if (!obj->path1_parent_valid)
+ goto out;
+ left_min = obj->path1_parent_stat.uid;
+ left_max = left_min;
+ break;
+ case PATH1_PARENT_GID:
+ if (!obj->path1_parent_valid)
+ goto out;
+ left_min = obj->path1_parent_stat.gid;
+ left_max = left_min;
+ break;
+ case PATH1_PARENT_INO:
+ if (!obj->path1_parent_valid)
+ goto out;
+ left_min = obj->path1_parent_stat.ino;
+ left_max = left_min;
+ break;
+ case PATH2_PARENT_UID:
+ if (!obj->path2_parent_valid)
+ goto out;
+ left_min = obj->path2_parent_stat.uid;
+ left_max = left_min;
+ break;
+ case PATH2_PARENT_GID:
+ if (!obj->path2_parent_valid)
+ goto out;
+ left_min = obj->path2_parent_stat.gid;
+ left_max = left_min;
+ break;
+ case PATH2_PARENT_INO:
+ if (!obj->path2_parent_valid)
+ goto out;
+ left_min = obj->path2_parent_stat.ino;
+ left_max = left_min;
+ break;
+ case MAX_KEYWORD:
+ left_min = *ptr2++;
+ left_max = left_min;
+ i++;
+ break;
+ case MAX_KEYWORD + 1:
+ left_min = *ptr2++;
+ left_max = *ptr2++;
+ i += 2;
+ break;
+ }
+ switch (right) {
+ case TASK_UID:
+ right_min = task->uid;
+ right_max = right_min;
+ break;
+ case TASK_EUID:
+ right_min = task->euid;
+ right_max = right_min;
+ break;
+ case TASK_SUID:
+ right_min = task->suid;
+ right_max = right_min;
+ break;
+ case TASK_FSUID:
+ right_min = task->fsuid;
+ right_max = right_min;
+ break;
+ case TASK_GID:
+ right_min = task->gid;
+ right_max = right_min;
+ break;
+ case TASK_EGID:
+ right_min = task->egid;
+ right_max = right_min;
+ break;
+ case TASK_SGID:
+ right_min = task->sgid;
+ right_max = right_min;
+ break;
+ case TASK_FSGID:
+ right_min = task->fsgid;
+ right_max = right_min;
+ break;
+ case TASK_PID:
+ right_min = task->pid;
+ right_max = right_min;
+ break;
+ case TASK_PPID:
+ right_min = sys_getppid();
+ right_max = right_min;
+ break;
+ case PATH1_UID:
+ if (!obj->path1_valid)
+ goto out;
+ right_min = obj->path1_stat.uid;
+ right_max = right_min;
+ break;
+ case PATH1_GID:
+ if (!obj->path1_valid)
+ goto out;
+ right_min = obj->path1_stat.gid;
+ right_max = right_min;
+ break;
+ case PATH1_INO:
+ if (!obj->path1_valid)
+ goto out;
+ right_min = obj->path1_stat.ino;
+ right_max = right_min;
+ break;
+ case PATH1_PARENT_UID:
+ if (!obj->path1_parent_valid)
+ goto out;
+ right_min = obj->path1_parent_stat.uid;
+ right_max = right_min;
+ break;
+ case PATH1_PARENT_GID:
+ if (!obj->path1_parent_valid)
+ goto out;
+ right_min = obj->path1_parent_stat.gid;
+ right_max = right_min;
+ break;
+ case PATH1_PARENT_INO:
+ if (!obj->path1_parent_valid)
+ goto out;
+ right_min = obj->path1_parent_stat.ino;
+ right_max = right_min;
+ break;
+ case PATH2_PARENT_UID:
+ if (!obj->path2_parent_valid)
+ goto out;
+ right_min = obj->path2_parent_stat.uid;
+ right_max = right_min;
+ break;
+ case PATH2_PARENT_GID:
+ if (!obj->path2_parent_valid)
+ goto out;
+ right_min = obj->path2_parent_stat.gid;
+ right_max = right_min;
+ break;
+ case PATH2_PARENT_INO:
+ if (!obj->path2_parent_valid)
+ goto out;
+ right_min = obj->path2_parent_stat.ino;
+ right_max = right_min;
+ break;
+ case MAX_KEYWORD:
+ right_min = *ptr2++;
+ right_max = right_min;
+ i++;
+ break;
+ case MAX_KEYWORD + 1:
+ right_min = *ptr2++;
+ right_max = *ptr2++;
+ i += 2;
+ break;
+ }
+ if (match) {
+ if (left_min <= right_max && left_max >= right_min)
+ continue;
+ } else {
+ if (left_min > right_max || left_max < right_min)
+ continue;
+ }
+out: ;
+ return -EPERM;
+ }
+ return 0;
+}
+
+/**
+ * tmy_dump_condition - dump condition part.
+ * @head: pointer to "struct io_buffer".
+ * @ptr: pointer to "struct condition_list". May be NULL.
+ *
+ * Returns nonzero if reading incomplete.
+ * Returns zero otherwise.
+ */
+int tmy_dump_condition(struct io_buffer *head, const struct condition_list *ptr)
+{
+ int i;
+ const unsigned long *ptr2;
+ char buffer[32];
+ if (!ptr)
+ goto last;
+ ptr2 = (unsigned long *) (((u8 *) ptr) + sizeof(*ptr));
+ memset(buffer, 0, sizeof(buffer));
+ for (i = 0; i < ptr->length; i++) {
+ const u16 match = (*ptr2) >> 16;
+ const u8 left = (*ptr2) >> 8;
+ const u8 right = *ptr2;
+ ptr2++;
+ if (tmy_io_printf(head, "%s", i ? " " : " if "))
+ break;
+ if (left < MAX_KEYWORD) {
+ if (tmy_io_printf(head, "%s", cc_keyword[left].keyword))
+ break;
+ } else {
+ tmy_print_ulong(buffer, sizeof(buffer) - 1, *ptr2++,
+ (match >> 2) & 3);
+ if (tmy_io_printf(head, "%s", buffer))
+ break;
+ i++;
+ if (left == MAX_KEYWORD + 1) {
+ tmy_print_ulong(buffer, sizeof(buffer) - 1,
+ *ptr2++, (match >> 4) & 3);
+ if (tmy_io_printf(head, "-%s", buffer))
+ break;
+ i++;
+ }
+ }
+ if (tmy_io_printf(head, "%s", (match & 1) ? "=" : "!="))
+ break;
+ if (right < MAX_KEYWORD) {
+ if (tmy_io_printf(head, "%s",
+ cc_keyword[right].keyword))
+ break;
+ } else {
+ tmy_print_ulong(buffer, sizeof(buffer) - 1, *ptr2++,
+ (match >> 6) & 3);
+ if (tmy_io_printf(head, "%s", buffer))
+ break;
+ i++;
+ if (right == MAX_KEYWORD + 1) {
+ tmy_print_ulong(buffer, sizeof(buffer) - 1,
+ *ptr2++, (match >> 8) & 3);
+ if (tmy_io_printf(head, "-%s", buffer))
+ break;
+ i++;
+ }
+ }
+ }
+ if (i < ptr->length)
+ return -ENOMEM;
+last: ;
+ return tmy_io_printf(head, "\n") ? -ENOMEM : 0;
+}
--
next prev parent reply other threads:[~2008-01-09 1:02 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-09 0:53 [TOMOYO #6 retry 00/21] TOMOYO Linux - MAC based on process invocation history Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 01/21] TOMOYO Linux documentation Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 02/21] Add struct vfsmount to struct task_struct Kentaro Takeda
2008-01-15 21:16 ` Serge E. Hallyn
2008-01-16 0:22 ` Kentaro Takeda
2008-01-16 14:39 ` Serge E. Hallyn
2008-01-17 4:55 ` Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 03/21] Add wrapper functions for VFS helper functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 04/21] Replace VFS with wrapper functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 05/21] Add packet filtering based on processs security context Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 06/21] Data structures and prototype defitions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 07/21] Memory and pathname management functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 08/21] Utility functions and policy manipulation interface Kentaro Takeda
2008-01-09 4:25 ` James Morris
2008-01-09 4:29 ` James Morris
2008-01-12 2:06 ` [TOMOYO #6 retry 08/21] Utility functions and policy manipulationinterface Tetsuo Handa
2008-01-12 3:06 ` James Morris
2008-01-12 4:45 ` Greg KH
2008-01-12 7:34 ` [TOMOYO #6 retry 08/21] Utility functions and policymanipulationinterface Tetsuo Handa
2008-01-09 4:31 ` [TOMOYO #6 retry 08/21] Utility functions and policy manipulation interface Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 09/21] Domain transition functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 10/21] Auditing interface Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 11/21] File access control functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 12/21] argv0 check functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 13/21] environment variable name " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 14/21] Network access control functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 15/21] Namespace manipulation " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 16/21] Signal " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 17/21] Capability access " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 18/21] LSM adapter functions Kentaro Takeda
2008-01-09 0:53 ` Kentaro Takeda [this message]
2008-01-09 0:53 ` [TOMOYO #6 retry 20/21] Kconfig and Makefile Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 21/21] Add signal hooks at sleepable location Kentaro Takeda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080109005427.328134504@nttdata.co.jp \
--to=takedakn@nttdata.co.jp \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.