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

Subversion リポジトリの参照

Diff of /trunk/1.8.x/ccs-patch/security/ccsecurity/domain.c

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

trunk/1.6.x/ccs-patch/fs/tomoyo_domain.c revision 2048 by kumaneko, Thu Jan 8 07:15:05 2009 UTC branches/ccs-patch/fs/tomoyo_domain.c revision 2738 by kumaneko, Tue Jul 7 01:28:46 2009 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2009  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.6-pre   2009/01/05   * Version: 1.7.0-pre   2009/07/03
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.
# Line 20  Line 20 
20  #include <linux/namei.h>  #include <linux/namei.h>
21  #include <linux/mount.h>  #include <linux/mount.h>
22  #endif  #endif
23    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
24    #include <linux/fs_struct.h>
25    #endif
26    
27  /* For compatibility with older kernels. */  /* For compatibility with older kernels. */
28  #ifndef for_each_process  #ifndef for_each_process
# Line 29  Line 32 
32  /* Variables definitions.*/  /* Variables definitions.*/
33    
34  /* The initial domain. */  /* The initial domain. */
35  struct domain_info KERNEL_DOMAIN;  struct ccs_domain_info ccs_kernel_domain;
   
 /* The list for "struct domain_info". */  
 LIST1_HEAD(ccs_domain_list);  
   
 #ifdef CONFIG_TOMOYO  
   
 /* Domain creation lock. */  
 static DEFINE_MUTEX(ccs_domain_list_lock);  
   
 /* Structure for "initialize_domain" and "no_initialize_domain" keyword. */  
 struct ccs_domain_initializer_entry {  
         struct list1_head list;  
         const struct ccs_path_info *domainname;    /* This may be NULL */  
         const struct ccs_path_info *program;  
         bool is_deleted;  
         bool is_not;       /* True if this entry is "no_initialize_domain".  */  
         bool is_last_name; /* True if the domainname is ccs_get_last_name(). */  
 };  
   
 /* Structure for "keep_domain" and "no_keep_domain" keyword. */  
 struct ccs_domain_keeper_entry {  
         struct list1_head list;  
         const struct ccs_path_info *domainname;  
         const struct ccs_path_info *program;       /* This may be NULL */  
         bool is_deleted;  
         bool is_not;       /* True if this entry is "no_keep_domain".        */  
         bool is_last_name; /* True if the domainname is ccs_get_last_name(). */  
 };  
   
 /* Structure for "aggregator" keyword. */  
 struct ccs_aggregator_entry {  
         struct list1_head list;  
         const struct ccs_path_info *original_name;  
         const struct ccs_path_info *aggregated_name;  
         bool is_deleted;  
 };  
   
 /* Structure for "alias" keyword. */  
 struct ccs_alias_entry {  
         struct list1_head list;  
         const struct ccs_path_info *original_name;  
         const struct ccs_path_info *aliased_name;  
         bool is_deleted;  
 };  
36    
37  /**  /* The list for "struct ccs_domain_info". */
38   * ccs_set_domain_flag - Set or clear domain's attribute flags.  LIST_HEAD(ccs_domain_list);
  *  
  * @domain:    Pointer to "struct domain_info".  
  * @is_delete: True if it is a delete request.  
  * @flags:     Flags to set or clear.  
  *  
  * Returns nothing.  
  */  
 void ccs_set_domain_flag(struct domain_info *domain, const bool is_delete,  
                          const u8 flags)  
 {  
         /* We need to serialize because this is bitfield operation. */  
         static DEFINE_SPINLOCK(lock);  
         /***** CRITICAL SECTION START *****/  
         spin_lock(&lock);  
         if (!is_delete)  
                 domain->flags |= flags;  
         else  
                 domain->flags &= ~flags;  
         spin_unlock(&lock);  
         /***** CRITICAL SECTION END *****/  
 }  
