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

Subversion リポジトリの参照

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

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

revision 3904 by kumaneko, Thu Aug 19 08:12:59 2010 UTC revision 3905 by kumaneko, Thu Aug 19 12:10:48 2010 UTC
# Line 38  struct list_head ccs_group_list[CCS_MAX_ Line 38  struct list_head ccs_group_list[CCS_MAX_
38  struct list_head ccs_shared_list[CCS_MAX_LIST];  struct list_head ccs_shared_list[CCS_MAX_LIST];
39    
40  /**  /**
  * ccs_audit_execute_handler_log - Audit execute_handler log.  
  *  
  * @ee:         Pointer to "struct ccs_execve".  
  *  
  * Returns 0 on success, negative value otherwise.  
  */  
 static int ccs_audit_execute_handler_log(struct ccs_execve *ee)  
 {  
         struct ccs_request_info *r = &ee->r;  
         const char *handler = ee->handler->name;  
         r->type = CCS_MAC_FILE_EXECUTE;  
         r->mode = ccs_get_mode(r->profile, CCS_MAC_FILE_EXECUTE);  
         r->granted = true;  
         return ccs_write_log(r, "%s %s\n", ee->handler_type ==  
                              CCS_TYPE_DENIED_EXECUTE_HANDLER ?  
                              CCS_KEYWORD_DENIED_EXECUTE_HANDLER :  
                              CCS_KEYWORD_EXECUTE_HANDLER, handler);  
 }  
   
 /**  
  * ccs_audit_domain_creation_log - Audit domain creation log.  
  *  
  * Returns 0 on success, negative value otherwise.  
  */  
 static int ccs_audit_domain_creation_log(void)  
 {  
         struct ccs_request_info r;  
         ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE);  
         r.granted = false;  
         return ccs_write_log(&r, "use_profile %u\n", r.profile);  
 }  
   
 /**  
41   * ccs_update_policy - Update an entry for exception policy.   * ccs_update_policy - Update an entry for exception policy.
42   *   *
43   * @new_entry:       Pointer to "struct ccs_acl_info".   * @new_entry:       Pointer to "struct ccs_acl_info".
# Line 438  int ccs_delete_domain(char *domainname) Line 405  int ccs_delete_domain(char *domainname)
405   * @domainname: The name of domain.   * @domainname: The name of domain.
406   * @profile:    Profile number to assign if the domain was newly created.   * @profile:    Profile number to assign if the domain was newly created.
407   * @group:      Group number to assign if the domain was newly created.   * @group:      Group number to assign if the domain was newly created.
408     * @transit:    True if transit to domain found or created.
409   *   *
410   * Returns pointer to "struct ccs_domain_info" on success, NULL otherwise.   * Returns pointer to "struct ccs_domain_info" on success, NULL otherwise.
411     *
412     * Caller holds ccs_read_lock().
413   */   */
414  struct ccs_domain_info *ccs_assign_domain(const char *domainname,  struct ccs_domain_info *ccs_assign_domain(const char *domainname,
415                                            const u8 profile, const u8 group)                                            const u8 profile, const u8 group,
416                                              const bool transit)
417  {  {
418          struct ccs_domain_info e = { };          struct ccs_domain_info e = { };
419          struct ccs_domain_info *entry = NULL;          struct ccs_domain_info *entry = ccs_find_domain(domainname);
420          bool found = false;          bool created = false;
421            if (entry)
422          if (!ccs_correct_domain(domainname))                  goto out;
423            if (strlen(domainname) >= CCS_EXEC_TMPSIZE - 10 ||
424                !ccs_correct_domain(domainname))
425                  return NULL;                  return NULL;
426          e.profile = profile;          e.profile = profile;
427          e.group = group;          e.group = group;
# Line 457  struct ccs_domain_info *ccs_assign_domai Line 430  struct ccs_domain_info *ccs_assign_domai
430                  return NULL;                  return NULL;
431          if (mutex_lock_interruptible(&ccs_policy_lock))          if (mutex_lock_interruptible(&ccs_policy_lock))
432                  goto out;                  goto out;
433          list_for_each_entry_rcu(entry, &ccs_domain_list, list) {          entry = ccs_find_domain(domainname);
434                  if (entry->is_deleted ||          if (!entry) {
                     ccs_pathcmp(e.domainname, entry->domainname))  
                         continue;  
                 found = true;  
                 break;  
         }  
         if (!found) {  
435                  entry = ccs_commit_ok(&e, sizeof(e));                  entry = ccs_commit_ok(&e, sizeof(e));
436                  if (entry) {                  if (entry) {
437                          INIT_LIST_HEAD(&entry->acl_info_list);                          INIT_LIST_HEAD(&entry->acl_info_list);
438                          list_add_tail_rcu(&entry->list, &ccs_domain_list);                          list_add_tail_rcu(&entry->list, &ccs_domain_list);
439                          found = true;                          created = true;
440                  }                  }
441          }          }
442          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
443   out:   out:
444          ccs_put_name(e.domainname);          ccs_put_name(e.domainname);
445          return found ? entry : NULL;          if (entry && transit) {
446                    current->ccs_domain_info = entry;
447                    if (created) {
448                            struct ccs_request_info r;
449                            ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE);
450                            r.granted = false;
451                            ccs_write_log(&r, "use_profile %u\n", r.profile);
452                    }
453            }
454            return entry;
455  }  }
456    
457  /**  /**
# Line 499  static int ccs_find_next_domain(struct c Line 475  static int ccs_find_next_domain(struct c
475          struct ccs_path_info rn = { }; /* real name */          struct ccs_path_info rn = { }; /* real name */
476          int retval;          int retval;
477          bool need_kfree = false;          bool need_kfree = false;
         bool domain_created = false;  
