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

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 2968 by kumaneko, Fri Aug 28 07:09:03 2009 UTC revision 3109 by kumaneko, Fri Oct 16 05:02:23 2009 UTC
# Line 3  Line 3 
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2009  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0-pre   2009/08/24   * Version: 1.7.1-pre   2009/10/16
7   *   *
8   * 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.
9   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 22  Line 22 
22  #endif  #endif
23  #include "internal.h"  #include "internal.h"
24    
 /* For compatibility with older kernels. */  
 #ifndef for_each_process  
 #define for_each_process for_each_task  
 #endif  
   
25  /* Variables definitions.*/  /* Variables definitions.*/
26    
27  /* The initial domain. */  /* The initial domain. */
# Line 862  static int ccs_get_root_depth(void) Line 857  static int ccs_get_root_depth(void)
857          return depth;          return depth;
858  }  }
859    
 static LIST_HEAD(ccs_execve_list);  
 static DEFINE_SPINLOCK(ccs_execve_list_lock);  
   
 /**  
  * ccs_allocate_execve_entry - Allocate memory for execve().  
  *  
  * Returns pointer to "struct ccs_execve_entry" on success, NULL otherwise.  
  */  
 static struct ccs_execve_entry *ccs_allocate_execve_entry(void)  
 {  
         struct ccs_execve_entry *ee = kzalloc(sizeof(*ee), GFP_KERNEL);  
         if (!ee)  
                 return NULL;  
         ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, GFP_KERNEL);  
         if (!ee->tmp) {  
                 kfree(ee);  
                 return NULL;  
         }  
         ee->reader_idx = ccs_read_lock();  
         /* ee->dump->data is allocated by ccs_dump_page(). */  
         ee->task = current;  
         ee->previous_domain = ee->task->ccs_domain_info;  
         spin_lock(&ccs_execve_list_lock);  
         list_add(&ee->list, &ccs_execve_list);  
         spin_unlock(&ccs_execve_list_lock);  
         return ee;  
 }  
   
 /**  
  * ccs_find_execve_entry - Find ccs_execve_entry of current process.  
  *  
  * @task: Task to find.  
  *  
  * Returns pointer to "struct ccs_execve_entry" on success, NULL otherwise.  
  */  
 static struct ccs_execve_entry *ccs_find_execve_entry(struct task_struct *task)  
 {  
         struct ccs_execve_entry *ee = NULL;  
         struct ccs_execve_entry *p;  
         spin_lock(&ccs_execve_list_lock);  
         list_for_each_entry(p, &ccs_execve_list, list) {  
                 if (p->task != task)  
                         continue;  
                 ee = p;  
                 break;  
         }  
         spin_unlock(&ccs_execve_list_lock);  
         return ee;  
 }  
   
 /**  
  * ccs_free_execve_entry - Free memory for execve().  
  *  
  * @ee: Pointer to "struct ccs_execve_entry".  
  */  
 static void ccs_free_execve_entry(struct ccs_execve_entry *ee)  
 {  
         if (!ee)  
                 return;  
         spin_lock(&ccs_execve_list_lock);  
         list_del(&ee->list);  
         spin_unlock(&ccs_execve_list_lock);  
         kfree(ee->handler_path);  
         kfree(ee->tmp);  
         kfree(ee->dump.data);  
         ccs_read_unlock(ee->reader_idx);  
         kfree(ee);  
 }  
   
