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

Subversion リポジトリの参照

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

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

revision 3731 by kumaneko, Fri Jun 4 01:42:54 2010 UTC revision 3746 by kumaneko, Wed Jun 9 11:20:32 2010 UTC
# Line 866  static bool ccs_select_one(struct ccs_io Line 866  static bool ccs_select_one(struct ccs_io
866  }  }
867    
868  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,
869                               struct ccs_condition *cond, const bool is_delete)                               const bool is_delete)
870  {  {
         u8 i;  
871          static const struct {          static const struct {
872                  const char *keyword;                  const char *keyword;
873                  int (*write) (char *, struct ccs_domain_info *,                  int (*write) (char *, struct ccs_domain_info *,
# Line 882  static int ccs_write_domain2(char *data, Line 881  static int ccs_write_domain2(char *data,
881          };          };
882          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,
883                        const bool) = ccs_write_file;                        const bool) = ccs_write_file;
884            int error;
885            u8 i;
886            struct ccs_condition *cond = NULL;
887            char *cp = ccs_find_condition_part(data);
888            if (cp) {
889                    cond = ccs_get_condition(cp);
890                    if (!cond)
891                            return -EINVAL;
892            }
893          for (i = 0; i < 5; i++) {          for (i = 0; i < 5; i++) {
894                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))
895                          continue;                          continue;
896                  write = ccs_callback[i].write;                  write = ccs_callback[i].write;
897                  break;                  break;
898          }          }
899          return write(data, domain, cond, is_delete);          error = write(data, domain, cond, is_delete);
900            if (cond)
901                    ccs_put_condition(cond);
902            return error;
903  }  }
904    
905  /**  /**
# Line 905  static int ccs_write_domain(struct ccs_i Line 916  static int ccs_write_domain(struct ccs_i
916          bool is_delete = false;          bool is_delete = false;
917          bool is_select = false;          bool is_select = false;
918          unsigned int profile;          unsigned int profile;
         struct ccs_condition *cond = NULL;  
         char *cp;  
         int error;  
919          if (ccs_str_starts(&data, CCS_KEYWORD_DELETE))          if (ccs_str_starts(&data, CCS_KEYWORD_DELETE))
920                  is_delete = true;                  is_delete = true;
921          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))
# Line 957  static int ccs_write_domain(struct ccs_i Line 965  static int ccs_write_domain(struct ccs_i
965                  domain->domain_transition_failed = !is_delete;                  domain->domain_transition_failed = !is_delete;
966                  return 0;                  return 0;
967          }          }
968          cp = ccs_find_condition_part(data);          return ccs_write_domain2(data, domain, is_delete);
         if (cp) {  
                 cond = ccs_get_condition(cp);  
                 if (!cond)  
                         return -EINVAL;  
         }  
         error = ccs_write_domain2(data, domain, cond, is_delete);  
         if (cond)  
                 ccs_put_condition(cond);  
         return error;  
969  }  }
970    
971  /**  /**
# Line 1851  static int ccs_write_exception(struct cc Line 1850  static int ccs_write_exception(struct cc
1850                  if (ccs_str_starts(&data, ccs_name[i]))                  if (ccs_str_starts(&data, ccs_name[i]))
1851                          return ccs_write_group(data, is_delete, i);                          return ccs_write_group(data, is_delete, i);
1852          }          }
1853          {          return ccs_write_domain2(data, &ccs_global_domain, is_delete);
                 int error;  
                 struct ccs_condition *cond = NULL;  
                 char *cp = ccs_find_condition_part(data);  
                 if (cp) {  
                         cond = ccs_get_condition(cp);  
                         if (!cond)  
                                 return -EINVAL;  
                 }  
                 error = ccs_write_domain2(data, &ccs_global_domain, cond,  
                                           is_delete);  
                 if (cond)  
                         ccs_put_condition(cond);  
                 return error;  
         }  
1854  }  }
1855    
1856  /**  /**
# Line 2112  static bool ccs_get_argv0(struct ccs_exe Line 2097  static bool ccs_get_argv0(struct ccs_exe
2097          return false;          return false;
2098  }  }
2099    
 /**  
  * ccs_get_execute_condition - Get condition part for execute requests.  
  *  
  * @ee: Pointer to "struct ccs_execve".  
  *  
  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.  
  */  
 static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve *ee)  
 {  
         struct ccs_condition *cond;  
         char *buf;  
         int len = 256;  
         char *realpath = NULL;  
         char *argv0 = NULL;  
         const struct ccs_profile *profile = ccs_profile(ccs_current_domain()->  
                                                         profile);  
         if (profile->learning->learning_exec_realpath) {  
                 struct file *file = ee->bprm->file;  
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)  
                 struct path path = { file->f_vfsmnt, file->f_dentry };  
                 realpath = ccs_realpath_from_path(&path);  
 #else  
                 realpath = ccs_realpath_from_path(&file->f_path);  
 #endif  
                 if (realpath)  
                         len += strlen(realpath) + 17;  
         }  
         if (profile->learning->learning_exec_argv0) {  
                 if (ccs_get_argv0(ee)) {  
                         argv0 = ee->tmp;  
                         len += strlen(argv0) + 16;  
                 }  
         }  
         buf = kmalloc(len, CCS_GFP_FLAGS);  
         if (!buf) {  
                 kfree(realpath);  
                 return NULL;  
         }  
         snprintf(buf, len - 1, "if");  
         if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {  
                 const int pos = strlen(buf);  
                 snprintf(buf + pos, len - pos - 1,  
                          " task.type=execute_handler");  
         }  
         if (realpath) {  
                 const int pos = strlen(buf);  
                 snprintf(buf + pos, len - pos - 1, " exec.realpath=\"%s\"",  
                          realpath);  
                 kfree(realpath);  
         }  
         if (argv0) {  
                 const int pos = strlen(buf);  
                 snprintf(buf + pos, len - pos - 1, " exec.argv[0]=\"%s\"",  
                          argv0);  
         }  
         cond = ccs_get_condition(buf);  
         kfree(buf);  
         return cond;  
 }  
   
 /**  
  * ccs_get_symlink_condition - Get condition part for symlink requests.  
  *  
  * @r: Pointer to "struct ccs_request_info".  
  *  
  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.  
  */  
 static struct ccs_condition *ccs_get_symlink_condition  
 (const struct ccs_request_info *r)  
 {  
         struct ccs_condition *cond;  
         char *buf;  
         int len = 256;  
         const char *symlink = NULL;  
         const struct ccs_profile *profile = ccs_profile(r->profile);  
         if (profile->learning->learning_symlink_target) {  
                 symlink = r->obj->symlink_target->name;  
                 len += strlen(symlink) + 18;  
         }  
         buf = kmalloc(len, CCS_GFP_FLAGS);  
         if (!buf)  
                 return NULL;  
         snprintf(buf, len - 1, "if");  
         if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {  
                 const int pos = strlen(buf);  
                 snprintf(buf + pos, len - pos - 1,  
                          " task.type=execute_handler");  
         }  
         if (symlink) {  
                 const int pos = strlen(buf);  
                 snprintf(buf + pos, len - pos - 1, " symlink.target=\"%s\"",  
                          symlink);  
         }  
         cond = ccs_get_condition(buf);  
         kfree(buf);  
         return cond;  
 }  
   
