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

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/ccs-patch/fs/sakura_chroot.c revision 141 by kumaneko, Mon Mar 19 13:29:09 2007 UTC trunk/1.6.x/ccs-patch/fs/sakura_chroot.c revision 1561 by kumaneko, Tue Sep 9 04:29:07 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.3.3   2007/04/01   * Version: 1.6.5-pre   2008/09/09
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. */
25    struct chroot_entry {
26  /***** The structure for chroot restrictions. *****/          struct list1_head list;
   
 typedef struct chroot_entry {  
         struct chroot_entry *next;  
27          const struct path_info *dir;          const struct path_info *dir;
28          int is_deleted;          bool is_deleted;
29  } CHROOT_ENTRY;  };
   
 /*************************  CHROOT RESTRICTION HANDLER  *************************/  
30    
31  static CHROOT_ENTRY *chroot_list = NULL;  /* The list for "struct chroot_entry". */
32    static LIST1_HEAD(chroot_list);
33    
34  static int AddChrootACL(const char *dir, const int 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          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 DECLARE_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          down(&lock);          saved_dir = ccs_save_name(dir);
52          for (ptr = chroot_list; ptr; ptr = ptr->next) {          if (!saved_dir)
53                  if (ptr->dir == saved_dir) {                  return -ENOMEM;
54                          ptr->is_deleted = is_delete;          mutex_lock(&lock);
55                          error = 0;          list1_for_each_entry(ptr, &chroot_list, list) {
56                          goto out;                  if (ptr->dir != saved_dir)
57                  }                          continue;
58                    ptr->is_deleted = is_delete;
59                    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 = (CHROOT_ENTRY *) alloc_element(sizeof(CHROOT_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          mb(); /* Instead of using spinlock. */          list1_add_tail_mb(&new_entry->list, &chroot_list);
         if ((ptr = chroot_list) != NULL) {  
                 while (ptr->next) ptr = ptr->next; ptr->next = new_entry;  
         } else {  
                 chroot_list = new_entry;  
         }  
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          up(&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 = -EPERM;          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(NULL, "# %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    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
109    #define PATH_or_NAMEIDATA path
110    #else
111    #define PATH_or_NAMEIDATA nameidata
112    #endif
113    /**
114     * ccs_check_chroot_permission - Check permission for chroot().
115     *
116     * @path: Pointer to "struct path" (for 2.6.27 and later).
117     *        Pointer to "struct nameidata" (for 2.6.26 and earlier).
118     *
119     * Returns 0 on success, negative value otherwise.
120     */
121    int ccs_check_chroot_permission(struct PATH_or_NAMEIDATA *path)
122    {
123            int error;
124          char *root_name;          char *root_name;
125          if (!CheckCCSFlags(CCS_SAKURA_RESTRICT_CHROOT)) return 0;          const u8 mode = ccs_check_flags(CCS_SAKURA_RESTRICT_CHROOT);
126          root_name = realpath_from_dentry(nd->dentry, nd->mnt);          if (!mode)
127                    return 0;
128     retry:
129            error = -EPERM;
130    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
131            root_name = ccs_realpath_from_dentry(path->path.dentry, path->path.mnt);
132    #else
133            root_name = ccs_realpath_from_dentry(path->dentry, path->mnt);
134    #endif
135          if (root_name) {          if (root_name) {
136                  struct path_info dir;                  struct path_info dir;
137                  dir.name = root_name;                  dir.name = root_name;
138                  fill_path_info(&dir);                  ccs_fill_path_info(&dir);
139                  if (dir.is_dir) {                  if (dir.is_dir) {
140                          CHROOT_ENTRY *ptr;                          struct chroot_entry *ptr;
141                          for (ptr = chroot_list; ptr; ptr = ptr->next) {                          list1_for_each_entry(ptr, &chroot_list, list) {
142                                  if (ptr->is_deleted) continue;                                  if (ptr->is_deleted)
143                                  if (PathMatchesToPattern(&dir, ptr->dir)) {                                          continue;
144                                          error = 0;                                  if (!ccs_path_matches_pattern(&dir, ptr->dir))
145                                          break;                                          continue;
146                                  }                                  error = 0;
147                                    break;
148                          }                          }
149                  }                  }
150          }          }
151          if (error) {          if (error)
152                  const int 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) && root_name) {  
                         AddChrootACL(root_name, 0);  
                         UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);  
                 }  
                 if (!is_enforce) error = 0;  
         }  
153          ccs_free(root_name);          ccs_free(root_name);
154            if (error == 1)
155                    goto retry;
156          return error;          return error;
157  }  }
158    
159  int AddChrootPolicy(char *data, const int is_delete)  /**
160     * ccs_write_chroot_policy - Write "struct chroot_entry" list.
161     *
162     * @data:      String to parse.
163     * @is_delete: True if it is a delete request.
164     *
165     * Returns 0 on success, negative value otherwise.
166     */
167    int ccs_write_chroot_policy(char *data, const bool is_delete)
168  {  {
169          return AddChrootACL(data, is_delete);          return update_chroot_acl(data, is_delete);
170  }  }
171    
172  int ReadChrootPolicy(IO_BUFFER *head)  /**
173     * ccs_read_chroot_policy - Read "struct chroot_entry" list.
174     *
175     * @head: Pointer to "struct ccs_io_buffer".
176     *
177     * Returns true on success, false otherwise.
178     */
179    bool ccs_read_chroot_policy(struct ccs_io_buffer *head)
180  {  {
181          CHROOT_ENTRY *ptr = (CHROOT_ENTRY *) head->read_var2;          struct list1_head *pos;
182          if (!ptr) ptr = chroot_list;          list1_for_each_cookie(pos, head->read_var2, &chroot_list) {
183          while (ptr) {                  struct chroot_entry *ptr;
184                  head->read_var2 = (void *) ptr;                  ptr = list1_entry(pos, struct chroot_entry, list);
185                  if (ptr->is_deleted == 0 && io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n", ptr->dir->name)) break;                  if (ptr->is_deleted)
186                  ptr = ptr->next;                          continue;
187                    if (!ccs_io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n",
188                                       ptr->dir->name))
189                            goto out;
190          }          }
191          return ptr ? -ENOMEM : 0;          return true;
192     out:
193            return false;
194  }  }
   
 EXPORT_SYMBOL(CheckChRootPermission);  
   
 /***** SAKURA Linux end. *****/  

Legend:
Removed from v.141  
changed lines
  Added in v.1561

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