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

Subversion リポジトリの参照

Diff of /trunk/1.7.x/ccs-patch/security/ccsecurity/util.c

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

revision 1280 by kumaneko, Tue Jun 10 05:22:12 2008 UTC revision 1695 by kumaneko, Sat Oct 11 08:46:59 2008 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2008  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.2-pre   2008/06/10   * Version: 1.6.5-pre   2008/10/11
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 56  static const int lookup_flags = LOOKUP_F Line 56  static const int lookup_flags = LOOKUP_F
56  #endif  #endif
57    
58  /* Has /sbin/init started? */  /* Has /sbin/init started? */
59  bool sbin_init_started = false;  bool sbin_init_started;
60    
61  /* Log level for SAKURA's printk(). */  /* Log level for SAKURA's printk(). */
62  const char *ccs_log_level = KERN_DEBUG;  const char *ccs_log_level = KERN_DEBUG;
# Line 94  static struct { Line 94  static struct {
94          [CCS_TOMOYO_MAX_REJECT_LOG]          [CCS_TOMOYO_MAX_REJECT_LOG]
95          = { "MAX_REJECT_LOG",      MAX_REJECT_LOG, INT_MAX },          = { "MAX_REJECT_LOG",      MAX_REJECT_LOG, INT_MAX },
96          [CCS_TOMOYO_VERBOSE]             = { "TOMOYO_VERBOSE",      1, 1 },          [CCS_TOMOYO_VERBOSE]             = { "TOMOYO_VERBOSE",      1, 1 },
         [CCS_ALLOW_ENFORCE_GRACE]        = { "ALLOW_ENFORCE_GRACE", 0, 1 },  