860  /**  /**
861   * ccs_try_alt_exec - Try to start execute handler.   * ccs_try_alt_exec - Try to start execute handler.
862   *   *
# Line 984  static int ccs_try_alt_exec(struct ccs_e Line 910  static int ccs_try_alt_exec(struct ccs_e
910          struct task_struct *task = current;          struct task_struct *task = current;
911    
912          /* Close the requested program's dentry. */          /* Close the requested program's dentry. */
913            ee->obj.path1.dentry = NULL;
914            ee->obj.path1.mnt = NULL;
915            ee->obj.validate_done = false;
916          allow_write_access(bprm->file);          allow_write_access(bprm->file);
917          fput(bprm->file);          fput(bprm->file);
918          bprm->file = NULL;          bprm->file = NULL;
# Line 1075  static int ccs_try_alt_exec(struct ccs_e Line 1004  static int ccs_try_alt_exec(struct ccs_e
1004                  int len = ee->handler->total_len + 1;                  int len = ee->handler->total_len + 1;
1005                  char *cp = kmalloc(len, GFP_KERNEL);                  char *cp = kmalloc(len, GFP_KERNEL);
1006                  if (!cp) {                  if (!cp) {
1007                          retval = ENOMEM;                          retval = -ENOMEM;
1008                          goto out;                          goto out;
1009                  }                  }
1010                  ee->handler_path = cp;                  ee->handler_path = cp;
# Line 1110  static int ccs_try_alt_exec(struct ccs_e Line 1039  static int ccs_try_alt_exec(struct ccs_e
1039                  retval = PTR_ERR(filp);                  retval = PTR_ERR(filp);
1040                  goto out;                  goto out;
1041          }          }
1042            ee->obj.path1.dentry = filp->f_dentry;
1043            ee->obj.path1.mnt = filp->f_vfsmnt;
1044          bprm->file = filp;          bprm->file = filp;
1045          bprm->filename = ee->handler_path;          bprm->filename = ee->handler_path;
1046  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
# Line 1174  bool ccs_dump_page(struct linux_binprm * Line 1105  bool ccs_dump_page(struct linux_binprm *
1105                     struct ccs_page_dump *dump)                     struct ccs_page_dump *dump)
1106  {  {
1107          struct page *page;          struct page *page;
1108          /* dump->data is released by ccs_free_execve_entry(). */          /* dump->data is released by ccs_finish_execve(). */
1109          if (!dump->data) {          if (!dump->data) {
1110                  dump->data = kzalloc(PAGE_SIZE, GFP_KERNEL);                  dump->data = kzalloc(PAGE_SIZE, GFP_KERNEL);
1111                  if (!dump->data)                  if (!dump->data)
# Line 1184  bool ccs_dump_page(struct linux_binprm * Line 1115  bool ccs_dump_page(struct linux_binprm *
1115  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1116          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)
1117                  return false;                  return false;
1118  #elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR == 3 && defined(CONFIG_MMU)  #elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR >= 3 && defined(CONFIG_MMU)
1119            if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
1120                    return false;
1121    #elif defined(AX_MAJOR) && AX_MAJOR == 3 && defined(AX_MINOR) && AX_MINOR >= 2 && defined(CONFIG_MMU)
1122          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)
1123                  return false;                  return false;
1124  #else  #else
# Line 1205  bool ccs_dump_page(struct linux_binprm * Line 1139  bool ccs_dump_page(struct linux_binprm *
1139          /* Same with put_arg_page(page) in fs/exec.c */          /* Same with put_arg_page(page) in fs/exec.c */
1140  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1141          put_page(page);          put_page(page);
1142  #elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR == 3 && defined(CONFIG_MMU)  #elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR >= 3 && defined(CONFIG_MMU)
1143            put_page(page);
1144    #elif defined(AX_MAJOR) && AX_MAJOR == 3 && defined(AX_MINOR) && AX_MINOR >= 2 && defined(CONFIG_MMU)
1145          put_page(page);          put_page(page);
1146  #endif  #endif
1147          return true;          return true;
# Line 1215  bool ccs_dump_page(struct linux_binprm * Line 1151  bool ccs_dump_page(struct linux_binprm *
1151   * ccs_start_execve - Prepare for execve() operation.   * ccs_start_execve - Prepare for execve() operation.
1152   *   *
1153   * @bprm: Pointer to "struct linux_binprm".   * @bprm: Pointer to "struct linux_binprm".
1154     * @eep:  Pointer to "struct ccs_execve_entry *".
1155   *   *
1156   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1157   */   */
1158  int ccs_start_execve(struct linux_binprm *bprm)  int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve_entry **eep)
1159  {  {
1160          int retval;          int retval;
1161          struct task_struct *task = current;          struct task_struct *task = current;
1162          struct ccs_execve_entry *ee = ccs_allocate_execve_entry();          struct ccs_execve_entry *ee;
1163            *eep = NULL;
1164          if (!ccs_policy_loaded)          if (!ccs_policy_loaded)
1165                  ccs_load_policy(bprm->filename);                  ccs_load_policy(bprm->filename);
1166            ee = kzalloc(sizeof(*ee), GFP_KERNEL);
1167          if (!ee)          if (!ee)
1168                  return -ENOMEM;                  return -ENOMEM;
1169            ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, GFP_KERNEL);
1170            if (!ee->tmp) {
1171                    kfree(ee);
1172                    return -ENOMEM;
1173            }
1174            ee->reader_idx = ccs_read_lock();
1175            /* ee->dump->data is allocated by ccs_dump_page(). */
1176            ee->previous_domain = task->ccs_domain_info;
1177            /* Clear manager flag. */
1178            task->ccs_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
1179            /* Tell GC that I started execve(). */
1180            task->ccs_flags |= CCS_TASK_IS_IN_EXECVE;
1181            /*
1182             * Make task->ccs_flags visible to GC before changing
1183             * task->ccs_domain_info .
1184             */
1185            smp_mb();
1186            *eep = ee;
1187          ccs_init_request_info(&ee->r, NULL, CCS_MAC_FILE_EXECUTE);          ccs_init_request_info(&ee->r, NULL, CCS_MAC_FILE_EXECUTE);
1188          ee->r.ee = ee;          ee->r.ee = ee;
1189          ee->bprm = bprm;          ee->bprm = bprm;
1190          ee->r.obj = &ee->obj;          ee->r.obj = &ee->obj;
1191          ee->obj.path1.dentry = bprm->file->f_dentry;          ee->obj.path1.dentry = bprm->file->f_dentry;
1192          ee->obj.path1.mnt = bprm->file->f_vfsmnt;          ee->obj.path1.mnt = bprm->file->f_vfsmnt;
         /* Clear manager flag. */  
         task->ccs_flags &= ~CCS_TASK_IS_POLICY_MANAGER;  
1193          if (ccs_find_execute_handler(ee, CCS_TYPE_EXECUTE_HANDLER)) {          if (ccs_find_execute_handler(ee, CCS_TYPE_EXECUTE_HANDLER)) {
1194                  retval = ccs_try_alt_exec(ee);                  retval = ccs_try_alt_exec(ee);
1195                  if (!retval)                  if (!retval)
# Line 1263  int ccs_start_execve(struct linux_binprm Line 1218  int ccs_start_execve(struct linux_binprm
1218          retval = ccs_environ(ee);          retval = ccs_environ(ee);
1219          if (retval < 0)          if (retval < 0)
1220                  goto out;                  goto out;
         task->ccs_flags |= CCS_CHECK_READ_FOR_OPEN_EXEC;  
1221          retval = 0;          retval = 0;
1222   out:   out:
         if (retval)  
                 ccs_finish_execve(retval);  
1223          return retval;          return retval;
1224  }  }
1225    
# Line 1275  int ccs_start_execve(struct linux_binprm Line 1227  int ccs_start_execve(struct linux_binprm
1227   * ccs_finish_execve - Clean up execve() operation.   * ccs_finish_execve - Clean up execve() operation.
1228   *   *
1229   * @retval: Return code of an execve() operation.   * @retval: Return code of an execve() operation.
1230     * @ee:     Pointer to "struct ccs_execve_entry".
1231   *   *
1232   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1233   */   */
1234  void ccs_finish_execve(int retval)  void ccs_finish_execve(int retval, struct ccs_execve_entry *ee)
1235  {  {
1236          struct task_struct *task = current;          struct task_struct *task = current;
         struct ccs_execve_entry *ee = ccs_find_execve_entry(task);  
         task->ccs_flags &= ~CCS_CHECK_READ_FOR_OPEN_EXEC;  
1237          if (!ee)          if (!ee)
1238                  return;                  return;
1239          if (retval < 0) {          if (retval < 0) {
1240                  task->ccs_domain_info = ee->previous_domain;                  task->ccs_domain_info = ee->previous_domain;
1241                  goto out;                  /*
1242                     * Make task->ccs_domain_info visible to GC before changing
1243                     * task->ccs_flags .
1244                     */
1245                    smp_mb();
1246            } else {
1247                    /* Mark the current process as execute handler. */
1248                    if (ee->handler)
1249                            task->ccs_flags |= CCS_TASK_IS_EXECUTE_HANDLER;
1250                    /* Mark the current process as normal process. */
1251                    else
1252                            task->ccs_flags &= ~CCS_TASK_IS_EXECUTE_HANDLER;
1253          }          }
1254          /* Mark the current process as execute handler. */          /* Tell GC that I finished execve(). */
1255          if (ee->handler)          task->ccs_flags &= ~CCS_TASK_IS_IN_EXECVE;
1256                  task->ccs_flags |= CCS_TASK_IS_EXECUTE_HANDLER;          ccs_read_unlock(ee->reader_idx);
1257          /* Mark the current process as normal process. */          kfree(ee->handler_path);
1258          else          kfree(ee->tmp);
1259                  task->ccs_flags &= ~CCS_TASK_IS_EXECUTE_HANDLER;          kfree(ee->dump.data);
1260   out:          kfree(ee);
         ccs_free_execve_entry(ee);  
1261  }  }

Legend:
Removed from v.2968  
changed lines
  Added in v.3109

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