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

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 1719 by kumaneko, Mon Oct 20 05:22:50 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.5-pre   2008/10/20
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     * @r:         Pointer to "struct ccs_request_info".
83     * @root_name: Requested directory name.
84     *
85     * Returns 0 if @r->mode is not enforcing mode or permitted by the
86     * administrator's decision, negative value otherwise.
87     */
88    static int print_error(struct ccs_request_info *r, const char *root_name)
89    {
90            int error;
91            const bool is_enforce = (r->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(r,
98                                                 "# %s is requesting\nchroot %s\n",
99                                                 exename, root_name);
100            else
101                    error = 0;
102            if (exename)
103                    ccs_free(exename);
104            if (r->mode == 1 && root_name)
105                    update_chroot_acl(root_name, false);
106            return error;
107    }
108    
109    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
110    #define PATH_or_NAMEIDATA path
111    #else
112    #define PATH_or_NAMEIDATA nameidata
113    #endif
114    /**
115     * ccs_check_chroot_permission - Check permission for chroot().
116     *
117     * @path: Pointer to "struct path" (for 2.6.27 and later).
118     *        Pointer to "struct nameidata" (for 2.6.26 and earlier).
119     *
120     * Returns 0 on success, negative value otherwise.
121     */
122    int ccs_check_chroot_permission(struct PATH_or_NAMEIDATA *path)
123  {  {
124          int error = -EPERM;          struct ccs_request_info r;
125            int error;
126          char *root_name;          char *root_name;
127          if (!CheckCCSFlags(CCS_SAKURA_RESTRICT_CHROOT)) return 0;          if (!ccs_can_sleep())
128          root_name = realpath_from_dentry(nd->dentry, nd->mnt);                  return 0;
129            ccs_init_request_info(&r, NULL, CCS_SAKURA_RESTRICT_CHROOT);
130            if (!r.mode)
131                    return 0;
132     retry:
133            error = -EPERM;
134    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
135            root_name = ccs_realpath_from_dentry(path->path.dentry, path->path.mnt);
136    #else
137            root_name = ccs_realpath_from_dentry(path->dentry, path->mnt);
138    #endif
139          if (root_name) {          if (root_name) {
140                  struct path_info dir;                  struct path_info dir;
141                  dir.name = root_name;                  dir.name = root_name;
142                  fill_path_info(&dir);                  ccs_fill_path_info(&dir);
143                  if (dir.is_dir) {                  if (dir.is_dir) {
144                          struct chroot_entry *ptr;                          struct chroot_entry *ptr;
145                          list1_for_each_entry(ptr, &chroot_list, list) {                          list1_for_each_entry(ptr, &chroot_list, list) {
146                                  if (ptr->is_deleted) continue;                                  if (ptr->is_deleted)
147                                  if (PathMatchesToPattern(&dir, ptr->dir)) {                                          continue;
148                                          error = 0;                                  if (!ccs_path_matches_pattern(&dir, ptr->dir))
149                                          break;                                          continue;
150                                  }                                  error = 0;
151                                    break;
152                          }                          }
153                  }                  }
154          }          }
155          if (error) {          if (error)
156                  const bool is_enforce = CheckCCSEnforce(CCS_SAKURA_RESTRICT_CHROOT);                  error = print_error(&r, root_name);
                 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;  
         }  
157          ccs_free(root_name);          ccs_free(root_name);
158            if (error == 1) {
159                    r.retry++;
160                    goto retry;
161            }
162          return error;          return error;
163  }  }
 EXPORT_SYMBOL(CheckChRootPermission);  
164    
165  int AddChrootPolicy(char *data, const bool is_delete)  /**
166     * ccs_write_chroot_policy - Write "struct chroot_entry" list.
167     *
168     * @data:      String to parse.
169     * @is_delete: True if it is a delete request.
170     *
171     * Returns 0 on success, negative value otherwise.
172     */
173    int ccs_write_chroot_policy(char *data, const bool is_delete)
174  {  {
175          return AddChrootACL(data, is_delete);          return update_chroot_acl(data, is_delete);
176  }  }
177    
178  int ReadChrootPolicy(struct io_buffer *head)  /**
179     * ccs_read_chroot_policy - Read "struct chroot_entry" list.
180     *
181     * @head: Pointer to "struct ccs_io_buffer".
182     *
183     * Returns true on success, false otherwise.
184     */
185    bool ccs_read_chroot_policy(struct ccs_io_buffer *head)
186  {  {
187          struct list1_head *pos;          struct list1_head *pos;
188          list1_for_each_cookie(pos, head->read_var2, &chroot_list) {          list1_for_each_cookie(pos, head->read_var2, &chroot_list) {
189                  struct chroot_entry *ptr;                  struct chroot_entry *ptr;
190                  ptr = list1_entry(pos, struct chroot_entry, list);                  ptr = list1_entry(pos, struct chroot_entry, list);
191                  if (ptr->is_deleted) continue;                  if (ptr->is_deleted)
192                  if (io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n", ptr->dir->name)) return -ENOMEM;                          continue;
193                    if (!ccs_io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n",
194                                       ptr->dir->name))
195                            goto out;
196          }          }
197          return 0;          return true;
198     out:
199            return false;
200  }  }
   
 /***** SAKURA Linux end. *****/  

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

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