478   retry:   retry:
479          current->ccs_flags = ccs_flags;          current->ccs_flags = ccs_flags;
480          r->cond = NULL;          r->cond = NULL;
# Line 525  static int ccs_find_next_domain(struct c Line 500  static int ccs_find_next_domain(struct c
500                          }                          }
501                          goto out;                          goto out;
502                  }                  }
503                    r->type = CCS_MAC_FILE_EXECUTE;
504                    r->mode = ccs_get_mode(r->profile, CCS_MAC_FILE_EXECUTE);
505                    r->granted = true;
506                    ccs_write_log(r, "%s %s\n", ee->handler_type ==
507                                  CCS_TYPE_DENIED_EXECUTE_HANDLER ?
508                                  CCS_KEYWORD_DENIED_EXECUTE_HANDLER :
509                                  CCS_KEYWORD_EXECUTE_HANDLER, handler->name);
510          } else {          } else {
511                  struct ccs_aggregator *ptr;                  struct ccs_aggregator *ptr;
512                  /* Check 'aggregator' directive. */                  /* Check 'aggregator' directive. */
# Line 589  static int ccs_find_next_domain(struct c Line 571  static int ccs_find_next_domain(struct c
571                  }                  }
572                  break;                  break;
573          }          }
         if (domain || strlen(ee->tmp) >= CCS_EXEC_TMPSIZE - 10)  
                 goto done;  
         domain = ccs_find_domain(ee->tmp);  
         if (domain)  
                 goto done;  
         if (r->mode == CCS_CONFIG_ENFORCING) {  
                 int error = ccs_supervisor(r, "# wants to create domain\n"  
                                            "%s\n", ee->tmp);  
                 if (error == CCS_RETRY_REQUEST)  
                         goto retry;  
                 if (error < 0)  
                         goto done;  
         }  
         domain = ccs_assign_domain(ee->tmp, r->profile, old_domain->group);  
         if (domain)  
                 domain_created = true;  
  done:  
         if (!domain) {  
                 retval = (r->mode == CCS_CONFIG_ENFORCING) ? -EPERM : 0;  
                 if (!old_domain->flags[CCS_DIF_TRANSITION_FAILED]) {  
                         old_domain->flags[CCS_DIF_TRANSITION_FAILED] = true;  
                         r->granted = false;  
                         ccs_write_log(r, CCS_KEYWORD_TRANSITION_FAILED "\n");  
                         printk(KERN_WARNING  
                                "ERROR: Domain '%s' not defined.\n", ee->tmp);  
                 }  
         } else {  
                 retval = 0;  
         }  
         if (!retval && handler)  
                 ccs_audit_execute_handler_log(ee);  