39    
40  /**  /**
41   * ccs_get_last_name - Get last component of a domainname.   * ccs_get_last_name - Get last component of a domainname.
42   *   *
43   * @domain: Pointer to "struct domain_info".   * @domain: Pointer to "struct ccs_domain_info".
44   *   *
45   * Returns the last component of the domainname.   * Returns the last component of the domainname.
46   */   */
47  const char *ccs_get_last_name(const struct domain_info *domain)  const char *ccs_get_last_name(const struct ccs_domain_info *domain)
48  {  {
49          const char *cp0 = domain->domainname->name;          const char *cp0 = domain->domainname->name;
50          const char *cp1 = strrchr(cp0, ' ');          const char *cp1 = strrchr(cp0, ' ');
# Line 118  const char *ccs_get_last_name(const stru Line 56  const char *ccs_get_last_name(const stru
56  /**  /**
57   * ccs_add_domain_acl - Add the given ACL to the given domain.   * ccs_add_domain_acl - Add the given ACL to the given domain.
58   *   *
59   * @domain: Pointer to "struct domain_info". May be NULL.   * @domain: Pointer to "struct ccs_domain_info". May be NULL.
60   * @acl:    Pointer to "struct ccs_acl_info".   * @acl:    Pointer to "struct ccs_acl_info".
61   *   *
62   * Returns 0.   * Returns 0.
63   */   */
64  int ccs_add_domain_acl(struct domain_info *domain, struct ccs_acl_info *acl)  int ccs_add_domain_acl(struct ccs_domain_info *domain, struct ccs_acl_info *acl)
65  {  {
66          if (domain) {          if (domain) {
67                  /*                  if (acl->cond)
68                   * We need to serialize because this function is called by                          atomic_inc(&acl->cond->users);
69                   * various update functions.                  list_add_tail_rcu(&acl->list, &domain->acl_info_list);
                  */  
                 static DEFINE_SPINLOCK(lock);  
                 /***** CRITICAL SECTION START *****/  
                 spin_lock(&lock);  
                 list1_add_tail_mb(&acl->list, &domain->acl_info_list);  
                 spin_unlock(&lock);  
                 /***** CRITICAL SECTION END *****/  
70          } else {          } else {
71                  acl->type &= ~ACL_DELETED;                  acl->type &= ~ACL_DELETED;
72          }          }
         ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);  
73          return 0;          return 0;
74  }  }
75    
# Line 154  int ccs_del_domain_acl(struct ccs_acl_in Line 84  int ccs_del_domain_acl(struct ccs_acl_in
84  {  {
85          if (acl)          if (acl)
86                  acl->type |= ACL_DELETED;                  acl->type |= ACL_DELETED;
         ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);  
87          return 0;          return 0;
88  }  }
89    
# Line 171  static int ccs_audit_execute_handler_log Line 100  static int ccs_audit_execute_handler_log
100  {  {
101          struct ccs_request_info *r = &ee->r;          struct ccs_request_info *r = &ee->r;
102          const char *handler = ee->handler->name;          const char *handler = ee->handler->name;
103          r->mode = ccs_check_flags(r->domain, CCS_TOMOYO_MAC_FOR_FILE);          r->mode = ccs_check_flags(r->domain, CCS_MAC_FOR_FILE);
104          return ccs_write_audit_log(true, r, "%s %s\n",          return ccs_write_audit_log(true, r, "%s %s\n",
105                                     is_default ? KEYWORD_EXECUTE_HANDLER :                                     is_default ? KEYWORD_EXECUTE_HANDLER :
106                                     KEYWORD_DENIED_EXECUTE_HANDLER, handler);                                     KEYWORD_DENIED_EXECUTE_HANDLER, handler);
# Line 180  static int ccs_audit_execute_handler_log Line 109  static int ccs_audit_execute_handler_log
109  /**  /**
110   * ccs_audit_domain_creation_log - Audit domain creation log.   * ccs_audit_domain_creation_log - Audit domain creation log.
111   *   *
112   * @domain:  Pointer to "struct domain_info".   * @domain:  Pointer to "struct ccs_domain_info".
113   *   *
114   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
115   */   */
116  static int ccs_audit_domain_creation_log(struct domain_info *domain)  static int ccs_audit_domain_creation_log(struct ccs_domain_info *domain)
117  {  {
118            int error;
119          struct ccs_request_info r;          struct ccs_request_info r;
120          ccs_init_request_info(&r, domain, CCS_TOMOYO_MAC_FOR_FILE);          ccs_init_request_info(&r, domain, CCS_MAC_FOR_FILE);
121          return ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile);          error = ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile);
122            return error;
123  }  }
124    
125  /* The list for "struct ccs_domain_initializer_entry". */  /* The list for "struct ccs_domain_initializer_entry". */
126  static LIST1_HEAD(ccs_domain_initializer_list);  LIST_HEAD(ccs_domain_initializer_list);
127    
128  /**  /**
129   * ccs_update_domain_initializer_entry - Update "struct ccs_domain_initializer_entry" list.   * ccs_update_domain_initializer_entry - Update "struct ccs_domain_initializer_entry" list.
# Line 209  static int ccs_update_domain_initializer Line 140  static int ccs_update_domain_initializer
140                                                 const bool is_not,                                                 const bool is_not,
141                                                 const bool is_delete)                                                 const bool is_delete)
142  {  {
143          struct ccs_domain_initializer_entry *new_entry;          struct ccs_domain_initializer_entry *entry = NULL;
144          struct ccs_domain_initializer_entry *ptr;          struct ccs_domain_initializer_entry *ptr;
         static DEFINE_MUTEX(lock);  
145          const struct ccs_path_info *saved_program;          const struct ccs_path_info *saved_program;
146          const struct ccs_path_info *saved_domainname = NULL;          const struct ccs_path_info *saved_domainname = NULL;
147          int error = -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
148          bool is_last_name = false;          bool is_last_name = false;
149          if (!ccs_is_correct_path(program, 1, -1, -1, __func__))          if (!ccs_is_correct_path(program, 1, -1, -1))
150                  return -EINVAL; /* No patterns allowed. */                  return -EINVAL; /* No patterns allowed. */
151          if (domainname) {          if (domainname) {
152                  if (!ccs_is_domain_def(domainname) &&                  if (!ccs_is_domain_def(domainname) &&
153                      ccs_is_correct_path(domainname, 1, -1, -1, __func__))                      ccs_is_correct_path(domainname, 1, -1, -1))
154                          is_last_name = true;                          is_last_name = true;
155                  else if (!ccs_is_correct_domain(domainname, __func__))                  else if (!ccs_is_correct_domain(domainname))
156                          return -EINVAL;                          return -EINVAL;
157                  saved_domainname = ccs_save_name(domainname);                  saved_domainname = ccs_get_name(domainname);
158                  if (!saved_domainname)                  if (!saved_domainname)
159                          return -ENOMEM;                          return -ENOMEM;
160          }          }
161          saved_program = ccs_save_name(program);          saved_program = ccs_get_name(program);
162          if (!saved_program)          if (!saved_program) {
163                    ccs_put_name(saved_domainname);
164                  return -ENOMEM;                  return -ENOMEM;
165          mutex_lock(&lock);          }
166          list1_for_each_entry(ptr, &ccs_domain_initializer_list, list) {          if (!is_delete)
167                    entry = kzalloc(sizeof(*entry), GFP_KERNEL);
168            mutex_lock(&ccs_policy_lock);
169            list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list, list) {
170                  if (ptr->is_not != is_not ||                  if (ptr->is_not != is_not ||
171                      ptr->domainname != saved_domainname ||                      ptr->domainname != saved_domainname ||
172                      ptr->program != saved_program)                      ptr->program != saved_program)
173                          continue;                          continue;
174                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
175                  error = 0;                  error = 0;
176                  goto out;                  break;
177          }          }
178          if (is_delete) {          if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
179                  error = -ENOENT;                  entry->domainname = saved_domainname;
180                  goto out;                  saved_domainname = NULL;
181                    entry->program = saved_program;
182                    saved_program = NULL;
183                    entry->is_not = is_not;
184                    entry->is_last_name = is_last_name;
185                    list_add_tail_rcu(&entry->list, &ccs_domain_initializer_list);
186                    entry = NULL;
187                    error = 0;
188          }          }
189          new_entry = ccs_alloc_element(sizeof(*new_entry));          mutex_unlock(&ccs_policy_lock);
190          if (!new_entry)          ccs_put_name(saved_domainname);
191                  goto out;          ccs_put_name(saved_program);
192          new_entry->domainname = saved_domainname;          kfree(entry);
         new_entry->program = saved_program;  
         new_entry->is_not = is_not;  
         new_entry->is_last_name = is_last_name;  
         list1_add_tail_mb(&new_entry->list, &ccs_domain_initializer_list);  
         error = 0;  
  out:  
         mutex_unlock(&lock);  
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
193          return error;          return error;
194  }  }
195    
# Line 266  static int ccs_update_domain_initializer Line 199  static int ccs_update_domain_initializer
199   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
200   *   *
201   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
202     *
203     * Caller holds srcu_read_lock(&ccs_ss).
204   */   */
205  bool ccs_read_domain_initializer_policy(struct ccs_io_buffer *head)  bool ccs_read_domain_initializer_policy(struct ccs_io_buffer *head)
206  {  {
207          struct list1_head *pos;          struct list_head *pos;
208          list1_for_each_cookie(pos, head->read_var2,          bool done = true;
209                                &ccs_domain_initializer_list) {          list_for_each_cookie(pos, head->read_var2,
210                                 &ccs_domain_initializer_list) {
211                  const char *no;                  const char *no;
212                  const char *from = "";                  const char *from = "";
213                  const char *domain = "";                  const char *domain = "";
214                  struct ccs_domain_initializer_entry *ptr;                  struct ccs_domain_initializer_entry *ptr;
215                  ptr = list1_entry(pos, struct ccs_domain_initializer_entry,                  ptr = list_entry(pos, struct ccs_domain_initializer_entry,
216                                    list);                                    list);
217                  if (ptr->is_deleted)                  if (ptr->is_deleted)
218                          continue;                          continue;
# Line 285  bool ccs_read_domain_initializer_policy( Line 221  bool ccs_read_domain_initializer_policy(
221                          from = " from ";                          from = " from ";
222                          domain = ptr->domainname->name;                          domain = ptr->domainname->name;
223                  }                  }
224                  if (!ccs_io_printf(head,                  done = ccs_io_printf(head,
225                                     "%s" KEYWORD_INITIALIZE_DOMAIN "%s%s%s\n",                                       "%s" KEYWORD_INITIALIZE_DOMAIN "%s%s%s\n",
226                                     no, ptr->program->name, from, domain))                                       no, ptr->program->name, from, domain);
227                          goto out;                  if (!done)
228                            break;
229          }          }
230          return true;          return done;
  out:  
         return false;  
