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

Subversion リポジトリの参照

Diff of /branches/ccs-patch/security/ccsecurity/policy_io.c

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

revision 2894 by kumaneko, Tue Aug 11 08:15:11 2009 UTC revision 2897 by kumaneko, Wed Aug 12 06:16:57 2009 UTC
# Line 553  static bool ccs_is_select_one(struct ccs Line 553  static bool ccs_is_select_one(struct ccs
553          return true;          return true;
554  }  }
555    
556    static int ccs_write_domain_policy2(char *data, struct ccs_domain_info *domain,
557                                        struct ccs_condition *cond,
558                                        const bool is_delete)
559    {
560            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CAPABILITY))
561                    return ccs_write_capability_policy(data, domain, cond,
562                                                       is_delete);
563            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_NETWORK))
564                    return ccs_write_network_policy(data, domain, cond, is_delete);
565            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_SIGNAL))
566                    return ccs_write_signal_policy(data, domain, cond, is_delete);
567            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))
568                    return ccs_write_env_policy(data, domain, cond, is_delete);
569            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))
570                    return ccs_write_mount_policy(data, domain, cond, is_delete);
571            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_UNMOUNT))
572                    return ccs_write_umount_policy(data, domain, cond, is_delete);
573            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CHROOT))
574                    return ccs_write_chroot_policy(data, domain, cond, is_delete);
575            if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_PIVOT_ROOT))
576                    return ccs_write_pivot_root_policy(data, domain, cond,
577                                                       is_delete);
578            return ccs_write_file_policy(data, domain, cond, is_delete);
579    }
580    
581  /**  /**
582   * ccs_write_domain_policy - Write domain policy.   * ccs_write_domain_policy - Write domain policy.
583   *   *
# Line 613  static int ccs_write_domain_policy(struc Line 638  static int ccs_write_domain_policy(struc
638                  if (!cond)                  if (!cond)
639                          return -EINVAL;                          return -EINVAL;
640          }          }
641          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CAPABILITY))          error = ccs_write_domain_policy2(data, domain, cond, is_delete);
                 error = ccs_write_capability_policy(data, domain, cond,  
                                                     is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_NETWORK))  
                 error = ccs_write_network_policy(data, domain, cond, is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_SIGNAL))  
                 error = ccs_write_signal_policy(data, domain, cond, is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))  
                 error = ccs_write_env_policy(data, domain, cond, is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))  
                 error = ccs_write_mount_policy(data, domain, cond, is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_UNMOUNT))  
                 error = ccs_write_umount_policy(data, domain, cond, is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CHROOT))  
                 error = ccs_write_chroot_policy(data, domain, cond, is_delete);  
         else if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_PIVOT_ROOT))  
                 error = ccs_write_pivot_root_policy(data, domain, cond,  
                                                     is_delete);  
         else  
                 error = ccs_write_file_policy(data, domain, cond, is_delete);  
642          if (cond)          if (cond)
643                  ccs_put_condition(cond);                  ccs_put_condition(cond);
644          return error;          return error;
# Line 855  static bool ccs_print_single_path_acl(st Line 861  static bool ccs_print_single_path_acl(st
861                  pos = head->read_avail;                  pos = head->read_avail;
862                  if (!ccs_io_printf(head, "allow_%s", msg) ||                  if (!ccs_io_printf(head, "allow_%s", msg) ||
863                      !ccs_print_name_union(head, &ptr->name) ||                      !ccs_print_name_union(head, &ptr->name) ||
864                      !ccs_print_condition(head, cond))                      !ccs_print_condition(head, cond)) {
865                          goto out;                          head->read_bit = bit;
866                            head->read_avail = pos;
867                            return false;
868                    }
869          }          }
870          head->read_bit = 0;          head->read_bit = 0;
871          return true;          return true;
  out:  
         head->read_bit = bit;  
         head->read_avail = pos;  
         return false;  
872  }  }
873    
874  /**  /**
# Line 892  static bool ccs_print_mkdev_acl(struct c Line 897  static bool ccs_print_mkdev_acl(struct c
897                      !ccs_print_name_union(head, &ptr->name) ||                      !ccs_print_name_union(head, &ptr->name) ||
898                      !ccs_print_number_union(head, &ptr->major) ||                      !ccs_print_number_union(head, &ptr->major) ||
899                      !ccs_print_number_union(head, &ptr->minor) ||                      !ccs_print_number_union(head, &ptr->minor) ||
900                      !ccs_print_condition(head, cond))                      !ccs_print_condition(head, cond)) {
901                          goto out;                          head->read_bit = bit;
902                            head->read_avail = pos;
903                            return false;
904                    }
905          }          }
906          head->read_bit = 0;          head->read_bit = 0;
907          return true;          return true;
  out:  
         head->read_bit = bit;  
         head->read_avail = pos;  
         return false;  
908  }  }
909    
910  /**  /**
# Line 928  static bool ccs_print_double_path_acl(st Line 932  static bool ccs_print_double_path_acl(st
932                  if (!ccs_io_printf(head, "allow_%s", msg) ||                  if (!ccs_io_printf(head, "allow_%s", msg) ||
933                      !ccs_print_name_union(head, &ptr->name1) ||                      !ccs_print_name_union(head, &ptr->name1) ||
934                      !ccs_print_name_union(head, &ptr->name2) ||                      !ccs_print_name_union(head, &ptr->name2) ||
935                      !ccs_print_condition(head, cond))                      !ccs_print_condition(head, cond)) {
936                          goto out;                          head->read_bit = bit;
937                            head->read_avail = pos;
938                            return false;
939                    }
940          }          }
941          head->read_bit = 0;          head->read_bit = 0;
942          return true;          return true;
  out:  
         head->read_bit = bit;  
         head->read_avail = pos;  
         return false;  
943  }  }
944    
945  /**  /**
# Line 964  static bool ccs_print_path_number_acl(st Line 967  static bool ccs_print_path_number_acl(st
967                  if (!ccs_io_printf(head, "allow_%s", msg) ||                  if (!ccs_io_printf(head, "allow_%s", msg) ||
968                      !ccs_print_name_union(head, &ptr->name) ||                      !ccs_print_name_union(head, &ptr->name) ||
969                      !ccs_print_number_union(head, &ptr->number) ||                      !ccs_print_number_union(head, &ptr->number) ||
970                      !ccs_print_condition(head, cond))                      !ccs_print_condition(head, cond)) {
971                          goto out;                          head->read_bit = bit;
972                            head->read_avail = pos;
973                            return false;
974                    }
975          }          }
976          head->read_bit = 0;          head->read_bit = 0;
977          return true;          return true;
  out:  
         head->read_bit = bit;  
         head->read_avail = pos;  
         return false;  
978  }  }
979    
980  /**  /**
# Line 988  static bool ccs_print_env_acl(struct ccs Line 990  static bool ccs_print_env_acl(struct ccs
990                                struct ccs_env_acl_record *ptr,                                struct ccs_env_acl_record *ptr,
991                                const struct ccs_condition *cond)                                const struct ccs_condition *cond)
992  {  {
993          int pos = head->read_avail;          const int pos = head->read_avail;
994          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_ENV "%s", ptr->env->name))          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_ENV "%s", ptr->env->name) ||
995                  goto out;              !ccs_print_condition(head, cond)) {
996          if (!ccs_print_condition(head, cond))                  head->read_avail = pos;
997                  goto out;                  return false;
998            }
999          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1000  }  }
1001    
1002  /**  /**
# Line 1012  static bool ccs_print_capability_acl(str Line 1012  static bool ccs_print_capability_acl(str
1012                                       struct ccs_capability_acl_record *ptr,                                       struct ccs_capability_acl_record *ptr,
1013                                       const struct ccs_condition *cond)                                       const struct ccs_condition *cond)
1014  {  {
1015          int pos = head->read_avail;          const int pos = head->read_avail;
1016          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CAPABILITY "%s",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CAPABILITY "%s",
1017                             ccs_cap2keyword(ptr->operation)))                             ccs_cap2keyword(ptr->operation)) ||
1018                  goto out;              !ccs_print_condition(head, cond)) {
1019          if (!ccs_print_condition(head, cond))                  head->read_avail = pos;
1020                  goto out;                  return false;
1021            }
1022          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1023  }  }
1024    
1025  /**  /**
# Line 1083  static bool ccs_print_network_acl(struct Line 1081  static bool ccs_print_network_acl(struct
1081                                    struct ccs_ip_network_acl_record *ptr,                                    struct ccs_ip_network_acl_record *ptr,
1082                                    const struct ccs_condition *cond)                                    const struct ccs_condition *cond)
1083  {  {
1084          int pos = head->read_avail;          const int pos = head->read_avail;
1085          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",
1086                             ccs_net2keyword(ptr->operation_type)))                             ccs_net2keyword(ptr->operation_type)))
1087                  goto out;                  goto out;
# Line 1124  static bool ccs_print_signal_acl(struct Line 1122  static bool ccs_print_signal_acl(struct
1122                                   struct ccs_signal_acl_record *ptr,                                   struct ccs_signal_acl_record *ptr,
1123                                   const struct ccs_condition *cond)                                   const struct ccs_condition *cond)
1124  {  {
1125          int pos = head->read_avail;          const int pos = head->read_avail;
1126          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u %s",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u %s",
1127                             ptr->sig, ptr->domainname->name))                             ptr->sig, ptr->domainname->name) ||
1128                  goto out;              !ccs_print_condition(head, cond)) {
1129          if (!ccs_print_condition(head, cond))                  head->read_avail = pos;
1130                  goto out;                  return false;
1131            }
1132          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1133  }  }
1134    
1135  /**  /**
# Line 1166  static bool ccs_print_mount_acl(struct c Line 1162  static bool ccs_print_mount_acl(struct c
1162                                  struct ccs_mount_acl_record *ptr,                                  struct ccs_mount_acl_record *ptr,
1163                                  const struct ccs_condition *cond)                                  const struct ccs_condition *cond)
1164  {  {
1165          int pos = head->read_avail;          const int pos = head->read_avail;
1166          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_MOUNT) ||
1167                             ptr->dev_name->name, ptr->dir_name->name,              !ccs_print_name_union(head, &ptr->dev_name) ||
1168                             ptr->fs_type->name, ptr->flags))              !ccs_print_name_union(head, &ptr->dir_name) ||
1169                  goto out;              !ccs_print_name_union(head, &ptr->fs_type) ||
1170          if (!ccs_print_condition(head, cond))              !ccs_print_number_union(head, &ptr->flags) ||
1171                  goto out;              !ccs_print_condition(head, cond)) {
1172                    head->read_avail = pos;
1173                    return false;
1174            }
1175          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1176  }  }
1177    
1178  /**  /**
# Line 1192  static bool ccs_print_umount_acl(struct Line 1188  static bool ccs_print_umount_acl(struct
1188                                   struct ccs_umount_acl_record *ptr,                                   struct ccs_umount_acl_record *ptr,
1189                                   const struct ccs_condition *cond)                                   const struct ccs_condition *cond)
1190  {  {
1191          int pos = head->read_avail;          const int pos = head->read_avail;
1192          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_UNMOUNT "%s\n",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_UNMOUNT) ||
1193                             ptr->dir->name))              !ccs_print_name_union(head, &ptr->dir) ||
1194                  goto out;              !ccs_print_condition(head, cond)) {
1195          if (!ccs_print_condition(head, cond))                  head->read_avail = pos;
1196                  goto out;                  return false;
1197            }
1198          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1199  }  }
1200    
1201  /**  /**
# Line 1217  static bool ccs_print_chroot_acl(struct Line 1211  static bool ccs_print_chroot_acl(struct
1211                                   struct ccs_chroot_acl_record *ptr,                                   struct ccs_chroot_acl_record *ptr,
1212                                   const struct ccs_condition *cond)                                   const struct ccs_condition *cond)
1213  {  {
1214          int pos = head->read_avail;          const int pos = head->read_avail;
1215          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CHROOT "%s\n",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CHROOT) ||
1216                             ptr->dir->name))              !ccs_print_name_union(head, &ptr->dir) ||
1217                  goto out;              !ccs_print_condition(head, cond)) {
1218          if (!ccs_print_condition(head, cond))                  head->read_avail = pos;
1219                  goto out;                  return false;
1220            }
1221          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1222  }  }
1223    
1224  /**  /**
# Line 1242  static bool ccs_print_pivot_root_acl(str Line 1234  static bool ccs_print_pivot_root_acl(str
1234                                       struct ccs_pivot_root_acl_record *ptr,                                       struct ccs_pivot_root_acl_record *ptr,
1235                                       const struct ccs_condition *cond)                                       const struct ccs_condition *cond)
1236  {  {
1237          int pos = head->read_avail;          const int pos = head->read_avail;
1238          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_PIVOT_ROOT "%s %s\n",          if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_PIVOT_ROOT) ||
1239                             ptr->new_root->name, ptr->old_root->name))              !ccs_print_name_union(head, &ptr->new_root) ||
1240                  goto out;              !ccs_print_name_union(head, &ptr->old_root) ||
1241          if (!ccs_print_condition(head, cond))              !ccs_print_condition(head, cond)) {
1242                  goto out;                  head->read_avail = pos;
1243                    return false;
1244            }
1245          return true;          return true;
  out:  
         head->read_avail = pos;  
         return false;  
1246  }  }
1247    
1248  /**  /**
# Line 1690  static int ccs_read_exception_policy(str Line 1681  static int ccs_read_exception_policy(str
1681          return 0;          return 0;
1682  }  }
1683    
1684    /**
1685     * ccs_get_argv0 - Get argv[0].
1686     *
1687     * @ee: Pointer to "struct ccs_execve_entry".
1688     *
1689     * Returns true on success, false otherwise.
1690     */
1691    static bool ccs_get_argv0(struct ccs_execve_entry *ee)
1692    {
1693            struct linux_binprm *bprm = ee->bprm;
1694            char *arg_ptr = ee->tmp;
1695            int arg_len = 0;
1696            unsigned long pos = bprm->p;
1697            int offset = pos % PAGE_SIZE;
1698            bool done = false;
1699            if (!bprm->argc)
1700                    goto out;
1701            while (1) {
1702                    if (!ccs_dump_page(bprm, pos, &ee->dump))
1703                            goto out;
1704                    pos += PAGE_SIZE - offset;
1705                    /* Read. */
1706                    while (offset < PAGE_SIZE) {
1707                            const char *kaddr = ee->dump.data;
1708                            const unsigned char c = kaddr[offset++];
1709                            if (c && arg_len < CCS_MAX_PATHNAME_LEN - 10) {
1710                                    if (c == '\\') {
1711                                            arg_ptr[arg_len++] = '\\';
1712                                            arg_ptr[arg_len++] = '\\';
1713                                    } else if (c == '/') {
1714                                            arg_len = 0;
1715                                    } else if (c > ' ' && c < 127) {
1716                                            arg_ptr[arg_len++] = c;
1717                                    } else {
1718                                            arg_ptr[arg_len++] = '\\';
1719                                            arg_ptr[arg_len++] = (c >> 6) + '0';
1720                                            arg_ptr[arg_len++]
1721                                                    = ((c >> 3) & 7) + '0';
1722                                            arg_ptr[arg_len++] = (c & 7) + '0';
1723                                    }
1724                            } else {
1725                                    arg_ptr[arg_len] = '\0';
1726                                    done = true;
1727                                    break;
1728                            }
1729                    }
1730                    offset = 0;
1731                    if (done)
1732                            break;
1733            }
1734            return true;
1735     out:
1736            return false;
1737    }
1738    
1739    static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry
1740                                                           *ee)
1741    {
1742            struct ccs_condition *cond;
1743            char *buf;
1744            int len = 256;
1745            char *realpath = NULL;
1746            char *argv0 = NULL;
1747            if (ccs_check_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) {
1748                    struct file *file = ee->bprm->file;
1749                    realpath = ccs_realpath_from_dentry(file->f_dentry,
1750                                                        file->f_vfsmnt);
1751                    if (realpath)
1752                            len += strlen(realpath) + 17;
1753            }
1754            if (ccs_check_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) {
1755                    if (ccs_get_argv0(ee)) {
1756                            argv0 = ee->tmp;
1757                            len += strlen(argv0) + 16;
1758                    }
1759            }
1760            buf = kmalloc(len, GFP_KERNEL);
1761            if (!buf)
1762                    return NULL;
1763            snprintf(buf, len - 1, "if");
1764            if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {
1765                    const int pos = strlen(buf);
1766                    snprintf(buf + pos, len - pos - 1,
1767                             " task.type=execute_handler");
1768            }
1769            if (realpath) {
1770                    const int pos = strlen(buf);
1771                    snprintf(buf + pos, len - pos - 1, " exec.realpath=\"%s\"",
1772                             realpath);
1773                    kfree(realpath);
1774            }
1775            if (argv0) {
1776                    const int pos = strlen(buf);
1777                    snprintf(buf + pos, len - pos - 1, " exec.argv[0]=\"%s\"",
1778                             argv0);
1779            }
1780            cond = ccs_get_condition(buf);
1781            kfree(buf);
1782            return cond;
1783    }
1784    
1785  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
1786  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1787    
# Line 1721  static atomic_t ccs_query_observers = AT Line 1813  static atomic_t ccs_query_observers = AT
1813   * Returns 0 if the supervisor decided to permit the access request which   * Returns 0 if the supervisor decided to permit the access request which
1814   * violated the policy in enforcing mode, 1 if the supervisor decided to   * violated the policy in enforcing mode, 1 if the supervisor decided to
1815   * retry the access request which violated the policy in enforcing mode,   * retry the access request which violated the policy in enforcing mode,
1816   * -EPERM otherwise.   * 0 if it is not in enforcing mode, -EPERM otherwise.
1817   */   */
1818  int ccs_check_supervisor(struct ccs_request_info *r, const char *fmt, ...)  int ccs_check_supervisor(struct ccs_request_info *r, const char *fmt, ...)
1819  {  {
# Line 1735  int ccs_check_supervisor(struct ccs_requ Line 1827  int ccs_check_supervisor(struct ccs_requ
1827          char *header;          char *header;
1828          if (!r->domain)          if (!r->domain)
1829                  r->domain = ccs_current_domain();                  r->domain = ccs_current_domain();
1830            switch (r->mode) {
1831                    char *buffer;
1832                    struct ccs_condition *cond;
1833            case 1:
1834                    if (!ccs_domain_quota_ok(r))
1835                            return 0;
1836                    va_start(args, fmt);
1837                    len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;
1838                    va_end(args);
1839                    buffer = kmalloc(len, GFP_KERNEL);
1840                    if (!buffer)
1841                            return 0;
1842                    va_start(args, fmt);
1843                    vsnprintf(buffer, len - 1, fmt, args);
1844                    va_end(args);
1845                    ccs_normalize_line(buffer);
1846                    if (r->ee && !strncmp(buffer, "allow_execute ", 14))
1847                            cond = ccs_get_execute_condition(r->ee);
1848                    else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
1849                            char str[] = "if task.type=execute_handler";
1850                            cond = ccs_get_condition(str);
1851                    } else
1852                            cond = NULL;
1853                    ccs_write_domain_policy2(buffer, r->domain, cond, false);
1854                    ccs_put_condition(cond);
1855                    kfree(buffer);
1856                    /* fall through */
1857            case 2:
1858                    return 0;
1859            }
1860          if (!atomic_read(&ccs_query_observers)) {          if (!atomic_read(&ccs_query_observers)) {
1861                  int i;                  int i;
1862                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)

Legend:
Removed from v.2894  
changed lines
  Added in v.2897

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