オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Diff of /trunk/1.6.x/ccs-patch/fs/sakura_chroot.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/1.5.x/ccs-patch/fs/sakura_chroot.c revision 731 by kumaneko, Tue Nov 27 04:48:59 2007 UTC trunk/1.6.x/ccs-patch/fs/sakura_chroot.c revision 1076 by kumaneko, Tue Apr 1 02:31:01 2008 UTC
# Line 3  Line 3 
3   *   *
4   * Implementation of the Domain-Free Mandatory Access Control.   * Implementation of the Domain-Free Mandatory Access Control.
5   *   *
6   * Copyright (C) 2005-2007  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.5.2-pre   2007/11/27   * Version: 1.6.0   2008/04/01
9   *   *
10   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
11   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
12   *   *
13   */   */
 /***** SAKURA Linux start. *****/  
14    
15  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
16  #include <linux/sakura.h>  #include <linux/sakura.h>
17  #include <linux/realpath.h>  #include <linux/realpath.h>
18  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
19  #include <linux/namei.h>  #include <linux/namei.h>
20  #else  #else
21  #include <linux/fs.h>  #include <linux/fs.h>
22  #endif  #endif
23    
24  extern const char *ccs_log_level;  /* Structure for "allow_chroot" keyword. */
   
 /***** The structure for chroot restrictions. *****/  
   
25  struct chroot_entry {  struct chroot_entry {
26          struct list1_head list;          struct list1_head list;
27          const struct path_info *dir;          const struct path_info *dir;
28          bool is_deleted;          bool is_deleted;
29  };  };
30    
31  /*************************  CHROOT RESTRICTION HANDLER  *************************/  /* The list for "struct chroot_entry". */
   
32  static LIST1_HEAD(chroot_list);  static LIST1_HEAD(chroot_list);
33    
34  static int AddChrootACL(const char *dir, const bool is_delete)  /**
35     * update_chroot_acl - Update "struct chroot_entry" list.
36     *
37     * @dir:       The name of directory.
38     * @is_delete: True if it is a delete request.
39     *
40     * Returns 0 on success, negative value otherwise.
41     */
42    static int update_chroot_acl(const char *dir, const bool is_delete)
43  {  {
44          struct chroot_entry *new_entry, *ptr;          struct chroot_entry *new_entry;
45            struct chroot_entry *ptr;
46          const struct path_info *saved_dir;          const struct path_info *saved_dir;
47          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
48          int error = -ENOMEM;          int error = -ENOMEM;
49          if (!IsCorrectPath(dir, 1, 0, 1, __FUNCTION__)) return -EINVAL;          if (!ccs_is_correct_path(dir, 1, 0, 1, __func__))
50          if ((saved_dir = SaveName(dir)) == NULL) return -ENOMEM;                  return -EINVAL;
51            saved_dir = ccs_save_name(dir);
52            if (!saved_dir)
53                    return -ENOMEM;
54          mutex_lock(&lock);          mutex_lock(&lock);
55          list1_for_each_entry(ptr, &chroot_list, list) {          list1_for_each_entry(ptr, &chroot_list, list) {
56                  if (ptr->dir == saved_dir) {                  if (ptr->dir != saved_dir)
57                          ptr->is_deleted = is_delete;                          continue;
58                          error = 0;                  ptr->is_deleted = is_delete;
59                          goto out;                  error = 0;
60                  }                  goto out;
61          }          }
62          if (is_delete) {          if (is_delete) {
63                  error = -ENOENT;                  error = -ENOENT;
64                  goto out;                  goto out;
65          }          }
66          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;          new_entry = ccs_alloc_element(sizeof(*new_entry));
67            if (!new_entry)
68                    goto out;
69          new_entry->dir = saved_dir;          new_entry->dir = saved_dir;
70          list1_add_tail_mb(&new_entry->list, &chroot_list);          list1_add_tail_mb(&new_entry->list, &chroot_list);
71          error = 0;          error = 0;
72          printk("%sAllow chroot() to %s\n", ccs_log_level, dir);          printk(KERN_CONT "%sAllow chroot() to %s\n", ccs_log_level, dir);
73   out:   out:
74          mutex_unlock(&lock);          mutex_unlock(&lock);
75            ccs_update_counter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
76          return error;          return error;
77  }  }
78    
79  int CheckChRootPermission(struct nameidata *nd)  /**
80     * print_error - Print error message.
81     *
82     * @root_name: Requested directory name.
83     * @mode:      Access control mode.
84     *
85     * Returns 0 if @mode is not enforcing mode or permitted by the administrator's
86     * decision, negative value otherwise.
87     */
88    static int print_error(const char *root_name, const u8 mode)
89    {
90            int error;
91            const bool is_enforce = (mode == 3);
92            const char *exename = ccs_get_exe();
93            printk(KERN_WARNING "SAKURA-%s: chroot %s (pid=%d:exe=%s): "
94                   "Permission denied.\n", ccs_get_msg(is_enforce),
95                   root_name, current->pid, exename);
96            if (is_enforce)
97                    error = ccs_check_supervisor("# %s is requesting\n"
98                                                 "chroot %s\n", exename, root_name);
99            else
100                    error = 0;
101            if (exename)
102                    ccs_free(exename);
103            if (mode == 1 && root_name)
104                    update_chroot_acl(root_name, false);
105            return error;
106    }
107    
108    /**
109     * ccs_check_chroot_permission - Check permission for chroot().
110     *
111     * @nd: Pointer to "struct nameidata".
112     *
113     * Returns 0 on success, negative value otherwise.
114     */
115    int ccs_check_chroot_permission(struct nameidata *nd)
116  {  {
117          int error = -EPERM;          int error = -EPERM;
118          char *root_name;          char *root_name;
119          if (!CheckCCSFlags(CCS_SAKURA_RESTRICT_CHROOT)) return 0;          const u8 mode = ccs_check_flags(CCS_SAKURA_RESTRICT_CHROOT);
120          root_name = realpath_from_dentry(nd->dentry, nd->mnt);          if (!mode)
121                    return 0;
122    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
123            root_name = ccs_realpath_from_dentry(nd->path.dentry, nd->path.mnt);
124    #else
125            root_name = ccs_realpath_from_dentry(nd->dentry, nd->mnt);
126    #endif
127          if (root_name) {          if (root_name) {
128                  struct path_info dir;                  struct path_info dir;
129                  dir.name = root_name;                  dir.name = root_name;
130                  fill_path_info(&dir);                  ccs_fill_path_info(&dir);
131                  if (dir.is_dir) {                  if (dir.is_dir) {
132                          struct chroot_entry *ptr;                          struct chroot_entry *ptr;
133                          list1_for_each_entry(ptr, &chroot_list, list) {                          list1_for_each_entry(ptr, &chroot_list, list) {
134                                  if (ptr->is_deleted) continue;                                  if (ptr->is_deleted)
135                                  if (PathMatchesToPattern(&dir, ptr->dir)) {                                          continue;
136                                          error = 0;                                  if (!ccs_path_matches_pattern(&dir, ptr->dir))
137                                          break;                                          continue;
138                                  }                                  error = 0;
139                                    break;
140                          }                          }
141                  }                  }
142          }          }
143          if (error) {          if (error)
144                  const bool is_enforce = CheckCCSEnforce(CCS_SAKURA_RESTRICT_CHROOT);                  error = print_error(root_name, mode);
                 const char *exename = GetEXE();  
                 printk("SAKURA-%s: chroot %s (pid=%d:exe=%s): Permission denied.\n", GetMSG(is_enforce), root_name, current->pid, exename);  
                 if (is_enforce && CheckSupervisor("# %s is requesting\nchroot %s\n", exename, root_name) == 0) error = 0;  
                 if (exename) ccs_free(exename);  
                 if (!is_enforce && CheckCCSAccept(CCS_SAKURA_RESTRICT_CHROOT, NULL) && root_name) {  
                         AddChrootACL(root_name, 0);  
                         UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);  
                 }  
                 if (!is_enforce) error = 0;  
         }  
145          ccs_free(root_name);          ccs_free(root_name);
146          return error;          return error;
147  }  }
 EXPORT_SYMBOL(CheckChRootPermission);  