231  }  }
232    
233  /**  /**
# Line 326  int ccs_write_domain_initializer_policy( Line 261  int ccs_write_domain_initializer_policy(
261   *   *
262   * Returns true if executing @program reinitializes domain transition,   * Returns true if executing @program reinitializes domain transition,
263   * false otherwise.   * false otherwise.
264     *
265     * Caller holds srcu_read_lock(&ccs_ss).
266   */   */
267  static bool ccs_is_domain_initializer(const struct ccs_path_info *domainname,  static bool ccs_is_domain_initializer(const struct ccs_path_info *domainname,
268                                        const struct ccs_path_info *program,                                        const struct ccs_path_info *program,
# Line 333  static bool ccs_is_domain_initializer(co Line 270  static bool ccs_is_domain_initializer(co
270  {  {
271          struct ccs_domain_initializer_entry *ptr;          struct ccs_domain_initializer_entry *ptr;
272          bool flag = false;          bool flag = false;
273          list1_for_each_entry(ptr, &ccs_domain_initializer_list, list) {          list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list, list) {
274                  if (ptr->is_deleted)                  if (ptr->is_deleted)
275                          continue;                          continue;
276                  if (ptr->domainname) {                  if (ptr->domainname) {
# Line 347  static bool ccs_is_domain_initializer(co Line 284  static bool ccs_is_domain_initializer(co
284                  }                  }
285                  if (ccs_pathcmp(ptr->program, program))                  if (ccs_pathcmp(ptr->program, program))
286                          continue;                          continue;
287                  if (ptr->is_not)                  if (ptr->is_not) {
288                          return false;                          flag = false;
289                            break;
290                    }
291                  flag = true;                  flag = true;
292          }          }
293          return flag;          return flag;
294  }  }
295    
296  /* The list for "struct ccs_domain_keeper_entry". */  /* The list for "struct ccs_domain_keeper_entry". */
297  static LIST1_HEAD(ccs_domain_keeper_list);  LIST_HEAD(ccs_domain_keeper_list);
298    
299  /**  /**
300   * ccs_update_domain_keeper_entry - Update "struct ccs_domain_keeper_entry" list.   * ccs_update_domain_keeper_entry - Update "struct ccs_domain_keeper_entry" list.
# Line 372  static int ccs_update_domain_keeper_entr Line 311  static int ccs_update_domain_keeper_entr
311                                            const bool is_not,                                            const bool is_not,
312                                            const bool is_delete)                                            const bool is_delete)
313  {  {
314          struct ccs_domain_keeper_entry *new_entry;          struct ccs_domain_keeper_entry *entry = NULL;
315          struct ccs_domain_keeper_entry *ptr;          struct ccs_domain_keeper_entry *ptr;
316          const struct ccs_path_info *saved_domainname;          const struct ccs_path_info *saved_domainname;
317          const struct ccs_path_info *saved_program = NULL;          const struct ccs_path_info *saved_program = NULL;
318          static DEFINE_MUTEX(lock);          int error = is_delete ? -ENOENT : -ENOMEM;
         int error = -ENOMEM;  
319          bool is_last_name = false;          bool is_last_name = false;
320          if (!ccs_is_domain_def(domainname) &&          if (!ccs_is_domain_def(domainname) &&
321              ccs_is_correct_path(domainname, 1, -1, -1, __func__))              ccs_is_correct_path(domainname, 1, -1, -1))
322                  is_last_name = true;                  is_last_name = true;
323          else if (!ccs_is_correct_domain(domainname, __func__))          else if (!ccs_is_correct_domain(domainname))
324                  return -EINVAL;                  return -EINVAL;
325          if (program) {          if (program) {
326                  if (!ccs_is_correct_path(program, 1, -1, -1, __func__))                  if (!ccs_is_correct_path(program, 1, -1, -1))
327                          return -EINVAL;                          return -EINVAL;
328                  saved_program = ccs_save_name(program);                  saved_program = ccs_get_name(program);
329                  if (!saved_program)                  if (!saved_program)
330                          return -ENOMEM;                          return -ENOMEM;
331          }          }
332          saved_domainname = ccs_save_name(domainname);          saved_domainname = ccs_get_name(domainname);
333          if (!saved_domainname)          if (!saved_domainname) {
334                    ccs_put_name(saved_program);
335                  return -ENOMEM;                  return -ENOMEM;
336          mutex_lock(&lock);          }
337          list1_for_each_entry(ptr, &ccs_domain_keeper_list, list) {          if (!is_delete)
338                    entry = kzalloc(sizeof(*entry), GFP_KERNEL);
339            mutex_lock(&ccs_policy_lock);
340            list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) {
341                  if (ptr->is_not != is_not ||                  if (ptr->is_not != is_not ||
342                      ptr->domainname != saved_domainname ||                      ptr->domainname != saved_domainname ||
343                      ptr->program != saved_program)                      ptr->program != saved_program)
344                          continue;                          continue;
345                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
346                  error = 0;                  error = 0;
347                  goto out;                  break;
348          }          }
349          if (is_delete) {          if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
350                  error = -ENOENT;                  entry->domainname = saved_domainname;
351                  goto out;                  saved_domainname = NULL;
352                    entry->program = saved_program;
353                    saved_program = NULL;
354                    entry->is_not = is_not;
355                    entry->is_last_name = is_last_name;
356                    list_add_tail_rcu(&entry->list, &ccs_domain_keeper_list);
357                    entry = NULL;
358                    error = 0;
359          }          }
360          new_entry = ccs_alloc_element(sizeof(*new_entry));          mutex_unlock(&ccs_policy_lock);
361          if (!new_entry)          ccs_put_name(saved_domainname);
362                  goto out;          ccs_put_name(saved_program);
363          new_entry->domainname = saved_domainname;          kfree(entry);
         new_entry->program = saved_program;  
         new_entry->is_not = is_not;  
         new_entry->is_last_name = is_last_name;  
         list1_add_tail_mb(&new_entry->list, &ccs_domain_keeper_list);  
         error = 0;  
  out:  
         mutex_unlock(&lock);  
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
364          return error;          return error;
365  }  }
366    
# Line 449  int ccs_write_domain_keeper_policy(char Line 390  int ccs_write_domain_keeper_policy(char
390   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
391   *   *
392   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
393     *
394     * Caller holds srcu_read_lock(&ccs_ss).
395   */   */
396  bool ccs_read_domain_keeper_policy(struct ccs_io_buffer *head)  bool ccs_read_domain_keeper_policy(struct ccs_io_buffer *head)
397  {  {
398          struct list1_head *pos;          struct list_head *pos;
399          list1_for_each_cookie(pos, head->read_var2, &ccs_domain_keeper_list) {          bool done = true;
400            list_for_each_cookie(pos, head->read_var2,
401                                 &ccs_domain_keeper_list) {
402                  struct ccs_domain_keeper_entry *ptr;                  struct ccs_domain_keeper_entry *ptr;
403                  const char *no;                  const char *no;
404                  const char *from = "";                  const char *from = "";
405                  const char *program = "";                  const char *program = "";
406                  ptr = list1_entry(pos, struct ccs_domain_keeper_entry, list);                  ptr = list_entry(pos, struct ccs_domain_keeper_entry, list);
407                  if (ptr->is_deleted)                  if (ptr->is_deleted)
408                          continue;                          continue;
409                  no = ptr->is_not ? "no_" : "";                  no = ptr->is_not ? "no_" : "";
# Line 466  bool ccs_read_domain_keeper_policy(struc Line 411  bool ccs_read_domain_keeper_policy(struc
411                          from = " from ";                          from = " from ";
412                          program = ptr->program->name;                          program = ptr->program->name;
413                  }                  }
414                  if (!ccs_io_printf(head,                  done = ccs_io_printf(head,
415                                     "%s" KEYWORD_KEEP_DOMAIN "%s%s%s\n", no,                                       "%s" KEYWORD_KEEP_DOMAIN "%s%s%s\n", no,
416                                     program, from, ptr->domainname->name))                                       program, from, ptr->domainname->name);
417                          goto out;                  if (!done)
418                            break;
419          }          }
420          return true;          return done;
  out:  
         return false;  
421  }  }
422    
423  /**  /**
# Line 485  bool ccs_read_domain_keeper_policy(struc Line 429  bool ccs_read_domain_keeper_policy(struc
429   *   *
430   * Returns true if executing @program supresses domain transition,   * Returns true if executing @program supresses domain transition,
431   * false otherwise.   * false otherwise.
432     *
433     * Caller holds srcu_read_lock(&ccs_ss).
434   */   */
435  static bool ccs_is_domain_keeper(const struct ccs_path_info *domainname,  static bool ccs_is_domain_keeper(const struct ccs_path_info *domainname,
436                                   const struct ccs_path_info *program,                                   const struct ccs_path_info *program,
# Line 492  static bool ccs_is_domain_keeper(const s Line 438  static bool ccs_is_domain_keeper(const s
438  {  {
439          struct ccs_domain_keeper_entry *ptr;          struct ccs_domain_keeper_entry *ptr;
440          bool flag = false;          bool flag = false;
441          list1_for_each_entry(ptr, &ccs_domain_keeper_list, list) {          list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) {
442                  if (ptr->is_deleted)                  if (ptr->is_deleted)
443                          continue;                          continue;
444                  if (!ptr->is_last_name) {                  if (!ptr->is_last_name) {
# Line 504  static bool ccs_is_domain_keeper(const s Line 450  static bool ccs_is_domain_keeper(const s
450                  }                  }
451                  if (ptr->program && ccs_pathcmp(ptr->program, program))                  if (ptr->program && ccs_pathcmp(ptr->program, program))
452                          continue;                          continue;
453                  if (ptr->is_not)                  if (ptr->is_not) {
454                          return false;                          flag = false;
455                            break;
456                    }
457                  flag = true;                  flag = true;
458          }          }
459          return flag;          return flag;
460  }  }
461    
 /* The list for "struct ccs_alias_entry". */  
 static LIST1_HEAD(ccs_alias_list);  
   
 /**  
  * ccs_update_alias_entry - Update "struct ccs_alias_entry" list.  
  *  
  * @original_name: The original program's real name.  
  * @aliased_name:  The symbolic program's symbolic link's name.  
  * @is_delete:     True if it is a delete request.  
  *  
  * Returns 0 on success, negative value otherwise.  
  */  
 static int ccs_update_alias_entry(const char *original_name,  
                                   const char *aliased_name,  
                                   const bool is_delete)  
 {  
         struct ccs_alias_entry *new_entry;  
         struct ccs_alias_entry *ptr;  
         static DEFINE_MUTEX(lock);  
         const struct ccs_path_info *saved_original_name;  
         const struct ccs_path_info *saved_aliased_name;  
         int error = -ENOMEM;  
         if (!ccs_is_correct_path(original_name, 1, -1, -1, __func__) ||  
             !ccs_is_correct_path(aliased_name, 1, -1, -1, __func__))  
                 return -EINVAL; /* No patterns allowed. */  
         saved_original_name = ccs_save_name(original_name);  
         saved_aliased_name = ccs_save_name(aliased_name);  
         if (!saved_original_name || !saved_aliased_name)  
                 return -ENOMEM;  
         mutex_lock(&lock);  
         list1_for_each_entry(ptr, &ccs_alias_list, list) {  
                 if (ptr->original_name != saved_original_name ||  
                     ptr->aliased_name != saved_aliased_name)  
                         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->original_name = saved_original_name;  
         new_entry->aliased_name = saved_aliased_name;  
         list1_add_tail_mb(&new_entry->list, &ccs_alias_list);  
         error = 0;  
  out:  
         mutex_unlock(&lock);  
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
         return error;  
 }  
   
 /**  
  * ccs_read_alias_policy - Read "struct ccs_alias_entry" list.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  *  
  * Returns true on success, false otherwise.  
  */  
 bool ccs_read_alias_policy(struct ccs_io_buffer *head)  
 {  
         struct list1_head *pos;  
         list1_for_each_cookie(pos, head->read_var2, &ccs_alias_list) {  
                 struct ccs_alias_entry *ptr;  
                 ptr = list1_entry(pos, struct ccs_alias_entry, list);  
                 if (ptr->is_deleted)  
                         continue;  
                 if (!ccs_io_printf(head, KEYWORD_ALIAS "%s %s\n",  
                                    ptr->original_name->name,  
                                    ptr->aliased_name->name))  
                         goto out;  
         }  
         return true;  
  out:  
         return false;  
 }  
   
 /**  
  * ccs_write_alias_policy - Write "struct ccs_alias_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_alias_policy(char *data, const bool is_delete)  
 {  
         char *cp = strchr(data, ' ');  
         if (!cp)  
                 return -EINVAL;  
         *cp++ = '\0';  
         return ccs_update_alias_entry(data, cp, is_delete);  
 }  
   
462  /* The list for "struct ccs_aggregator_entry". */  /* The list for "struct ccs_aggregator_entry". */
463  static LIST1_HEAD(ccs_aggregator_list);  LIST_HEAD(ccs_aggregator_list);
464    
465  /**  /**
466   * ccs_update_aggregator_entry - Update "struct ccs_aggregator_entry" list.   * ccs_update_aggregator_entry - Update "struct ccs_aggregator_entry" list.
# Line 624  static int ccs_update_aggregator_entry(c Line 475  static int ccs_update_aggregator_entry(c
475                                         const char *aggregated_name,                                         const char *aggregated_name,
476                                         const bool is_delete)                                         const bool is_delete)
477  {  {
478          struct ccs_aggregator_entry *new_entry;          struct ccs_aggregator_entry *entry = NULL;
479          struct ccs_aggregator_entry *ptr;          struct ccs_aggregator_entry *ptr;
         static DEFINE_MUTEX(lock);  
480          const struct ccs_path_info *saved_original_name;          const struct ccs_path_info *saved_original_name;
481          const struct ccs_path_info *saved_aggregated_name;          const struct ccs_path_info *saved_aggregated_name;
482          int error = -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
483          if (!ccs_is_correct_path(original_name, 1, 0, -1, __func__) ||          if (!ccs_is_correct_path(original_name, 1, 0, -1) ||
484              !ccs_is_correct_path(aggregated_name, 1, -1, -1, __func__))              !ccs_is_correct_path(aggregated_name, 1, -1, -1))
485                  return -EINVAL;                  return -EINVAL;
486          saved_original_name = ccs_save_name(original_name);          saved_original_name = ccs_get_name(original_name);
487          saved_aggregated_name = ccs_save_name(aggregated_name);          saved_aggregated_name = ccs_get_name(aggregated_name);
488          if (!saved_original_name || !saved_aggregated_name)          if (!saved_original_name || !saved_aggregated_name) {
489                    ccs_put_name(saved_original_name);
490                    ccs_put_name(saved_aggregated_name);
491                  return -ENOMEM;                  return -ENOMEM;
492          mutex_lock(&lock);          }
493          list1_for_each_entry(ptr, &ccs_aggregator_list, list) {          if (!is_delete)
494                    entry = kzalloc(sizeof(*entry), GFP_KERNEL);
495            mutex_lock(&ccs_policy_lock);
496            list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) {
497                  if (ptr->original_name != saved_original_name ||                  if (ptr->original_name != saved_original_name ||
498                      ptr->aggregated_name != saved_aggregated_name)                      ptr->aggregated_name != saved_aggregated_name)
499                          continue;                          continue;
500                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
501                  error = 0;                  error = 0;
502                  goto out;                  break;
503          }          }
504          if (is_delete) {          if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
505                  error = -ENOENT;                  entry->original_name = saved_original_name;
506                  goto out;                  saved_original_name = NULL;
507                    entry->aggregated_name = saved_aggregated_name;
508                    saved_aggregated_name = NULL;
509                    list_add_tail_rcu(&entry->list, &ccs_aggregator_list);
510                    entry = NULL;
511                    error = 0;
512          }          }
513          new_entry = ccs_alloc_element(sizeof(*new_entry));          mutex_unlock(&ccs_policy_lock);
514          if (!new_entry)          ccs_put_name(saved_original_name);
515                  goto out;          ccs_put_name(saved_aggregated_name);
516          new_entry->original_name = saved_original_name;          kfree(entry);
         new_entry->aggregated_name = saved_aggregated_name;  
         list1_add_tail_mb(&new_entry->list, &ccs_aggregator_list);  
         error = 0;  
  out:  
         mutex_unlock(&lock);  
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
517          return error;          return error;
518  }  }
519    
# Line 669  static int ccs_update_aggregator_entry(c Line 523  static int ccs_update_aggregator_entry(c
523   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
524   *   *
525   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
526     *
527     * Caller holds srcu_read_lock(&ccs_ss).
528   */   */
529  bool ccs_read_aggregator_policy(struct ccs_io_buffer *head)  bool ccs_read_aggregator_policy(struct ccs_io_buffer *head)
530  {  {
531          struct list1_head *pos;          struct list_head *pos;
532          list1_for_each_cookie(pos, head->read_var2, &ccs_aggregator_list) {          bool done = true;
533            list_for_each_cookie(pos, head->read_var2, &ccs_aggregator_list) {
534                  struct ccs_aggregator_entry *ptr;                  struct ccs_aggregator_entry *ptr;
535                  ptr = list1_entry(pos, struct ccs_aggregator_entry, list);                  ptr = list_entry(pos, struct ccs_aggregator_entry, list);
536                  if (ptr->is_deleted)                  if (ptr->is_deleted)
537                          continue;                          continue;
538                  if (!ccs_io_printf(head, KEYWORD_AGGREGATOR "%s %s\n",                  done = ccs_io_printf(head, KEYWORD_AGGREGATOR "%s %s\n",
539                                     ptr->original_name->name,                                       ptr->original_name->name,
540                                     ptr->aggregated_name->name))                                       ptr->aggregated_name->name);
541                          goto out;                  if (!done)
542                            break;
543          }          }
544          return true;          return done;
  out:  
         return false;  
545  }  }
546    
547  /**  /**
# Line 705  int ccs_write_aggregator_policy(char *da Line 561  int ccs_write_aggregator_policy(char *da
561          return ccs_update_aggregator_entry(data, cp, is_delete);          return ccs_update_aggregator_entry(data, cp, is_delete);
562  }  }
563    
564  /* Domain create/delete/undelete handler. */  /* Domain create/delete handler. */
   
 /* #define DEBUG_DOMAIN_UNDELETE */  
565    
566  /**  /**
567   * ccs_delete_domain - Delete a domain.   * ccs_delete_domain - Delete a domain.
# Line 718  int ccs_write_aggregator_policy(char *da Line 572  int ccs_write_aggregator_policy(char *da
572   */   */
573  int ccs_delete_domain(char *domainname)  int ccs_delete_domain(char *domainname)
574  {  {
575          struct domain_info *domain;          struct ccs_domain_info *domain;
576          struct ccs_path_info name;          struct ccs_path_info name;
577          name.name = domainname;          name.name = domainname;
578          ccs_fill_path_info(&name);          ccs_fill_path_info(&name);
579          mutex_lock(&ccs_domain_list_lock);          mutex_lock(&ccs_policy_lock);
 #ifdef DEBUG_DOMAIN_UNDELETE  
         printk(KERN_DEBUG "ccs_delete_domain %s\n", domainname);  
         list1_for_each_entry(domain, &ccs_domain_list, list) {  
                 if (ccs_pathcmp(domain->domainname, &name))  
                         continue;  
                 printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);  
         }  
 #endif  
580          /* Is there an active domain? */          /* Is there an active domain? */
581          list1_for_each_entry(domain, &ccs_domain_list, list) {          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
582                  struct domain_info *domain2;                  /* Never delete ccs_kernel_domain */
583                  /* Never delete KERNEL_DOMAIN */                  if (domain == &ccs_kernel_domain)
                 if (domain == &KERNEL_DOMAIN)  
584                          continue;                          continue;
585                  if (domain->is_deleted ||                  if (domain->is_deleted ||
586                      ccs_pathcmp(domain->domainname, &name))                      ccs_pathcmp(domain->domainname, &name))
587                          continue;                          continue;
588                  /* Mark already deleted domains as non undeletable. */                  domain->is_deleted = true;
                 list1_for_each_entry(domain2, &ccs_domain_list, list) {  
                         if (!domain2->is_deleted ||  
                             ccs_pathcmp(domain2->domainname, &name))  
                                 continue;  
 #ifdef DEBUG_DOMAIN_UNDELETE  
                         if (domain2->is_deleted != 255)  
                                 printk(KERN_DEBUG  
                                        "Marked %p as non undeletable\n",  
                                        domain2);  
 #endif  
                         domain2->is_deleted = 255;  
                 }  
                 /* Delete and mark active domain as undeletable. */  
                 domain->is_deleted = 1;  
 #ifdef DEBUG_DOMAIN_UNDELETE  
                 printk(KERN_DEBUG "Marked %p as undeletable\n", domain);  
 #endif  
589                  break;                  break;
590          }          }
591          mutex_unlock(&ccs_domain_list_lock);          mutex_unlock(&ccs_policy_lock);
592          return 0;          return 0;
593  }  }
594    
595  /**  /**
  * ccs_undelete_domain - Undelete a domain.  
  *  
  * @domainname: The name of domain.  
  *  
  * Returns pointer to "struct domain_info" on success, NULL otherwise.  
  */  
 struct domain_info *ccs_undelete_domain(const char *domainname)  
 {  
         struct domain_info *domain;  
         struct domain_info *candidate_domain = NULL;  
         struct ccs_path_info name;  
         name.name = domainname;  
         ccs_fill_path_info(&name);  
         mutex_lock(&ccs_domain_list_lock);  
 #ifdef DEBUG_DOMAIN_UNDELETE  
         printk(KERN_DEBUG "ccs_undelete_domain %s\n", domainname);  
         list1_for_each_entry(domain, &ccs_domain_list, list) {  
                 if (ccs_pathcmp(domain->domainname, &name))  
                         continue;  
                 printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);  
         }  
 #endif  
         list1_for_each_entry(domain, &ccs_domain_list, list) {  
                 if (ccs_pathcmp(&name, domain->domainname))  
                         continue;  
                 if (!domain->is_deleted) {  
                         /* This domain is active. I can't undelete. */  
                         candidate_domain = NULL;  
 #ifdef DEBUG_DOMAIN_UNDELETE  
                         printk(KERN_DEBUG "%p is active. I can't undelete.\n",  
                                domain);  
 #endif  
                         break;  
                 }  
                 /* Is this domain undeletable? */  
                 if (domain->is_deleted == 1)  
                         candidate_domain = domain;  
         }  
         if (candidate_domain) {  
                 candidate_domain->is_deleted = 0;  
 #ifdef DEBUG_DOMAIN_UNDELETE  
                 printk(KERN_DEBUG "%p was undeleted.\n", candidate_domain);  
 #endif  
         }  
         mutex_unlock(&ccs_domain_list_lock);  
         return candidate_domain;  
 }  
   
 /**  
596   * ccs_find_or_assign_new_domain - Create a domain.   * ccs_find_or_assign_new_domain - Create a domain.
597   *   *
598   * @domainname: The name of domain.   * @domainname: The name of domain.
599   * @profile:    Profile number to assign if the domain was newly created.   * @profile:    Profile number to assign if the domain was newly created.
600   *   *
601   * Returns pointer to "struct domain_info" on success, NULL otherwise.   * Returns pointer to "struct ccs_domain_info" on success, NULL otherwise.
602   */   */
603  struct domain_info *ccs_find_or_assign_new_domain(const char *domainname,  struct ccs_domain_info *ccs_find_or_assign_new_domain(const char *domainname,
604                                                    const u8 profile)                                                        const u8 profile)
605  {  {
606          struct domain_info *domain = NULL;          struct ccs_domain_info *entry;
607            struct ccs_domain_info *domain;
608          const struct ccs_path_info *saved_domainname;          const struct ccs_path_info *saved_domainname;
609          mutex_lock(&ccs_domain_list_lock);          bool found = false;
610          domain = ccs_find_domain(domainname);  
611          if (domain)          if (!ccs_is_correct_domain(domainname))
612                  goto out;                  return NULL;
613          if (!ccs_is_correct_domain(domainname, __func__))          saved_domainname = ccs_get_name(domainname);
                 goto out;  
         saved_domainname = ccs_save_name(domainname);  
614          if (!saved_domainname)          if (!saved_domainname)
615                  goto out;                  return NULL;
616          /* Can I reuse memory of deleted domain? */          entry = kzalloc(sizeof(*entry), GFP_KERNEL);
617          list1_for_each_entry(domain, &ccs_domain_list, list) {          mutex_lock(&ccs_policy_lock);
618                  struct task_struct *p;          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
619                  struct ccs_acl_info *ptr;                  if (domain->is_deleted ||
620                  bool flag;                      ccs_pathcmp(saved_domainname, domain->domainname))
                 if (!domain->is_deleted ||  
                     domain->domainname != saved_domainname)  
                         continue;  
                 flag = false;  
                 /***** CRITICAL SECTION START *****/  
                 read_lock(&tasklist_lock);  
                 for_each_process(p) {  
                         if (p->domain_info != domain)  
                                 continue;  
                         flag = true;  
                         break;  
                 }  
                 read_unlock(&tasklist_lock);  
                 /***** CRITICAL SECTION END *****/  
                 if (flag)  
621                          continue;                          continue;
622  #ifdef DEBUG_DOMAIN_UNDELETE                  found = true;
623                  printk(KERN_DEBUG "Reusing %p %s\n", domain,                  break;
                        domain->domainname->name);  
 #endif  
                 list1_for_each_entry(ptr, &domain->acl_info_list, list) {  
                         ptr->type |= ACL_DELETED;  
                 }  
                 ccs_set_domain_flag(domain, true, domain->flags);  
                 domain->profile = profile;  
                 domain->quota_warned = false;  
                 mb(); /* Avoid out-of-order execution. */  
                 domain->is_deleted = 0;  
                 goto out;  
         }  
         /* No memory reusable. Create using new memory. */  
         domain = ccs_alloc_element(sizeof(*domain));  
         if (domain) {  
                 INIT_LIST1_HEAD(&domain->acl_info_list);  
                 domain->domainname = saved_domainname;  
                 domain->profile = profile;  
                 list1_add_tail_mb(&domain->list, &ccs_domain_list);  
624          }          }
625   out:          if (!found && ccs_memory_ok(entry, sizeof(*entry))) {
626          mutex_unlock(&ccs_domain_list_lock);                  INIT_LIST_HEAD(&entry->acl_info_list);
627          return domain;                  entry->domainname = saved_domainname;
628                    saved_domainname = NULL;
629                    entry->profile = profile;
630                    list_add_tail_rcu(&entry->list, &ccs_domain_list);
631                    domain = entry;
632                    entry = NULL;
633                    found = true;
634            }
635            mutex_unlock(&ccs_policy_lock);
636            ccs_put_name(saved_domainname);
637            kfree(entry);
638            return found ? domain : NULL;
639  }  }
640    
641  /**  /**
# Line 941  static bool ccs_get_argv0(struct ccs_exe Line 696  static bool ccs_get_argv0(struct ccs_exe
696  /**  /**
697   * ccs_find_next_domain - Find a domain.   * ccs_find_next_domain - Find a domain.
698   *   *
699   * @ee:      Pointer to "struct ccs_request_info".   * @ee: Pointer to "struct ccs_execve_entry".
700   *   *
701   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
702     *
703     * Caller holds srcu_read_lock(&ccs_ss).
704   */   */
705  static int ccs_find_next_domain(struct ccs_execve_entry *ee)  static int ccs_find_next_domain(struct ccs_execve_entry *ee)
706  {  {
707          struct ccs_request_info *r = &ee->r;          struct ccs_request_info *r = &ee->r;
708          const struct ccs_path_info *handler = ee->handler;          const struct ccs_path_info *handler = ee->handler;
709          struct domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
710          const char *old_domain_name = r->domain->domainname->name;          const char *old_domain_name = r->domain->domainname->name;
711          struct linux_binprm *bprm = ee->bprm;          struct linux_binprm *bprm = ee->bprm;
         const char *original_name = bprm->filename;  
712          const u8 mode = r->mode;          const u8 mode = r->mode;
713          const bool is_enforce = (mode == 3);          const bool is_enforce = (mode == 3);
714          const u32 tomoyo_flags = current->tomoyo_flags;          const u32 ccs_flags = current->ccs_flags;
715          char *new_domain_name = NULL;          char *new_domain_name = NULL;
716          struct ccs_path_info rn; /* real name */          struct ccs_path_info rn; /* real name */
         struct ccs_path_info sn; /* symlink name */  
717          struct ccs_path_info ln; /* last name */          struct ccs_path_info ln; /* last name */
718          int retval;          int retval;
   
         {  
                 /*  
                  * Built-in initializers. This is needed because policies are  
                  * not loaded until starting /sbin/init.  
                  */  
                 static bool first = true;  
                 if (first) {  
                         ccs_update_domain_initializer_entry(NULL,  
                                                             "/sbin/hotplug",  
                                                             false, false);  
                         ccs_update_domain_initializer_entry(NULL,  
                                                             "/sbin/modprobe",  
                                                             false, false);  
                         first = false;  
                 }  
         }  
   
719   retry:   retry:
720          current->tomoyo_flags = tomoyo_flags;          current->ccs_flags = ccs_flags;
721          r->cond = NULL;          r->cond = NULL;
722          /* Get ccs_realpath of program and symbolic link. */          /* Get symlink's pathname of program. */
723          retval = -ENOENT; /* I hope ccs_realpath() won't fail with -ENOMEM. */          retval = ccs_symlink_path(bprm->filename, ee);
724          if (!ccs_realpath_both(original_name, ee))          if (retval < 0)
725                  goto out;                  goto out;
726    
727          rn.name = ee->program_path;          rn.name = ee->program_path;
728          ccs_fill_path_info(&rn);          ccs_fill_path_info(&rn);
         sn.name = ee->tmp;  
         ccs_fill_path_info(&sn);  
729          ln.name = ccs_get_last_name(r->domain);          ln.name = ccs_get_last_name(r->domain);
730          ccs_fill_path_info(&ln);          ccs_fill_path_info(&ln);
731    
# Line 1008  static int ccs_find_next_domain(struct c Line 743  static int ccs_find_next_domain(struct c
743                  goto calculate_domain;                  goto calculate_domain;
744          }          }
745    
         /* Check 'alias' directive. */  
         if (ccs_pathcmp(&rn, &sn)) {  
                 struct ccs_alias_entry *ptr;  
                 /* Is this program allowed to be called via symbolic links? */  
                 list1_for_each_entry(ptr, &ccs_alias_list, list) {  
                         if (ptr->is_deleted ||  
                             ccs_pathcmp(&rn, ptr->original_name) ||  
                             ccs_pathcmp(&sn, ptr->aliased_name))  
                                 continue;  
                         strncpy(ee->program_path, ptr->aliased_name->name,  
                                 CCS_MAX_PATHNAME_LEN - 1);  
                         ccs_fill_path_info(&rn);  
                         break;  
                 }  
         }  
         /* sn will be overwritten after here. */  
   
