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 16/30] Unmount restriction part.
Some partitions such as /proc/ /sys/ should not be unmounted
for proper operation.

This file forbids unmount operation for specified directory.

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_umount.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 157 insertions(+)

--- /dev/null
+++ linux-2.6.25-rc8-mm1/fs/sakura_umount.c
@@ -0,0 +1,157 @@
+/*
+ * fs/sakura_umount.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/mount.h>
+
+/* Structure for "deny_unmount" keyword. */
+struct no_umount_entry {
+ struct list1_head list;
+ const struct path_info *dir;
+ bool is_deleted;
+};
+
+/* The list for "struct no_umount_entry". */
+static LIST1_HEAD(no_umount_list);
+
+/**
+ * update_no_umount_acl - Update "struct no_umount_entry" list.
+ *
+ * @dir: The name of directrory.
+ * @is_delete: True if it is a delete request.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int update_no_umount_acl(const char *dir, const bool is_delete)
+{
+ struct no_umount_entry *new_entry;
+ struct no_umount_entry *ptr;
+ const struct path_info *saved_dir;
+ static DEFINE_MUTEX(lock);
+ int error = -ENOMEM;
+ if (!ccs_is_correct_path(dir, 1, 0, 1, __func__))
+ return -EINVAL;
+ saved_dir = ccs_save_name(dir);
+ if (!saved_dir)
+ return -ENOMEM;
+ mutex_lock(&lock);
+ list1_for_each_entry(ptr, &no_umount_list, list) {
+ if (ptr->dir != saved_dir)
+ 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->dir = saved_dir;
+ list1_add_tail_mb(&new_entry->list, &no_umount_list);
+ error = 0;
+ printk(KERN_CONT "%sDon't allow umount %s\n", ccs_log_level, dir);
+ out:
+ mutex_unlock(&lock);
+ ccs_update_counter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
+ return error;
+}
+
+/**
+ * ccs_may_umount - Check permission for unmount.
+ *
+ * @mnt: Pointer to "struct vfsmount".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+int ccs_may_umount(struct vfsmount *mnt)
+{
+ int error = -EPERM;
+ const char *dir0;
+ const u8 mode = ccs_check_flags(CCS_SAKURA_RESTRICT_UNMOUNT);
+ const bool is_enforce = (mode == 3);
+ struct no_umount_entry *ptr;
+ struct path_info dir;
+ bool found = false;
+ if (!mode)
+ return 0;
+ dir0 = ccs_realpath_from_dentry(mnt->mnt_root, mnt);
+ if (!dir0)
+ goto out;
+ dir.name = dir0;
+ ccs_fill_path_info(&dir);
+ list1_for_each_entry(ptr, &no_umount_list, list) {
+ if (ptr->is_deleted)
+ continue;
+ if (!ccs_path_matches_pattern(&dir, ptr->dir))
+ continue;
+ found = true;
+ break;
+ }
+ if (found) {
+ const char *exename = ccs_get_exe();
+ printk(KERN_WARNING "SAKURA-%s: umount %s "
+ "(pid=%d:exe=%s): Permission denied.\n",
+ ccs_get_msg(is_enforce), dir0, current->pid,
+ exename);
+ if (is_enforce)
+ error = ccs_check_supervisor("# %s is requesting\n"
+ "unmount %s\n",
+ exename, dir0);
+ ccs_free(exename);
+ }
+ ccs_free(dir0);
+ out:
+ if (!is_enforce)
+ error = 0;
+ return error;
+}
+
+/**
+ * ccs_write_no_umount_policy - Write "struct no_umount_entry" list.
+ *
+ * @data: String to parse.
+ * @is_delete: True if it is a delete request.
+ *
+ * Returns 0 on sucess, negative value otherwise.
+ */
+int ccs_write_no_umount_policy(char *data, const bool is_delete)
+{
+ return update_no_umount_acl(data, is_delete);
+}
+
+/**
+ * ccs_read_no_umount_policy - Read "struct no_umount_entry" list.
+ *
+ * @head: Pointer to "struct ccs_io_buffer".
+ *
+ * Returns true on success, false otherwise.
+ */
+bool ccs_read_no_umount_policy(struct ccs_io_buffer *head)
+{
+ struct list1_head *pos;
+ list1_for_each_cookie(pos, head->read_var2, &no_umount_list) {
+ struct no_umount_entry *ptr;
+ ptr = list1_entry(pos, struct no_umount_entry, list);
+ if (ptr->is_deleted)
+ continue;
+ if (!ccs_io_printf(head, KEYWORD_DENY_UNMOUNT "%s\n",
+ ptr->dir->name))
+ goto out;
+ }
+ return true;
+ out:
+ return false;
+}
--


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