lkml.org 
[lkml]   [2008]   [Apr]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[TOMOYO #7 18/30] pivot_root restriction part.
This file controls pivot_root() requests.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Toshiharu Harada <haradats@nttdata.co.jp>
---
fs/sakura_pivot.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 185 insertions(+)

--- /dev/null
+++ linux-2.6.25-rc8-mm1/fs/sakura_pivot.c
@@ -0,0 +1,185 @@
+/*
+ * fs/sakura_pivot.c
+ *
+ * Implementation of the Domain-Free Mandatory Access Control.
+ *
+ * Copyright (C) 2005-2008 NTT DATA CORPORATION
+ *
+ * Version: 1.6.0 2008/04/01
+ *
+ */
+
+#include <linux/ccs_common.h>
+#include <linux/sakura.h>
+#include <linux/realpath.h>
+#include <linux/namei.h>
+
+/* Structure for "allow_pivot_root" keyword. */
+struct pivot_root_entry {
+ struct list1_head list;
+ const struct path_info *old_root;
+ const struct path_info *new_root;
+ bool is_deleted;
+};
+
+/* The list for "struct pivot_root_entry". */
+static LIST1_HEAD(pivot_root_list);
+
+/**
+ * update_pivot_root_acl - Update "struct pivot_root_entry" list.
+ *
+ * @old_root: The name of old root directory.
+ * @new_root: The name of new root directory.
+ * @is_delete: True if it is a delete request.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int update_pivot_root_acl(const char *old_root, const char *new_root,
+ const bool is_delete)
+{
+ struct pivot_root_entry *new_entry;
+ struct pivot_root_entry *ptr;
+ const struct path_info *saved_old_root;
+ const struct path_info *saved_new_root;
+ static DEFINE_MUTEX(lock);
+ int error = -ENOMEM;
+ if (!ccs_is_correct_path(old_root, 1, 0, 1, __func__) ||
+ !ccs_is_correct_path(new_root, 1, 0, 1, __func__))
+ return -EINVAL;
+ saved_old_root = ccs_save_name(old_root);
+ saved_new_root = ccs_save_name(new_root);
+ if (!saved_old_root || !saved_new_root)
+ return -ENOMEM;
+ mutex_lock(&lock);
+ list1_for_each_entry(ptr, &pivot_root_list, list) {
+ if (ptr->old_root != saved_old_root ||
+ ptr->new_root != saved_new_root)
+ continue;
+ ptr->is_deleted = is_delete;
+ error = 0;
+ goto out;
+ }
+ if (is_delete) {
+ error = -ENOENT;
+ goto out;
+ }
+ new_entry = ccs_alloc_element(sizeof(*new_entry));
+ if (!new_entry)
+ goto out;
+ new_entry->old_root = saved_old_root;
+ new_entry->new_root = saved_new_root;
+ list1_add_tail_mb(&new_entry->list, &pivot_root_list);
+ error = 0;
+ printk(KERN_CONT "%sAllow pivot_root(%s, %s)\n", ccs_log_level,
+ new_root, old_root);
+ out:
+ mutex_unlock(&lock);
+ ccs_update_counter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
+ return error;
+}
+
+/**
+ * ccs_check_pivot_root_permission - Check permission for pivot_root().
+ *
+ * @old_nd: Pointer to "struct nameidata".
+ * @new_nd: Pointer to "struct nameidata".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+int ccs_check_pivot_root_permission(struct nameidata *old_nd,
+ struct nameidata *new_nd)
+{
+ int error = -EPERM;
+ char *old_root, *new_root;
+ const u8 mode = ccs_check_flags(CCS_SAKURA_RESTRICT_PIVOT_ROOT);
+ if (!mode)
+ return 0;
+ old_root = ccs_realpath_from_dentry(old_nd->path.dentry,
+ old_nd->path.mnt);
+ new_root = ccs_realpath_from_dentry(new_nd->path.dentry,
+ new_nd->path.mnt);
+ if (old_root && new_root) {
+ struct path_info old_root_dir, new_root_dir;
+ old_root_dir.name = old_root;
+ ccs_fill_path_info(&old_root_dir);
+ new_root_dir.name = new_root;
+ ccs_fill_path_info(&new_root_dir);
+ if (old_root_dir.is_dir && new_root_dir.is_dir) {
+ struct pivot_root_entry *ptr;
+ list1_for_each_entry(ptr, &pivot_root_list, list) {
+ if (ptr->is_deleted)
+ continue;
+ if (!ccs_path_matches_pattern(&old_root_dir,
+ ptr->old_root) ||
+ !ccs_path_matches_pattern(&new_root_dir,
+ ptr->new_root))
+ continue;
+ error = 0;
+ break;
+ }
+ }
+ }
+ if (error) {
+ const bool is_enforce = (mode == 3);
+ const char *exename = ccs_get_exe();
+ printk(KERN_WARNING "SAKURA-%s: pivot_root %s %s "
+ "(pid=%d:exe=%s): Permission denied.\n",
+ ccs_get_msg(is_enforce), new_root, old_root,
+ current->pid, exename);
+ if (is_enforce)
+ error = ccs_check_supervisor("# %s is requesting\n"
+ "pivot_root %s %s\n",
+ exename, new_root,
+ old_root);
+ else
+ error = 0;
+ if (exename)
+ ccs_free(exename);
+ if (mode == 1 && old_root && new_root)
+ update_pivot_root_acl(old_root, new_root, 0);
+ }
+ ccs_free(old_root);
+ ccs_free(new_root);
+ return error;
+}
+
+/**
+ * ccs_write_pivot_root_policy - Write "struct pivot_root_entry" list.
+ *
+ * @data: String to parse.
+ * @is_delete: True if it is a delete request.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+int ccs_write_pivot_root_policy(char *data, const bool is_delete)
+{
+ char *cp = strchr(data, ' ');
+ if (!cp)
+ return -EINVAL;
+ *cp++ = '\0';
+ return update_pivot_root_acl(cp, data, is_delete);
+}
+
+/**
+ * ccs_read_pivot_root_policy - Read "struct pivot_root_entry" list.
+ *
+ * @head: Pointer to "struct ccs_io_buffer".
+ *
+ * Returns true on success, false otherwise.
+ */
+bool ccs_read_pivot_root_policy(struct ccs_io_buffer *head)
+{
+ struct list1_head *pos;
+ list1_for_each_cookie(pos, head->read_var2, &pivot_root_list) {
+ struct pivot_root_entry *ptr;
+ ptr = list1_entry(pos, struct pivot_root_entry, list);
+ if (ptr->is_deleted)
+ continue;
+ if (!ccs_io_printf(head, KEYWORD_ALLOW_PIVOT_ROOT "%s %s\n",
+ ptr->new_root->name, ptr->old_root->name))
+ goto out;
+ }
+ return true;
+ out:
+ return false;
+}
--


\
 
 \ /
  Last update: 2008-04-04 14:59    [W:1.571 / U:0.024 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site