574          /*          /*
575           * Tell GC that I started execve().           * Tell GC that I started execve().
576           * Also, tell open_exec() to check read permission.           * Also, tell open_exec() to check read permission.
# Line 636  static int ccs_find_next_domain(struct c Line 587  static int ccs_find_next_domain(struct c
587           * But it is better than being unable to reach via PID in interactive           * But it is better than being unable to reach via PID in interactive
588           * enforcing mode.           * enforcing mode.
589           */           */
590            if (!domain)
591                    domain = ccs_assign_domain(ee->tmp, r->profile,
592                                               old_domain->group, true);
593          if (domain)          if (domain)
594                  task->ccs_domain_info = domain;                  retval = 0;
595          if (domain_created)          else if (r->mode == CCS_CONFIG_ENFORCING)
596                  ccs_audit_domain_creation_log();                  retval = -ENOMEM;
597            else {
598                    retval = 0;
599                    if (!old_domain->flags[CCS_DIF_TRANSITION_FAILED]) {
600                            old_domain->flags[CCS_DIF_TRANSITION_FAILED] = true;
601                            r->granted = false;
602                            ccs_write_log(r, CCS_KEYWORD_TRANSITION_FAILED "\n");
603                            printk(KERN_WARNING
604                                   "ERROR: Domain '%s' not defined.\n", ee->tmp);
605                    }
606            }
607   out:   out:
608          if (need_kfree)          if (need_kfree)
609                  kfree(rn.name);                  kfree(rn.name);
# Line 1183  static void ccs_finish_execve(int retval Line 1147  static void ccs_finish_execve(int retval
1147          kfree(ee);          kfree(ee);
1148  }  }
1149    
 /**  
  * ccs_may_transit - Check permission and do domain transition without execve().  
  *  
  * @domainname: Domainname to transit to.  
  * @pathname: Pathname to check.  
  *  
  * Returns 0 on success, negative value otherwise.  
  *  
  * Caller holds ccs_read_lock().  
  */  
 int ccs_may_transit(const char *domainname, const char *pathname)  
 {  
         struct ccs_path_info name;  
         struct ccs_request_info r;  
         struct ccs_domain_info *domain;  
         int error;  
         bool domain_created = false;  
         name.name = pathname;  
         ccs_fill_path_info(&name);  
         /* Check "file transit" permission. */  
         ccs_init_request_info(&r, CCS_MAC_FILE_TRANSIT);  
         error = ccs_path_permission(&r, CCS_TYPE_TRANSIT, &name);  
         if (error)  
                 return error;  
         /* Check destination domain. */  
         domain = ccs_find_domain(domainname);  
         if (!domain && r.mode != CCS_CONFIG_ENFORCING &&  
             strlen(domainname) < CCS_EXEC_TMPSIZE - 10) {  
                 domain = ccs_assign_domain(domainname, r.profile,  
                                            ccs_current_domain()->group);  
                 if (domain)  
                         domain_created = true;  
         }  
         if (domain) {  
                 error = 0;  
                 current->ccs_domain_info = domain;  
                 if (domain_created)  
                         ccs_audit_domain_creation_log();  
         } else {  
                 error = -ENOENT;  
         }  
         return error;  
 }  
   
1150  static int __ccs_search_binary_handler(struct linux_binprm *bprm,  static int __ccs_search_binary_handler(struct linux_binprm *bprm,
1151                                         struct pt_regs *regs)                                         struct pt_regs *regs)
1152  {  {

Legend:
Removed from v.3904  
changed lines
  Added in v.3905

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