2100  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
2101  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
2102    
# Line 2232  static LIST_HEAD(ccs_query_list); Line 2119  static LIST_HEAD(ccs_query_list);
2119  /* Number of "struct file" referring /proc/ccs/query interface. */  /* Number of "struct file" referring /proc/ccs/query interface. */
2120  static atomic_t ccs_query_observers = ATOMIC_INIT(0);  static atomic_t ccs_query_observers = ATOMIC_INIT(0);
2121    
2122    static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
2123    {
2124            va_list args;
2125            const int pos = strlen(buffer);
2126            va_start(args, fmt);
2127            vsnprintf(buffer + pos, len - pos - 1, fmt, args);
2128            va_end(args);
2129    }
2130                            
2131  /**  /**
2132   * ccs_supervisor - Ask for the supervisor's decision.   * ccs_supervisor - Ask for the supervisor's decision.
2133   *   *
# Line 2254  int ccs_supervisor(struct ccs_request_in Line 2150  int ccs_supervisor(struct ccs_request_in
2150          bool quota_exceeded = false;          bool quota_exceeded = false;
2151          char *header;          char *header;
2152          struct ccs_domain_info * const domain = ccs_current_domain();          struct ccs_domain_info * const domain = ccs_current_domain();
2153          switch (r->mode) {          va_start(args, fmt);
2154            len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 80;
2155            va_end(args);
2156            if (r->mode == CCS_CONFIG_LEARNING) {
2157                  char *buffer;                  char *buffer;
2158                  struct ccs_condition *cond;                  char *realpath = NULL;
2159          case CCS_CONFIG_LEARNING:                  char *argv0 = NULL;
2160                    const char *symlink = NULL;
2161                    const struct ccs_preference *pref;
2162                  if (!ccs_domain_quota_ok(r))                  if (!ccs_domain_quota_ok(r))
2163                          return 0;                          return 0;
2164                  va_start(args, fmt);                  pref = ccs_profile(r->profile)->learning;
                 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;  
                 va_end(args);  
                 buffer = kmalloc(len, CCS_GFP_FLAGS);  
                 if (!buffer)  
                         return 0;  
                 va_start(args, fmt);  
                 vsnprintf(buffer, len - 1, fmt, args);  
                 va_end(args);  
                 ccs_normalize_line(buffer);  
2165                  if (r->param_type == CCS_TYPE_PATH_ACL &&                  if (r->param_type == CCS_TYPE_PATH_ACL &&
2166                      r->param.path.operation == CCS_TYPE_EXECUTE)                      r->param.path.operation == CCS_TYPE_EXECUTE) {
2167                          cond = ccs_get_execute_condition(r->ee);                          if (pref->learning_exec_realpath) {
2168                  else if (r->param_type == CCS_TYPE_PATH_ACL &&                                  struct file *file = r->ee->bprm->file;
2169                           r->param.path.operation == CCS_TYPE_SYMLINK)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
2170                          cond = ccs_get_symlink_condition(r);                                  struct path path = { file->f_vfsmnt,
2171                  else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {                                                       file->f_dentry };
2172                          char str[] = "if task.type=execute_handler";                                  realpath = ccs_realpath_from_path(&path);
2173                          cond = ccs_get_condition(str);  #else
2174                  } else                                  realpath = ccs_realpath_from_path(&file->
2175                          cond = NULL;                                                                    f_path);
2176                  ccs_write_domain2(buffer, domain, cond, false);  #endif
2177                  ccs_put_condition(cond);                                  if (realpath)
2178                  kfree(buffer);                                          len += strlen(realpath);
2179                  /* fall through */                          }
2180          case CCS_CONFIG_PERMISSIVE:                          if (pref->learning_exec_argv0) {
2181                                    if (ccs_get_argv0(r->ee)) {
2182                                            argv0 = r->ee->tmp;
2183                                            len += strlen(argv0);
2184                                    }
2185                            }
2186                    }
2187                    if (r->param_type == CCS_TYPE_PATH_ACL &&
2188                        r->param.path.operation == CCS_TYPE_SYMLINK &&
2189                        pref->learning_symlink_target) {
2190                            symlink = r->obj->symlink_target->name;
2191                            len += strlen(symlink);
2192                    }
2193                    buffer = kmalloc(len, CCS_GFP_FLAGS);
2194                    if (buffer) {
2195                            const bool handler = (current->ccs_flags &
2196                                                  CCS_TASK_IS_EXECUTE_HANDLER)
2197                                    != 0;
2198                            va_start(args, fmt);
2199                            vsnprintf(buffer, len - 1, fmt, args);
2200                            va_end(args);
2201                            if (handler || realpath || argv0 || symlink) {
2202                                    ccs_addprintf(buffer, len, " if");
2203                                    if (handler)
2204                                            ccs_addprintf(buffer, len, " task.type"
2205                                                          "=execute_handler");
2206                                    if (realpath)
2207                                            ccs_addprintf(buffer, len,
2208                                                          " exec.realpath=\"%s\"",
2209                                                          realpath);
2210                                    if (argv0)
2211                                            ccs_addprintf(buffer, len,
2212                                                          " exec.argv[0]=\"%s\"",
2213                                                          argv0);
2214                                    if (symlink)
2215                                            ccs_addprintf(buffer, len,
2216                                                          " symlink.target=\"%s\"",
2217                                                          symlink);
2218                            }
2219                            ccs_normalize_line(buffer);
2220                            ccs_write_domain2(buffer, domain, false);
2221                            kfree(buffer);
2222                    }
2223                    kfree(realpath);
2224                  return 0;                  return 0;
2225          }          }
2226            if (r->mode != CCS_CONFIG_ENFORCING)
2227                    return 0;
2228          if (!atomic_read(&ccs_query_observers)) {          if (!atomic_read(&ccs_query_observers)) {
2229                  int i;                  int i;
2230                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
# Line 2299  int ccs_supervisor(struct ccs_request_in Line 2236  int ccs_supervisor(struct ccs_request_in
2236                  }                  }
2237                  return -EPERM;                  return -EPERM;
2238          }          }
         va_start(args, fmt);  
         len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;  
         va_end(args);  
2239          header = ccs_init_log(&len, r);          header = ccs_init_log(&len, r);
2240          if (!header)          if (!header)
2241                  goto out;                  goto out;
# Line 2324  int ccs_supervisor(struct ccs_request_in Line 2258  int ccs_supervisor(struct ccs_request_in
2258          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2259          if (quota_exceeded)          if (quota_exceeded)
2260                  goto out;                  goto out;
2261          pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",          snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",
2262                         ccs_query_entry->serial, r->retry, header);                   ccs_query_entry->serial, r->retry, header);
2263          kfree(header);          kfree(header);
2264          header = NULL;          header = NULL;
2265          va_start(args, fmt);          ccs_addprintf(ccs_query_entry->query, len, fmt, args);
         vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);  
2266          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;
         va_end(args);  
2267          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2268          list_add_tail(&ccs_query_entry->list, &ccs_query_list);          list_add_tail(&ccs_query_entry->list, &ccs_query_list);
2269          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);

Legend:
Removed from v.3731  
changed lines
  Added in v.3746

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