746          /* Compare basename of program_path and argv[0] */          /* Compare basename of program_path and argv[0] */
747          r->mode = ccs_check_flags(r->domain, CCS_TOMOYO_MAC_FOR_ARGV0);          r->mode = ccs_check_flags(r->domain, CCS_MAC_FOR_ARGV0);
748          if (bprm->argc > 0 && r->mode) {          if (bprm->argc > 0 && r->mode) {
749                  char *base_argv0 = ee->tmp;                  char *base_argv0 = ee->tmp;
750                  const char *base_filename;                  const char *base_filename;
# Line 1051  static int ccs_find_next_domain(struct c Line 769  static int ccs_find_next_domain(struct c
769          {          {
770                  struct ccs_aggregator_entry *ptr;                  struct ccs_aggregator_entry *ptr;
771                  /* Is this program allowed to be aggregated? */                  /* Is this program allowed to be aggregated? */
772                  list1_for_each_entry(ptr, &ccs_aggregator_list, list) {                  list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) {
773                          if (ptr->is_deleted ||                          if (ptr->is_deleted ||
774                              !ccs_path_matches_pattern(&rn, ptr->original_name))                              !ccs_path_matches_pattern(&rn, ptr->original_name))
775                                  continue;                                  continue;
# Line 1073  static int ccs_find_next_domain(struct c Line 791  static int ccs_find_next_domain(struct c
791   calculate_domain:   calculate_domain:
792          new_domain_name = ee->tmp;          new_domain_name = ee->tmp;
793          if (ccs_is_domain_initializer(r->domain->domainname, &rn, &ln)) {          if (ccs_is_domain_initializer(r->domain->domainname, &rn, &ln)) {
794                  /* Transit to the child of KERNEL_DOMAIN domain. */                  /* Transit to the child of ccs_kernel_domain domain. */
795                  snprintf(new_domain_name, CCS_EXEC_TMPSIZE - 1,                  snprintf(new_domain_name, CCS_EXEC_TMPSIZE - 1,
796                           ROOT_NAME " " "%s", ee->program_path);                           ROOT_NAME " " "%s", ee->program_path);
797          } else if (r->domain == &KERNEL_DOMAIN && !ccs_policy_loaded) {          } else if (r->domain == &ccs_kernel_domain && !ccs_policy_loaded) {
798                  /*                  /*
799                   * Needn't to transit from kernel domain before starting                   * Needn't to transit from kernel domain before starting
800                   * /sbin/init. But transit from kernel domain if executing                   * /sbin/init. But transit from kernel domain if executing
# Line 1107  static int ccs_find_next_domain(struct c Line 825  static int ccs_find_next_domain(struct c
825          }          }
826          domain = ccs_find_or_assign_new_domain(new_domain_name, r->profile);          domain = ccs_find_or_assign_new_domain(new_domain_name, r->profile);
827          if (domain)          if (domain)
828                  ccs_audit_domain_creation_log(domain);                  ccs_audit_domain_creation_log(r->domain);
829   done:   done:
830          if (!domain) {          if (!domain) {
831                  printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",                  printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",
# Line 1116  static int ccs_find_next_domain(struct c Line 834  static int ccs_find_next_domain(struct c
834                          retval = -EPERM;                          retval = -EPERM;
835                  else {                  else {
836                          retval = 0;                          retval = 0;
837                          ccs_set_domain_flag(r->domain, false,                          r->domain->domain_transition_failed = true;
                                             DOMAIN_FLAGS_TRANSITION_FAILED);  
838                  }                  }
839          } else {          } else {
840                  retval = 0;                  retval = 0;
841          }          }
842   out:   out:
843          if (domain)          if (domain)
844                  r->domain = domain;                  r->domain = domain;
845          return retval;          return retval;
846  }  }
847    
# Line 1207  static int ccs_check_environ(struct ccs_ Line 924  static int ccs_check_environ(struct ccs_
924  /**  /**
925   * ccs_unescape - Unescape escaped string.   * ccs_unescape - Unescape escaped string.
926   *   *
927   * @dest: String to ccs_unescape.   * @dest: String to unescape.
928   *   *
929   * Returns nothing.   * Returns nothing.
930   */   */
# Line 1319  static DEFINE_SPINLOCK(ccs_execve_list_l Line 1036  static DEFINE_SPINLOCK(ccs_execve_list_l
1036   */   */
1037  static struct ccs_execve_entry *ccs_allocate_execve_entry(void)  static struct ccs_execve_entry *ccs_allocate_execve_entry(void)
1038  {  {
1039          struct ccs_execve_entry *ee = ccs_alloc(sizeof(*ee), false);          struct ccs_execve_entry *ee = kzalloc(sizeof(*ee), GFP_KERNEL);
1040          if (!ee)          if (!ee)
1041                  return NULL;                  return NULL;
1042          memset(ee, 0, sizeof(*ee));          ee->program_path = kzalloc(CCS_MAX_PATHNAME_LEN, GFP_KERNEL);
1043          ee->program_path = ccs_alloc(CCS_MAX_PATHNAME_LEN, false);          ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, GFP_KERNEL);
         ee->tmp = ccs_alloc(CCS_MAX_PATHNAME_LEN, false);  
1044          if (!ee->program_path || !ee->tmp) {          if (!ee->program_path || !ee->tmp) {
1045                  ccs_free(ee->program_path);                  kfree(ee->program_path);
1046                  ccs_free(ee->tmp);                  kfree(ee->tmp);
1047                  ccs_free(ee);                  kfree(ee);
1048                  return NULL;                  return NULL;
1049          }          }
1050            ee->srcu_idx = srcu_read_lock(&ccs_ss);
1051          /* ee->dump->data is allocated by ccs_dump_page(). */          /* ee->dump->data is allocated by ccs_dump_page(). */
1052          ee->task = current;          ee->task = current;
1053          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
# Line 1378  static void ccs_free_execve_entry(struct Line 1095  static void ccs_free_execve_entry(struct
1095          list_del(&ee->list);          list_del(&ee->list);
1096          spin_unlock(&ccs_execve_list_lock);          spin_unlock(&ccs_execve_list_lock);
1097          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
1098          ccs_free(ee->program_path);          kfree(ee->program_path);
1099          ccs_free(ee->tmp);          kfree(ee->tmp);
1100          kfree(ee->dump.data);          kfree(ee->dump.data);
1101          ccs_free(ee);          srcu_read_unlock(&ccs_ss, ee->srcu_idx);
1102            kfree(ee);
1103  }  }
1104    
1105  /**  /**
1106   * ccs_try_alt_exec - Try to start execute handler.   * ccs_try_alt_exec - Try to start execute handler.
1107   *   *
1108   * @ee:          Pointer to "struct ccs_execve_entry".   * @ee: Pointer to "struct ccs_execve_entry".
1109   *   *
1110   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1111   */   */
# Line 1407  static int ccs_try_alt_exec(struct ccs_e Line 1125  static int ccs_try_alt_exec(struct ccs_e
1125           * modified bprm->argv[0]           * modified bprm->argv[0]
1126           *    = the program's name specified by execute_handler           *    = the program's name specified by execute_handler
1127           * modified bprm->argv[1]           * modified bprm->argv[1]
1128           *    = current->domain_info->domainname->name           *    = ccs_current_domain()->domainname->name
1129           * modified bprm->argv[2]           * modified bprm->argv[2]
1130           *    = the current process's name           *    = the current process's name
1131           * modified bprm->argv[3]           * modified bprm->argv[3]
# Line 1470  static int ccs_try_alt_exec(struct ccs_e Line 1188  static int ccs_try_alt_exec(struct ccs_e
1188    
1189          /* Set argv[4] */          /* Set argv[4] */
1190          {          {
1191                  retval = copy_strings_kernel(1, (char **) &bprm->filename,                  retval = copy_strings_kernel(1, &bprm->filename, bprm);
                                              bprm);  
1192                  if (retval < 0)                  if (retval < 0)
1193                          goto out;                          goto out;
1194                  bprm->argc++;                  bprm->argc++;
# Line 1480  static int ccs_try_alt_exec(struct ccs_e Line 1197  static int ccs_try_alt_exec(struct ccs_e
1197          /* Set argv[3] */          /* Set argv[3] */
1198          {          {
1199                  char *cp = ee->tmp;                  char *cp = ee->tmp;
1200                  const u32 tomoyo_flags = task->tomoyo_flags;                  const u32 ccs_flags = task->ccs_flags;
1201                  snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1,                  snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1,
1202                           "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "                           "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
1203                           "sgid=%d fsuid=%d fsgid=%d state[0]=%u "                           "sgid=%d fsuid=%d fsgid=%d state[0]=%u "
# Line 1488  static int ccs_try_alt_exec(struct ccs_e Line 1205  static int ccs_try_alt_exec(struct ccs_e
1205                           (pid_t) sys_getpid(), current_uid(), current_gid(),                           (pid_t) sys_getpid(), current_uid(), current_gid(),
1206                           current_euid(), current_egid(), current_suid(),                           current_euid(), current_egid(), current_suid(),
1207                           current_sgid(), current_fsuid(), current_fsgid(),                           current_sgid(), current_fsuid(), current_fsgid(),
1208                           (u8) (tomoyo_flags >> 24), (u8) (tomoyo_flags >> 16),                           (u8) (ccs_flags >> 24), (u8) (ccs_flags >> 16),
1209                           (u8) (tomoyo_flags >> 8));                           (u8) (ccs_flags >> 8));
1210                  retval = copy_strings_kernel(1, &cp, bprm);                  retval = copy_strings_kernel(1, &cp, bprm);
1211                  if (retval < 0)                  if (retval < 0)
1212                          goto out;                          goto out;
# Line 1501  static int ccs_try_alt_exec(struct ccs_e Line 1218  static int ccs_try_alt_exec(struct ccs_e
1218                  char *exe = (char *) ccs_get_exe();                  char *exe = (char *) ccs_get_exe();
1219                  if (exe) {                  if (exe) {
1220                          retval = copy_strings_kernel(1, &exe, bprm);                          retval = copy_strings_kernel(1, &exe, bprm);
1221                          ccs_free(exe);                          kfree(exe);
1222                  } else {                  } else {
1223                          exe = ee->tmp;                          exe = ee->tmp;
1224                          strncpy(ee->tmp, "<unknown>", CCS_EXEC_TMPSIZE - 1);                          strncpy(ee->tmp, "<unknown>", CCS_EXEC_TMPSIZE - 1);
# Line 1515  static int ccs_try_alt_exec(struct ccs_e Line 1232  static int ccs_try_alt_exec(struct ccs_e
1232          /* Set argv[1] */          /* Set argv[1] */
1233          {          {
1234                  char *cp = ee->tmp;                  char *cp = ee->tmp;
1235                  strncpy(ee->tmp, task->domain_info->domainname->name,                  strncpy(ee->tmp, ccs_current_domain()->domainname->name,
1236                          CCS_EXEC_TMPSIZE - 1);                          CCS_EXEC_TMPSIZE - 1);
1237                  retval = copy_strings_kernel(1, &cp, bprm);                  retval = copy_strings_kernel(1, &cp, bprm);
1238                  if (retval < 0)                  if (retval < 0)
# Line 1561  static int ccs_try_alt_exec(struct ccs_e Line 1278  static int ccs_try_alt_exec(struct ccs_e
1278          bprm->file = filp;          bprm->file = filp;
1279          bprm->filename = ee->program_path;          bprm->filename = ee->program_path;
1280  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1281          bprm->interp = ee->program_path;          bprm->interp = bprm->filename;
1282  #endif  #endif
1283          retval = prepare_binprm(bprm);          retval = prepare_binprm(bprm);
1284          if (retval < 0)          if (retval < 0)
1285                  goto out;                  goto out;
1286          /*          {
1287           * Backup ee->propgram_path for ccs_find_next_domain().                  /*
1288           * ee->program_path will be overwritten by ccs_find_next_domain().                   * Backup ee->program_path because ccs_find_next_domain() will
1289           * But ee->tmp won't be overwritten by ccs_find_next_domain()                   * overwrite ee->program_path and ee->tmp.
1290           * because ee->handler != NULL.                   */
1291           */                  const int len = strlen(ee->program_path) + 1;
1292          strncpy(ee->tmp, ee->program_path, CCS_EXEC_TMPSIZE - 1);                  char *cp = kzalloc(len, GFP_KERNEL);
1293          task->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;                  if (!cp) {
1294          retval = ccs_find_next_domain(ee);                          retval = -ENOMEM;
1295          task->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;                          goto out;
1296          /*                  }
1297           * Restore ee->program_path for search_binary_handler().                  memmove(cp, ee->program_path, len);
1298           */                  bprm->filename = cp;
1299          strncpy(ee->program_path, ee->tmp, CCS_MAX_PATHNAME_LEN - 1);  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1300                    bprm->interp = bprm->filename;
1301    #endif
1302                    task->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
1303                    retval = ccs_find_next_domain(ee);
1304                    task->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
1305                    /* Restore ee->program_path for search_binary_handler(). */
1306                    memmove(ee->program_path, cp, len);
1307                    bprm->filename = ee->program_path;
1308    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1309                    bprm->interp = bprm->filename;
1310    #endif
1311                    kfree(cp);
1312            }
1313   out:   out:
1314          return retval;          return retval;
1315  }  }
# Line 1590  static int ccs_try_alt_exec(struct ccs_e Line 1320  static int ccs_try_alt_exec(struct ccs_e
1320   * @ee:   Pointer to "struct ccs_execve_entry".   * @ee:   Pointer to "struct ccs_execve_entry".
1321   * @type: Type of execute handler.   * @type: Type of execute handler.
1322   *   *
1323   * Returns bool if found, false otherwise.   * Returns true if found, false otherwise.
1324     *
1325     * Caller holds srcu_read_lock(&ccs_ss).
1326   */   */
1327  static bool ccs_find_execute_handler(struct ccs_execve_entry *ee,  static bool ccs_find_execute_handler(struct ccs_execve_entry *ee,
1328                                       const u8 type)                                       const u8 type)
1329  {  {
1330          struct task_struct *task = current;          struct task_struct *task = current;
1331          const struct domain_info *domain = task->domain_info;          const struct ccs_domain_info *domain = ccs_current_domain();
1332          struct ccs_acl_info *ptr;          struct ccs_acl_info *ptr;
1333            bool found = false;
1334          /*          /*
1335           * Don't use execute handler if the current process is           * Don't use execute handler if the current process is
1336           * marked as execute handler to avoid infinite execute handler loop.           * marked as execute handler to avoid infinite execute handler loop.
1337           */           */
1338          if (task->tomoyo_flags & TOMOYO_TASK_IS_EXECUTE_HANDLER)          if (task->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)
1339                  return false;                  return false;
1340          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list_for_each_entry(ptr, &domain->acl_info_list, list) {
1341                  struct ccs_execute_handler_record *acl;                  struct ccs_execute_handler_record *acl;
1342                  if (ptr->type != type)                  if (ptr->type != type)
1343                          continue;                          continue;
1344                  acl = container_of(ptr, struct ccs_execute_handler_record,                  acl = container_of(ptr, struct ccs_execute_handler_record,
1345                                     head);                                     head);
1346                  ee->handler = acl->handler;                  ee->handler = acl->handler;
1347                  return true;                  found = true;
1348                    break;
1349          }          }
1350          return false;          return found;
1351  }  }
1352    
1353  /**  /**
# Line 1631  bool ccs_dump_page(struct linux_binprm * Line 1365  bool ccs_dump_page(struct linux_binprm *
1365          struct page *page;          struct page *page;
1366          /* dump->data is released by ccs_free_execve_entry(). */          /* dump->data is released by ccs_free_execve_entry(). */
1367          if (!dump->data) {          if (!dump->data) {
1368                  dump->data = kmalloc(PAGE_SIZE, GFP_KERNEL);                  dump->data = kzalloc(PAGE_SIZE, GFP_KERNEL);
1369                  if (!dump->data)                  if (!dump->data)
1370                          return false;                          return false;
1371          }          }
# Line 1639  bool ccs_dump_page(struct linux_binprm * Line 1373  bool ccs_dump_page(struct linux_binprm *
1373  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1374          if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)          if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
1375                  return false;                  return false;
1376    #elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR == 3 && defined(CONFIG_MMU)
1377            if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
1378                    return false;
1379  #else  #else
1380          page = bprm->page[pos / PAGE_SIZE];          page = bprm->page[pos / PAGE_SIZE];
1381  #endif  #endif
# Line 1657  bool ccs_dump_page(struct linux_binprm * Line 1394  bool ccs_dump_page(struct linux_binprm *
1394          /* Same with put_arg_page(page) in fs/exec.c */          /* Same with put_arg_page(page) in fs/exec.c */
1395  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1396          put_page(page);          put_page(page);
1397    #elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR == 3 && defined(CONFIG_MMU)
1398            put_page(page);
1399  #endif  #endif
1400          return true;          return true;
1401  }  }
# Line 1664  bool ccs_dump_page(struct linux_binprm * Line 1403  bool ccs_dump_page(struct linux_binprm *
1403  /**  /**
1404   * ccs_fetch_next_domain - Fetch next_domain from the list.   * ccs_fetch_next_domain - Fetch next_domain from the list.
1405   *   *
1406   * Returns pointer to "struct domain_info" which will be used if execve()   * Returns pointer to "struct ccs_domain_info" which will be used if execve()
1407   * succeeds. This function does not return NULL.   * succeeds. This function does not return NULL.
1408   */   */
1409  struct domain_info *ccs_fetch_next_domain(void)  struct ccs_domain_info *ccs_fetch_next_domain(void)
1410  {  {
1411          struct ccs_execve_entry *ee = ccs_find_execve_entry();          struct ccs_execve_entry *ee = ccs_find_execve_entry();
1412          struct domain_info *next_domain = NULL;          struct ccs_domain_info *next_domain = NULL;
1413          if (ee)          if (ee)
1414                  next_domain = ee->next_domain;                  next_domain = ee->r.domain;
1415          if (!next_domain)          if (!next_domain)
1416                  next_domain = current->domain_info;                  next_domain = ccs_current_domain();
1417          return next_domain;          return next_domain;
1418  }  }
1419    
# Line 1694  int ccs_start_execve(struct linux_binprm Line 1433  int ccs_start_execve(struct linux_binprm
1433                  ccs_load_policy(bprm->filename);                  ccs_load_policy(bprm->filename);
1434          if (!ee)          if (!ee)
1435                  return -ENOMEM;                  return -ENOMEM;
1436          ccs_init_request_info(&ee->r, NULL, CCS_TOMOYO_MAC_FOR_FILE);          ccs_init_request_info(&ee->r, NULL, CCS_MAC_FOR_FILE);
1437          ee->r.ee = ee;          ee->r.ee = ee;
1438          ee->bprm = bprm;          ee->bprm = bprm;
1439          ee->r.obj = &ee->obj;          ee->r.obj = &ee->obj;
1440          ee->obj.path1_dentry = bprm->file->f_dentry;          ee->obj.path1_dentry = bprm->file->f_dentry;
1441          ee->obj.path1_vfsmnt = bprm->file->f_vfsmnt;          ee->obj.path1_vfsmnt = bprm->file->f_vfsmnt;
1442          /* Clear manager flag. */          /* Clear manager flag. */
1443          task->tomoyo_flags &= ~CCS_TASK_IS_POLICY_MANAGER;          task->ccs_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
1444          if (ccs_find_execute_handler(ee, TYPE_EXECUTE_HANDLER)) {          if (ccs_find_execute_handler(ee, TYPE_EXECUTE_HANDLER)) {
1445                  retval = ccs_try_alt_exec(ee);                  retval = ccs_try_alt_exec(ee);
1446                  if (!retval)                  if (!retval)
# Line 1719  int ccs_start_execve(struct linux_binprm Line 1458  int ccs_start_execve(struct linux_binprm
1458   ok:   ok:
1459          if (retval < 0)          if (retval < 0)
1460                  goto out;                  goto out;
1461          ee->r.mode = ccs_check_flags(ee->r.domain, CCS_TOMOYO_MAC_FOR_ENV);          ee->r.mode = ccs_check_flags(ee->r.domain, CCS_MAC_FOR_ENV);
1462          retval = ccs_check_environ(ee);          retval = ccs_check_environ(ee);
1463          if (retval < 0)          if (retval < 0)
1464                  goto out;                  goto out;
1465          ee->next_domain = ee->r.domain;          task->ccs_flags |= CCS_CHECK_READ_FOR_OPEN_EXEC;
         task->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC;  
1466          retval = 0;          retval = 0;
1467   out:   out:
1468          if (retval)          if (retval)
# Line 1734  int ccs_start_execve(struct linux_binprm Line 1472  int ccs_start_execve(struct linux_binprm
1472    
1473  /**  /**
1474   * ccs_finish_execve - Clean up execve() operation.   * ccs_finish_execve - Clean up execve() operation.
1475     *
1476     * @retval: Return code of an execve() operation.
1477     *
1478     * Caller holds srcu_read_lock(&ccs_ss).
1479   */   */
1480  void ccs_finish_execve(int retval)  void ccs_finish_execve(int retval)
1481  {  {
1482          struct task_struct *task = current;          struct task_struct *task = current;
1483          struct ccs_execve_entry *ee = ccs_find_execve_entry();          struct ccs_execve_entry *ee = ccs_find_execve_entry();
1484          task->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;          task->ccs_flags &= ~CCS_CHECK_READ_FOR_OPEN_EXEC;
1485          if (!ee)          if (!ee)
1486                  return;                  return;
1487          if (retval < 0)          if (retval < 0)
1488                  goto out;                  goto out;
1489          /* Proceed to next domain if execution suceeded. */          /* Proceed to next domain if execution suceeded. */
1490          task->domain_info = ee->r.domain;          task->ccs_domain_info = ee->r.domain;
         mb(); /* Make domain transition visible to other CPUs. */  
1491          /* Mark the current process as execute handler. */          /* Mark the current process as execute handler. */
1492          if (ee->handler)          if (ee->handler)
1493                  task->tomoyo_flags |= TOMOYO_TASK_IS_EXECUTE_HANDLER;                  task->ccs_flags |= CCS_TASK_IS_EXECUTE_HANDLER;
1494          /* Mark the current process as normal process. */          /* Mark the current process as normal process. */
1495          else          else
1496                  task->tomoyo_flags &= ~TOMOYO_TASK_IS_EXECUTE_HANDLER;                  task->ccs_flags &= ~CCS_TASK_IS_EXECUTE_HANDLER;
1497   out:   out:
1498          ccs_free_execve_entry(ee);          ccs_free_execve_entry(ee);
1499  }  }
   
 #else  
   
 /**  
  * ccs_start_execve - Prepare for execve() operation.  
  *  
  * @bprm: Pointer to "struct linux_binprm".  
  *  
  * Returns 0.  
  */  
 static inline int ccs_start_execve(struct linux_binprm *bprm)  
 {  
 #ifdef CONFIG_SAKURA  
         /* Clear manager flag. */  
         current->tomoyo_flags &= ~CCS_TASK_IS_POLICY_MANAGER;  
         if (!ccs_policy_loaded)  
                 ccs_load_policy(bprm->filename);  
 #endif  
         return 0;  
 }  
   
 /**  
  * ccs_finish_execve - Clean up execve() operation.  
  */  
 static inline void ccs_finish_execve(int retval)  
 {  
 }  
   
 #endif  

Legend:
Removed from v.2048  
changed lines
  Added in v.2738

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