148    
149  int AddChrootPolicy(char *data, const bool is_delete)  /**
150     * ccs_write_chroot_policy - Write "struct chroot_entry" list.
151     *
152     * @data:      String to parse.
153     * @is_delete: True if it is a delete request.
154     *
155     * Returns 0 on success, negative value otherwise.
156     */
157    int ccs_write_chroot_policy(char *data, const bool is_delete)
158  {  {
159          return AddChrootACL(data, is_delete);          return update_chroot_acl(data, is_delete);
160  }  }
161    
162  int ReadChrootPolicy(struct io_buffer *head)  /**
163     * ccs_read_chroot_policy - Read "struct chroot_entry" list.
164     *
165     * @head: Pointer to "struct ccs_io_buffer".
166     *
167     * Returns true on success, false otherwise.
168     */
169    bool ccs_read_chroot_policy(struct ccs_io_buffer *head)
170  {  {
171          struct list1_head *pos;          struct list1_head *pos;
172          list1_for_each_cookie(pos, head->read_var2, &chroot_list) {          list1_for_each_cookie(pos, head->read_var2, &chroot_list) {
173                  struct chroot_entry *ptr;                  struct chroot_entry *ptr;
174                  ptr = list1_entry(pos, struct chroot_entry, list);                  ptr = list1_entry(pos, struct chroot_entry, list);
175                  if (ptr->is_deleted) continue;                  if (ptr->is_deleted)
176                  if (io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n", ptr->dir->name)) return -ENOMEM;                          continue;
177                    if (!ccs_io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n",
178                                       ptr->dir->name))
179                            goto out;
180          }          }
181          return 0;          return true;
182     out:
183            return false;
184  }  }
   
 /***** SAKURA Linux end. *****/  

Legend:
Removed from v.731  
changed lines
  Added in v.1076

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26