97          [CCS_SLEEP_PERIOD]          [CCS_SLEEP_PERIOD]
98          = { "SLEEP_PERIOD",        0, 3000 }, /* in 0.1 second */          = { "SLEEP_PERIOD",        0, 3000 }, /* in 0.1 second */
99  };  };
# Line 146  static struct profile { Line 145  static struct profile {
145  } *profile_ptr[MAX_PROFILES];  } *profile_ptr[MAX_PROFILES];
146    
147  /* Permit policy management by non-root user? */  /* Permit policy management by non-root user? */
148  static bool manage_by_non_root = false;  static bool manage_by_non_root;
149    
150  /* Utility functions. */  /* Utility functions. */
151    
# Line 190  static bool is_byte_range(const char *st Line 189  static bool is_byte_range(const char *st
189   */   */
190  static bool is_decimal(const char c)  static bool is_decimal(const char c)
191  {  {
192          return (c >= '0' && c <= '9');          return c >= '0' && c <= '9';
193  }  }
194    
195  /**  /**
# Line 202  static bool is_decimal(const char c) Line 201  static bool is_decimal(const char c)
201   */   */
202  static bool is_hexadecimal(const char c)  static bool is_hexadecimal(const char c)
203  {  {
204          return ((c >= '0' && c <= '9') ||          return (c >= '0' && c <= '9') ||
205                  (c >= 'A' && c <= 'F') ||                  (c >= 'A' && c <= 'F') ||
206                  (c >= 'a' && c <= 'f'));                  (c >= 'a' && c <= 'f');
207  }  }
208    
209  /**  /**
# Line 216  static bool is_hexadecimal(const char c) Line 215  static bool is_hexadecimal(const char c)
215   */   */
216  static bool is_alphabet_char(const char c)  static bool is_alphabet_char(const char c)
217  {  {
218          return ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));          return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
219  }  }
220    
221  /**  /**
# Line 671  static bool file_matches_to_pattern2(con Line 670  static bool file_matches_to_pattern2(con
670          while (*pattern == '\\' &&          while (*pattern == '\\' &&
671                 (*(pattern + 1) == '*' || *(pattern + 1) == '@'))                 (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
672                  pattern += 2;                  pattern += 2;
673          return (filename == filename_end && pattern == pattern_end);          return filename == filename_end && pattern == pattern_end;
674  }  }
675    
676  /**  /**
# Line 773  bool ccs_path_matches_pattern(const stru Line 772  bool ccs_path_matches_pattern(const stru
772          while (*p == '\\' &&          while (*p == '\\' &&
773                 (*(p + 1) == '*' || *(p + 1) == '@'))                 (*(p + 1) == '*' || *(p + 1) == '@'))
774                  p += 2;                  p += 2;
775          return (!*f && !*p);          return !*f && !*p;
776  }  }
777    
778  /**  /**
# Line 846  const char *ccs_get_msg(const bool is_en Line 845  const char *ccs_get_msg(const bool is_en
845  }  }
846    
847  /**  /**
848   * ccs_check_flags_no_sleep_check - Check mode for specified functionality.   * ccs_can_sleep - Check whether it is permitted to do operations that may sleep.
  *  
  * @index: The functionality to check mode.  
  *  
  * Returns the mode of specified functionality.  
  */  
 unsigned int ccs_check_flags_no_sleep_check(const u8 index)  
 {  
         const u8 profile = current->domain_info->profile;  
         return sbin_init_started && index < CCS_MAX_CONTROL_INDEX  
 #if MAX_PROFILES != 256  
                 && profile < MAX_PROFILES  
 #endif  
                 && profile_ptr[profile] ?  
                 profile_ptr[profile]->value[index] : 0;  
 }  
   
 /**  
  * sleep_check - Check whether it is permitted to do operations that may sleep.  
849   *   *
850   * Returns true if it is permitted to do operations that may sleep,   * Returns true if it is permitted to do operations that may sleep,
851   * false otherwise.   * false otherwise.
# Line 875  unsigned int ccs_check_flags_no_sleep_ch Line 856  unsigned int ccs_check_flags_no_sleep_ch
856   * it is permitted to do operations that may sleep.   * it is permitted to do operations that may sleep.
857   * Thus, this warning should not happen.   * Thus, this warning should not happen.
858   */   */
859  static bool sleep_check(void)  bool ccs_can_sleep(void)
860  {  {
861          static u8 count = 20;          static u8 count = 20;
862          if (likely(!in_interrupt()))          if (likely(!in_interrupt()))
# Line 892  static bool sleep_check(void) Line 873  static bool sleep_check(void)
873  /**  /**
874   * ccs_check_flags - Check mode for specified functionality.   * ccs_check_flags - Check mode for specified functionality.
875   *   *
876   * @index: The functionality to check mode.   * @domain: Pointer to "struct domain_info". NULL for current->domain_info.
877     * @index:  The functionality to check mode.
878   *   *
879   * Returns the mode of specified functionality.   * Returns the mode of specified functionality.
880   */   */
881  unsigned int ccs_check_flags(const u8 index)  unsigned int ccs_check_flags(const struct domain_info *domain, const u8 index)
882  {  {
883          return sleep_check() ? ccs_check_flags_no_sleep_check(index) : 0;          u8 profile;
884            if (!domain)
885                    domain = current->domain_info;
886            profile = domain->profile;
887            return sbin_init_started && index < CCS_MAX_CONTROL_INDEX
888    #if MAX_PROFILES != 256
889                    && profile < MAX_PROFILES
890    #endif
891                    && profile_ptr[profile] ?
892                    profile_ptr[profile]->value[index] : 0;
893  }  }
894    
895  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
896  /**  /**
897   * ccs_check_capability_flags - Check mode for specified capability.   * ccs_check_capability_flags - Check mode for specified capability.
898   *   *
899   * @index: The capability to check mode.   * @domain: Pointer to "struct domain_info". NULL for current->domain_info.
900     * @index:  The capability to check mode.
901   *   *
902   * Returns the mode of specified capability.   * Returns the mode of specified capability.
903   */   */
904  u8 ccs_check_capability_flags(const u8 index)  static u8 ccs_check_capability_flags(const struct domain_info *domain,
905                                         const u8 index)
906  {  {
907          const u8 profile = current->domain_info->profile;          const u8 profile = domain ? domain->profile :
908                    current->domain_info->profile;
909          return sbin_init_started && index < TOMOYO_MAX_CAPABILITY_INDEX          return sbin_init_started && index < TOMOYO_MAX_CAPABILITY_INDEX
910  #if MAX_PROFILES != 256  #if MAX_PROFILES != 256
911                  && profile < MAX_PROFILES                  && profile < MAX_PROFILES
912  #endif  #endif
                 && sleep_check()  
913                  && profile_ptr[profile] ?                  && profile_ptr[profile] ?
914                  profile_ptr[profile]->capability_value[index] : 0;                  profile_ptr[profile]->capability_value[index] : 0;
915  }  }
# Line 937  const char *ccs_cap2keyword(const u8 ope Line 930  const char *ccs_cap2keyword(const u8 ope
930  #endif  #endif
931    
932  /**  /**
933     * ccs_init_request_info - Initialize "struct ccs_request_info" members.
934     *
935     * @r:      Pointer to "struct ccs_request_info" to initialize.
936     * @domain: Pointer to "struct domain_info". NULL for current->domain_info.
937     * @index:  Index number of functionality.
938     */
939    void ccs_init_request_info(struct ccs_request_info *r,
940                               struct domain_info *domain, const u8 index)
941    {
942            memset(r, 0, sizeof(*r));
943            if (!domain)
944                    domain = current->domain_info;
945            r->domain = domain;
946            r->profile = domain->profile;
947            if (index < CCS_MAX_CONTROL_INDEX)
948                    r->mode = ccs_check_flags(domain, index);
949    #ifdef CONFIG_TOMOYO
950            else
951                    r->mode = ccs_check_capability_flags(domain, index
952                                                         - CCS_MAX_CONTROL_INDEX);
953    #endif
954            r->tomoyo_flags = current->tomoyo_flags;
955    }
956    
957    /**
958   * ccs_verbose_mode - Check whether TOMOYO is verbose mode.   * ccs_verbose_mode - Check whether TOMOYO is verbose mode.
959   *   *
960     * @domain: Pointer to "struct domain_info". NULL for current->domain_info.
961     *
962   * Returns true if domain policy violation warning should be printed to   * Returns true if domain policy violation warning should be printed to
963   * console.   * console.
964   */   */
965  bool ccs_verbose_mode(void)  bool ccs_verbose_mode(const struct domain_info *domain)
966  {  {
967          return ccs_check_flags(CCS_TOMOYO_VERBOSE) != 0;          return ccs_check_flags(domain, CCS_TOMOYO_VERBOSE) != 0;
968  }  }
969    
970  /**  /**
# Line 1015  bool ccs_check_domain_quota(struct domai Line 1035  bool ccs_check_domain_quota(struct domai
1035                          count++;                          count++;
1036                  }                  }
1037          }          }
1038          if (count < ccs_check_flags(CCS_TOMOYO_MAX_ACCEPT_ENTRY))          if (count < ccs_check_flags(domain, CCS_TOMOYO_MAX_ACCEPT_ENTRY))
1039                  return true;                  return true;
1040          if (!domain->quota_warned) {          if (!domain->quota_warned) {
1041                  domain->quota_warned = true;                  domain->quota_warned = true;
# Line 1065  static struct profile *ccs_find_or_assig Line 1085  static struct profile *ccs_find_or_assig
1085  /**  /**
1086   * write_profile - Write profile table.   * write_profile - Write profile table.
1087   *   *
1088   * @head: Pointer to "struct ccs_io_buffer"   * @head: Pointer to "struct ccs_io_buffer".
1089   *   *
1090   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1091   */   */
# Line 1126  static int write_profile(struct ccs_io_b Line 1146  static int write_profile(struct ccs_io_b
1146                          switch (i) {                          switch (i) {
1147                          case CCS_SAKURA_RESTRICT_AUTOBIND:                          case CCS_SAKURA_RESTRICT_AUTOBIND:
1148                          case CCS_TOMOYO_VERBOSE:                          case CCS_TOMOYO_VERBOSE:
                         case CCS_ALLOW_ENFORCE_GRACE:  
1149                                  modes = mode_2;                                  modes = mode_2;
1150                                  break;                                  break;
1151                          default:                          default:
# Line 1159  static int write_profile(struct ccs_io_b Line 1178  static int write_profile(struct ccs_io_b
1178  /**  /**
1179   * read_profile - Read profile table.   * read_profile - Read profile table.
1180   *   *
1181   * @head: Pointer to "struct ccs_io_buffer"   * @head: Pointer to "struct ccs_io_buffer".
1182   *   *
1183   * Returns 0.   * Returns 0.
1184   */   */
# Line 1316  static int update_manager_entry(const ch Line 1335  static int update_manager_entry(const ch
1335  /**  /**
1336   * write_manager_policy - Write manager policy.   * write_manager_policy - Write manager policy.
1337   *   *
1338   * @head: Pointer to "struct ccs_io_buffer"   * @head: Pointer to "struct ccs_io_buffer".
1339   *   *
1340   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1341   */   */
# Line 1334  static int write_manager_policy(struct c Line 1353  static int write_manager_policy(struct c
1353  /**  /**
1354   * read_manager_policy - Read manager policy.   * read_manager_policy - Read manager policy.
1355   *   *
1356   * @head: Pointer to "struct ccs_io_buffer"   * @head: Pointer to "struct ccs_io_buffer".
1357   *   *
1358   * Returns 0.   * Returns 0.
1359   */   */
# Line 1365  static bool is_policy_manager(void) Line 1384  static bool is_policy_manager(void)
1384  {  {
1385          struct policy_manager_entry *ptr;          struct policy_manager_entry *ptr;
1386          const char *exe;          const char *exe;
1387          const struct task_struct *task = current;          struct task_struct *task = current;
1388          const struct path_info *domainname = task->domain_info->domainname;          const struct path_info *domainname = task->domain_info->domainname;
1389          bool found = false;          bool found = false;
1390          if (!sbin_init_started)          if (!sbin_init_started)
1391                  return true;                  return true;
1392            if (task->tomoyo_flags & CCS_TASK_IS_POLICY_MANAGER)
1393                    return true;
1394          if (!manage_by_non_root && (task->uid || task->euid))          if (!manage_by_non_root && (task->uid || task->euid))
1395                  return false;                  return false;
1396          list1_for_each_entry(ptr, &policy_manager_list, list) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
1397                  if (!ptr->is_deleted && ptr->is_domain                  if (!ptr->is_deleted && ptr->is_domain
1398                      && !ccs_pathcmp(domainname, ptr->manager))                      && !ccs_pathcmp(domainname, ptr->manager)) {
1399                            /* Set manager flag. */
1400                            task->tomoyo_flags |= CCS_TASK_IS_POLICY_MANAGER;
1401                          return true;                          return true;
1402                    }
1403          }          }
1404          exe = ccs_get_exe();          exe = ccs_get_exe();
1405          if (!exe)          if (!exe)
# Line 1384  static bool is_policy_manager(void) Line 1408  static bool is_policy_manager(void)
1408                  if (!ptr->is_deleted && !ptr->is_domain                  if (!ptr->is_deleted && !ptr->is_domain
1409                      && !strcmp(exe, ptr->manager->name)) {                      && !strcmp(exe, ptr->manager->name)) {
1410                          found = true;                          found = true;
1411                            /* Set manager flag. */
1412                            task->tomoyo_flags |= CCS_TASK_IS_POLICY_MANAGER;
1413                          break;                          break;
1414                  }                  }
1415          }          }
# Line 1427  static char *ccs_find_condition_part(cha Line 1453  static char *ccs_find_condition_part(cha
1453  }  }
1454    
1455  /**  /**
1456     * is_select_one - Parse select command.
1457     *
1458     * @head: Pointer to "struct ccs_io_buffer".
1459     * @data: String to parse.
1460     *
1461     * Returns true on success, false otherwise.
1462     */
1463    static bool is_select_one(struct ccs_io_buffer *head, const char *data)
1464    {
1465            unsigned int pid;
1466            struct domain_info *domain = NULL;
1467            if (sscanf(data, "pid=%u", &pid) == 1) {
1468                    struct task_struct *p;
1469                    /***** CRITICAL SECTION START *****/
1470                    read_lock(&tasklist_lock);
1471                    p = find_task_by_pid(pid);
1472                    if (p)
1473                            domain = p->domain_info;
1474                    read_unlock(&tasklist_lock);
1475                    /***** CRITICAL SECTION END *****/
1476            } else if (!strncmp(data, "domain=", 7)) {
1477                    if (ccs_is_domain_def(data + 7))
1478                            domain = ccs_find_domain(data + 7);
1479            } else
1480                    return false;
1481            head->read_avail = 0;
1482            ccs_io_printf(head, "# select %s\n", data);
1483            head->read_single_domain = true;
1484            head->read_eof = !domain;
1485            if (domain) {
1486                    struct domain_info *d;
1487                    head->read_var1 = NULL;
1488                    list1_for_each_entry(d, &domain_list, list) {
1489                            if (d == domain)
1490                                    break;
1491                            head->read_var1 = &d->list;
1492                    }
1493                    head->read_var2 = NULL;
1494                    head->read_bit = 0;
1495                    head->read_step = 0;
1496                    if (domain->is_deleted)
1497                            ccs_io_printf(head, "# This is a deleted domain.\n");
1498            }
1499            head->write_var1 = domain;
1500            return true;
1501    }
1502    
1503    /**
1504   * write_domain_policy - Write domain policy.   * write_domain_policy - Write domain policy.
1505   *   *
1506   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 1449  static int write_domain_policy(struct cc Line 1523  static int write_domain_policy(struct cc
1523                  is_select = true;                  is_select = true;
1524          else if (str_starts(&data, KEYWORD_UNDELETE))          else if (str_starts(&data, KEYWORD_UNDELETE))
1525                  is_undelete = true;                  is_undelete = true;
1526            if (is_select && is_select_one(head, data))
1527                    return 0;
1528            /* Don't allow updating policies by non manager programs. */
1529            if (!is_policy_manager())
1530                    return -EPERM;
1531          if (ccs_is_domain_def(data)) {          if (ccs_is_domain_def(data)) {
1532                  domain = NULL;                  domain = NULL;
1533                  if (is_delete)                  if (is_delete)
# Line 1918  static int read_domain_policy(struct ccs Line 1997  static int read_domain_policy(struct ccs
1997                  domain = list1_entry(dpos, struct domain_info, list);                  domain = list1_entry(dpos, struct domain_info, list);
1998                  if (head->read_step != 1)                  if (head->read_step != 1)
1999                          goto acl_loop;                          goto acl_loop;
2000                  if (domain->is_deleted)                  if (domain->is_deleted && !head->read_single_domain)
2001                          continue;                          continue;
2002                  /* Print domainname and flags. */                  /* Print domainname and flags. */
2003                  if (domain->quota_warned)                  if (domain->quota_warned)
# Line 1955  static int read_domain_policy(struct ccs Line 2034  static int read_domain_policy(struct ccs
2034                  if (!ccs_io_printf(head, "\n"))                  if (!ccs_io_printf(head, "\n"))
2035                          return 0;                          return 0;
2036                  head->read_step = 1;                  head->read_step = 1;
2037                    if (head->read_single_domain)
2038                            break;
2039          }          }
2040          head->read_eof = true;          head->read_eof = true;
2041          return 0;          return 0;
# Line 2051  static int write_pid(struct ccs_io_buffe Line 2132  static int write_pid(struct ccs_io_buffe
2132  static int read_pid(struct ccs_io_buffer *head)  static int read_pid(struct ccs_io_buffer *head)
2133  {  {
2134          if (head->read_avail == 0 && !head->read_eof) {          if (head->read_avail == 0 && !head->read_eof) {
2135                    const char *is_manager = "";
2136                    const char *is_execute_handler = "";
2137                  const int pid = head->read_step;                  const int pid = head->read_step;
2138                  struct task_struct *p;                  struct task_struct *p;
2139                  struct domain_info *domain = NULL;                  struct domain_info *domain = NULL;
2140                    u32 tomoyo_flags = 0;
2141                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
2142                  read_lock(&tasklist_lock);                  read_lock(&tasklist_lock);
2143                  p = find_task_by_pid(pid);                  p = find_task_by_pid(pid);
2144                  if (p)                  if (p) {
2145                          domain = p->domain_info;                          domain = p->domain_info;
2146                            tomoyo_flags = p->tomoyo_flags;
2147                    }
2148                  read_unlock(&tasklist_lock);                  read_unlock(&tasklist_lock);
2149                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
2150                    if (tomoyo_flags & TOMOYO_TASK_IS_EXECUTE_HANDLER)
2151                            is_execute_handler = "(execute_handler)";
2152                    if (tomoyo_flags & CCS_TASK_IS_POLICY_MANAGER)
2153                            is_manager = "(manager)";
2154                  if (domain)                  if (domain)
2155                          ccs_io_printf(head, "%d %u %s", pid, domain->profile,                          ccs_io_printf(head, "%d%s%s %u %s", pid, is_manager,
2156                                          is_execute_handler, domain->profile,
2157                                        domain->domainname->name);                                        domain->domainname->name);
2158                  head->read_eof = true;                  head->read_eof = true;
2159          }          }
# Line 2373  void ccs_load_policy(const char *filenam Line 2464  void ccs_load_policy(const char *filenam
2464                  envp[2] = NULL;                  envp[2] = NULL;
2465                  call_usermodehelper(argv[0], argv, envp, 1);                  call_usermodehelper(argv[0], argv, envp, 1);
2466          }          }
2467    #elif defined(TASK_DEAD)
2468            {
2469                    /* Copied from kernel/kmod.c */
2470                    struct task_struct *task = current;
2471                    pid_t pid = kernel_thread(run_ccs_loader, NULL, 0);
2472                    sigset_t tmpsig;
2473                    spin_lock_irq(&task->sighand->siglock);
2474                    tmpsig = task->blocked;
2475                    siginitsetinv(&task->blocked,
2476                                  sigmask(SIGKILL) | sigmask(SIGSTOP));
2477                    recalc_sigpending();
2478                    spin_unlock_irq(&current->sighand->siglock);
2479                    if (pid >= 0)
2480                            waitpid(pid, NULL, __WCLONE);
2481                    spin_lock_irq(&task->sighand->siglock);
2482                    task->blocked = tmpsig;
2483                    recalc_sigpending();
2484                    spin_unlock_irq(&task->sighand->siglock);
2485            }
2486  #else  #else
2487          {          {
2488                  /* Copied from kernel/kmod.c */                  /* Copied from kernel/kmod.c */
# Line 2394  void ccs_load_policy(const char *filenam Line 2504  void ccs_load_policy(const char *filenam
2504          }          }
2505  #endif  #endif
2506  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
2507          printk(KERN_INFO "SAKURA: 1.6.2-pre   2008/06/10\n");          printk(KERN_INFO "SAKURA: 1.6.5-pre   2008/10/07\n");
2508  #endif  #endif
2509  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
2510          printk(KERN_INFO "TOMOYO: 1.6.2-pre   2008/06/10\n");          printk(KERN_INFO "TOMOYO: 1.6.5-pre   2008/10/11\n");
2511  #endif  #endif
2512          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
2513          sbin_init_started = true;          sbin_init_started = true;
# Line 2439  static atomic_t queryd_watcher = ATOMIC_ Line 2549  static atomic_t queryd_watcher = ATOMIC_
2549  /**  /**
2550   * ccs_check_supervisor - Ask for the supervisor's decision.   * ccs_check_supervisor - Ask for the supervisor's decision.
2551   *   *
2552   * @bprm: Pointer to "struct linux_binprm". May be NULL.   * @r:       Pointer to "struct ccs_request_info".
2553   * @fmt:  The printf()'s format string, followed by parameters.   * @fmt:     The printf()'s format string, followed by parameters.
2554   *   *
2555   * Returns 0 if the supervisor decided to permit the access request which   * Returns 0 if the supervisor decided to permit the access request which
2556   * violated the policy in enforcing mode, -EPERM otherwise.   * violated the policy in enforcing mode, 1 if the supervisor decided to
2557     * retry the access request which violated the policy in enforcing mode,
2558     * -EPERM otherwise.
2559   */   */
2560  int ccs_check_supervisor(struct linux_binprm *bprm, const char *fmt, ...)  int ccs_check_supervisor(struct ccs_request_info *r, const char *fmt, ...)
2561  {  {
2562          va_list args;          va_list args;
2563          int error = -EPERM;          int error = -EPERM;
# Line 2454  int ccs_check_supervisor(struct linux_bi Line 2566  int ccs_check_supervisor(struct linux_bi
2566          static unsigned int serial;          static unsigned int serial;
2567          struct query_entry *query_entry = NULL;          struct query_entry *query_entry = NULL;
2568          char *header;          char *header;
2569            if (!r->domain)
2570                    r->domain = current->domain_info;
2571          if (!atomic_read(&queryd_watcher)) {          if (!atomic_read(&queryd_watcher)) {
2572                  int i;                  int i;
2573                  if (current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2574                          return -EPERM;                          return -EPERM;
2575                  for (i = 0; i < ccs_check_flags(CCS_SLEEP_PERIOD); i++) {                  for (i = 0; i < ccs_check_flags(r->domain, CCS_SLEEP_PERIOD);
2576                         i++) {
2577                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
2578                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
2579                  }                  }
# Line 2468  int ccs_check_supervisor(struct linux_bi Line 2583  int ccs_check_supervisor(struct linux_bi
2583          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2584          va_end(args);          va_end(args);
2585  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
2586          header = ccs_init_audit_log(&len, current->domain_info->profile,          header = ccs_init_audit_log(&len, r);
                                     3, bprm);  
2587  #else  #else
2588          header = ccs_alloc(1);          header = ccs_alloc(1);
2589  #endif  #endif
# Line 2487  int ccs_check_supervisor(struct linux_bi Line 2601  int ccs_check_supervisor(struct linux_bi
2601          query_entry->serial = serial++;          query_entry->serial = serial++;
2602          spin_unlock(&query_lock);          spin_unlock(&query_lock);
2603          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2604          pos = snprintf(query_entry->query, len - 1, "Q%u\n%s",          pos = snprintf(query_entry->query, len - 1, "Q%u-%hu\n%s",
2605                         query_entry->serial, header);                         query_entry->serial, r->retry, header);
2606          ccs_free(header);          ccs_free(header);
2607          header = NULL;          header = NULL;
2608          va_start(args, fmt);          va_start(args, fmt);
# Line 2517  int ccs_check_supervisor(struct linux_bi Line 2631  int ccs_check_supervisor(struct linux_bi
2631          spin_unlock(&query_lock);          spin_unlock(&query_lock);
2632          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2633          switch (query_entry->answer) {          switch (query_entry->answer) {
2634            case 3: /* Asked to retry by administrator. */
2635                    error = 1;
2636                    break;
2637          case 1:          case 1:
2638                  /* Granted by administrator. */                  /* Granted by administrator. */
2639                  error = 0;                  error = 0;
# Line 2548  int ccs_check_supervisor(struct linux_bi Line 2665  int ccs_check_supervisor(struct linux_bi
2665   */   */
2666  static int poll_query(struct file *file, poll_table *wait)  static int poll_query(struct file *file, poll_table *wait)
2667  {  {
2668          bool found;          struct list_head *tmp;
2669          /***** CRITICAL SECTION START *****/          bool found = false;
2670          spin_lock(&query_lock);          u8 i;
2671          found = !list_empty(&query_list);          for (i = 0; i < 2; i++) {
2672          spin_unlock(&query_lock);                  /***** CRITICAL SECTION START *****/
2673          /***** CRITICAL SECTION END *****/                  spin_lock(&query_lock);
2674          if (found)                  list_for_each(tmp, &query_list) {
2675                  return POLLIN | POLLRDNORM;                          struct query_entry *ptr
2676          poll_wait(file, &query_wait, wait);                                  = list_entry(tmp, struct query_entry, list);
2677          /***** CRITICAL SECTION START *****/                          if (ptr->answer)
2678          spin_lock(&query_lock);                                  continue;
2679          found = !list_empty(&query_list);                          found = true;
2680          spin_unlock(&query_lock);                          break;
2681          /***** CRITICAL SECTION END *****/                  }
2682          if (found)                  spin_unlock(&query_lock);
2683                  return POLLIN | POLLRDNORM;                  /***** CRITICAL SECTION END *****/
2684                    if (found)
2685                            return POLLIN | POLLRDNORM;
2686                    if (i)
2687                            break;
2688                    poll_wait(file, &query_wait, wait);
2689            }
2690          return 0;          return 0;
2691  }  }
2692    
# Line 2592  static int read_query(struct ccs_io_buff Line 2715  static int read_query(struct ccs_io_buff
2715          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
2716                  struct query_entry *ptr                  struct query_entry *ptr
2717                          = list_entry(tmp, struct query_entry, list);                          = list_entry(tmp, struct query_entry, list);
2718                    if (ptr->answer)
2719                            continue;
2720                  if (pos++ != head->read_step)                  if (pos++ != head->read_step)
2721                          continue;                          continue;
2722                  len = ptr->query_len;                  len = ptr->query_len;
# Line 2604  static int read_query(struct ccs_io_buff Line 2729  static int read_query(struct ccs_io_buff
2729                  return 0;                  return 0;
2730          }          }
2731          buf = ccs_alloc(len);          buf = ccs_alloc(len);
2732          if (buf) {          if (!buf)
2733                  pos = 0;                  return 0;
2734                  /***** CRITICAL SECTION START *****/          pos = 0;
2735                  spin_lock(&query_lock);          /***** CRITICAL SECTION START *****/
2736                  list_for_each(tmp, &query_list) {          spin_lock(&query_lock);
2737                          struct query_entry *ptr          list_for_each(tmp, &query_list) {
2738                                  = list_entry(tmp, struct query_entry, list);                  struct query_entry *ptr
2739                          if (pos++ != head->read_step)                          = list_entry(tmp, struct query_entry, list);
2740                                  continue;                  if (ptr->answer)
2741                          /*                          continue;
2742                           * Some query can be skipped because query_list                  if (pos++ != head->read_step)
2743                           * can change, but I don't care.                          continue;
2744                           */                  /*
2745                          if (len == ptr->query_len)                   * Some query can be skipped because query_list
2746                                  memmove(buf, ptr->query, len);                   * can change, but I don't care.
2747                          break;                   */
2748                  }                  if (len == ptr->query_len)
2749                  spin_unlock(&query_lock);                          memmove(buf, ptr->query, len);
2750                  /***** CRITICAL SECTION END *****/                  break;
2751                  if (buf[0]) {          }
2752                          head->read_avail = len;          spin_unlock(&query_lock);
2753                          head->readbuf_size = head->read_avail;          /***** CRITICAL SECTION END *****/
2754                          head->read_buf = buf;          if (buf[0]) {
2755                          head->read_step++;                  head->read_avail = len;
2756                  } else {                  head->readbuf_size = head->read_avail;
2757                          ccs_free(buf);                  head->read_buf = buf;
2758                  }                  head->read_step++;
2759            } else {
2760                    ccs_free(buf);
2761          }          }
2762          return 0;          return 0;
2763  }  }
# Line 2648  static int write_answer(struct ccs_io_bu Line 2775  static int write_answer(struct ccs_io_bu
2775          struct list_head *tmp;          struct list_head *tmp;
2776          unsigned int serial;          unsigned int serial;
2777          unsigned int answer;          unsigned int answer;
         if (!ccs_check_flags(CCS_ALLOW_ENFORCE_GRACE))  
                 return -EPERM;  
2778          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2779          spin_lock(&query_lock);          spin_lock(&query_lock);
2780          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
# Line 2749  static int read_updates_counter(struct c Line 2874  static int read_updates_counter(struct c
2874  static int read_version(struct ccs_io_buffer *head)  static int read_version(struct ccs_io_buffer *head)
2875  {  {
2876          if (!head->read_eof) {          if (!head->read_eof) {
2877                  ccs_io_printf(head, "1.6.1");                  ccs_io_printf(head, "1.6.4");
2878                  head->read_eof = true;                  head->read_eof = true;
2879          }          }
2880          return 0;          return 0;
# Line 2790  int ccs_open_control(const u8 type, stru Line 2915  int ccs_open_control(const u8 type, stru
2915          struct ccs_io_buffer *head = ccs_alloc(sizeof(*head));          struct ccs_io_buffer *head = ccs_alloc(sizeof(*head));
2916          if (!head)          if (!head)
2917                  return -ENOMEM;                  return -ENOMEM;
2918          mutex_init(&head->read_sem);          mutex_init(&head->io_sem);
         mutex_init(&head->write_sem);  
2919          switch (type) {          switch (type) {
2920  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
2921          case CCS_SYSTEMPOLICY: /* /proc/ccs/system_policy */          case CCS_SYSTEMPOLICY: /* /proc/ccs/system_policy */
# Line 2946  int ccs_read_control(struct file *file, Line 3070  int ccs_read_control(struct file *file,
3070                  return -ENOSYS;                  return -ENOSYS;
3071          if (!access_ok(VERIFY_WRITE, buffer, buffer_len))          if (!access_ok(VERIFY_WRITE, buffer, buffer_len))
3072                  return -EFAULT;                  return -EFAULT;
3073          if (mutex_lock_interruptible(&head->read_sem))          if (mutex_lock_interruptible(&head->io_sem))
3074                  return -EINTR;                  return -EINTR;
3075          /* Call the policy handler. */          /* Call the policy handler. */
3076          len = head->read(head);          len = head->read(head);
# Line 2967  int ccs_read_control(struct file *file, Line 3091  int ccs_read_control(struct file *file,
3091          head->read_avail -= len;          head->read_avail -= len;
3092          memmove(cp, cp + len, head->read_avail);          memmove(cp, cp + len, head->read_avail);
3093   out:   out:
3094          mutex_unlock(&head->read_sem);          mutex_unlock(&head->io_sem);
3095          return len;          return len;
3096  }  }
3097    
# Line 2992  int ccs_write_control(struct file *file, Line 3116  int ccs_write_control(struct file *file,
3116          if (!access_ok(VERIFY_READ, buffer, buffer_len))          if (!access_ok(VERIFY_READ, buffer, buffer_len))
3117                  return -EFAULT;                  return -EFAULT;
3118          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
3119          if (head->write != write_pid && !is_policy_manager())          if (head->write != write_pid &&
3120    #ifdef CONFIG_TOMOYO
3121                head->write != write_domain_policy &&
3122    #endif
3123                !is_policy_manager())
3124                  return -EPERM;                  return -EPERM;
3125          if (mutex_lock_interruptible(&head->write_sem))          if (mutex_lock_interruptible(&head->io_sem))
3126                  return -EINTR;                  return -EINTR;
3127          /* Read a line and dispatch it to the policy handler. */          /* Read a line and dispatch it to the policy handler. */
3128          while (avail_len > 0) {          while (avail_len > 0) {
# Line 3016  int ccs_write_control(struct file *file, Line 3144  int ccs_write_control(struct file *file,
3144                  normalize_line(cp0);                  normalize_line(cp0);
3145                  head->write(head);                  head->write(head);
3146          }          }
3147          mutex_unlock(&head->write_sem);          mutex_unlock(&head->io_sem);
3148          return error;          return error;
3149  }  }
3150    

Legend:
Removed from v.1280  
changed lines
  Added in v.1695

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