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

Subversion リポジトリの参照

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

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

branches/ccs-patch/security/ccsecurity/memory.c revision 2894 by kumaneko, Tue Aug 11 08:15:11 2009 UTC trunk/1.7.x/ccs-patch/security/ccsecurity/memory.c revision 3519 by kumaneko, Sun Mar 21 08:31:39 2010 UTC
# Line 1  Line 1 
1  /*  /*
2   * security/ccsecurity/gc.c   * security/ccsecurity/memory.c
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0-pre   2009/08/08   * Version: 1.7.2-pre   2010/03/21
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 11  Line 11 
11   */   */
12    
13  #include "internal.h"  #include "internal.h"
14    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
15    #include <linux/hash.h>
16    #endif
17    
18    void ccs_warn_oom(const char *function)
19    {
20            /* Reduce error messages. */
21            static pid_t ccs_last_pid;
22            const pid_t pid = current->pid;
23            if (ccs_last_pid != pid) {
24                    printk(KERN_WARNING "ERROR: Out of memory at %s.\n",
25                           function);
26                    ccs_last_pid = pid;
27            }
28            if (!ccs_policy_loaded)
29                    panic("MAC Initialization failed.\n");
30    }
31    
32  static atomic_t ccs_non_string_memory_size;  static atomic_t ccs_policy_memory_size;
33  static unsigned int ccs_quota_for_non_string;  static unsigned int ccs_quota_for_policy;
34    
35  /**  /**
36   * ccs_memory_ok - Check memory quota.   * ccs_memory_ok - Check memory quota.
# Line 21  static unsigned int ccs_quota_for_non_st Line 38  static unsigned int ccs_quota_for_non_st
38   * @ptr:  Pointer to allocated memory.   * @ptr:  Pointer to allocated memory.
39   * @size: Size in byte.   * @size: Size in byte.
40   *   *
41   * Returns true if @ptr is not NULL and quota not exceeded, false otehrwise.   * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
42   */   */
43  bool ccs_memory_ok(const void *ptr, const unsigned int size)  bool ccs_memory_ok(const void *ptr, const unsigned int size)
44  {  {
45          atomic_add(size, &ccs_non_string_memory_size);          size_t s = ccs_round2(size);
46          if (ptr && (!ccs_quota_for_non_string ||          atomic_add(s, &ccs_policy_memory_size);
47                      atomic_read(&ccs_non_string_memory_size)          if (ptr && (!ccs_quota_for_policy ||
48                      <= ccs_quota_for_non_string))                      atomic_read(&ccs_policy_memory_size)
49                        <= ccs_quota_for_policy))
50                  return true;                  return true;
51          atomic_sub(size, &ccs_non_string_memory_size);          atomic_sub(s, &ccs_policy_memory_size);
52          printk(KERN_WARNING "ERROR: Out of memory. (%s)\n", __func__);          ccs_warn_oom(__func__);
         if (!ccs_policy_loaded)  
                 panic("MAC Initialization failed.\n");  
53          return false;          return false;
54  }  }
55    
56  /**  /**
57   * ccs_memory_free - Free memory for elements.   * ccs_commit_ok - Allocate memory and check memory quota.
58   *   *
59   * @ptr:  Pointer to allocated memory.   * @data:   Data to copy from.
60   * @size: Size in byte.   * @size:   Size in byte.
  */  
 void ccs_memory_free(const void *ptr, size_t size)  
 {  
         atomic_sub(size, &ccs_non_string_memory_size);  
         kfree(ptr);  
 }  
   
 /**  
  * ccs_put_path_group - Delete memory for "struct ccs_path_group".  
61   *   *
62   * @group: Pointer to "struct ccs_path_group".   * Returns pointer to allocated memory on success, NULL otherwise.
63     * @data is zero-cleared on success.
64   */   */
65  void ccs_put_path_group(struct ccs_path_group *group)  void *ccs_commit_ok(void *data, const unsigned int size)
66  {  {
67          struct ccs_path_group_member *member;          void *ptr = kmalloc(size, CCS_GFP_FLAGS);
68          struct ccs_path_group_member *next_member;          if (!ptr)
69          LIST_HEAD(q);                  return NULL;
70          bool can_delete_group = false;          if (ccs_memory_ok(ptr, size)) {
71          if (!group)                  memmove(ptr, data, size);
72                  return;                  memset(data, 0, size);
73          mutex_lock(&ccs_policy_lock);                  return ptr;
         if (atomic_dec_and_test(&group->users)) {  
                 list_for_each_entry_safe(member, next_member,  
                                          &group->path_group_member_list,  
                                          list) {  
                         if (!member->is_deleted)  
                                 break;  
                         list_del(&member->list);  
                         list_add(&member->list, &q);  
                 }  
                 if (list_empty(&group->path_group_member_list)) {  
                         list_del(&group->list);  
                         can_delete_group = true;  
                 }  
         }  
         mutex_unlock(&ccs_policy_lock);  
         list_for_each_entry_safe(member, next_member, &q, list) {  
                 list_del(&member->list);  
                 ccs_put_name(member->member_name);  
                 ccs_memory_free(member, sizeof(*member));  
         }  
         if (can_delete_group) {  
                 ccs_put_name(group->group_name);  
                 ccs_memory_free(group, sizeof(*group));  
74          }          }
75            kfree(ptr);
76            return NULL;
77  }  }
78    
 /**  
  * ccs_put_address_group - Delete memory for "struct ccs_address_group_entry".  
  *  
  * @group: Pointer to "struct ccs_address_group_entry".  
  */  
 void ccs_put_address_group(struct ccs_address_group_entry *group)  
 {  
         struct ccs_address_group_member *member;  
         struct ccs_address_group_member *next_member;  
         LIST_HEAD(q);  
         bool can_delete_group = false;  
         if (!group)  
                 return;  
         mutex_lock(&ccs_policy_lock);  
         if (atomic_dec_and_test(&group->users)) {  
                 list_for_each_entry_safe(member, next_member,  
                                          &group->address_group_member_list,  
                                          list) {  
                         if (!member->is_deleted)  
                                 break;  
                         list_del(&member->list);  
                         list_add(&member->list, &q);  
                 }  
                 if (list_empty(&group->address_group_member_list)) {  
                         list_del(&group->list);  
                         can_delete_group = true;  
                 }  
         }  
         mutex_unlock(&ccs_policy_lock);  
         list_for_each_entry_safe(member, next_member, &q, list) {  
                 list_del(&member->list);  
                 if (member->is_ipv6) {  
                         ccs_put_ipv6_address(member->min.ipv6);  
                         ccs_put_ipv6_address(member->max.ipv6);  
                 }  
                 ccs_memory_free(member, sizeof(*member));  
         }  
         if (can_delete_group) {  
                 ccs_put_name(group->group_name);  
                 ccs_memory_free(group, sizeof(*group));  
         }  
 }  
79    
80  /**  /**
81   * ccs_put_number_group - Delete memory for "struct ccs_number_group".   * ccs_memory_free - Free memory for elements.
82   *   *
83   * @group: Pointer to "struct ccs_number_group".   * @ptr:  Pointer to allocated memory.
84     * @size: Size in byte.
85   */   */
86  void ccs_put_number_group(struct ccs_number_group *group)  void ccs_memory_free(const void *ptr, size_t size)
87  {  {
88          struct ccs_number_group_member *member;          atomic_sub(ccs_round2(size), &ccs_policy_memory_size);
89          struct ccs_number_group_member *next_member;          kfree(ptr);
         LIST_HEAD(q);  
         bool can_delete_group = false;  
         if (!group)  
                 return;  
         mutex_lock(&ccs_policy_lock);  
         if (atomic_dec_and_test(&group->users)) {  
                 list_for_each_entry_safe(member, next_member,  
                                          &group->number_group_member_list,  
                                          list) {  
                         if (!member->is_deleted)  
                                 break;  
                         list_del(&member->list);  
                         list_add(&member->list, &q);  
                 }  
                 if (list_empty(&group->number_group_member_list)) {  
                         list_del(&group->list);  
                         can_delete_group = true;  
                 }  
         }  
         mutex_unlock(&ccs_policy_lock);  
         list_for_each_entry_safe(member, next_member, &q, list) {  
                 list_del(&member->list);  
                 ccs_memory_free(member, sizeof(*member));  
         }  
         if (can_delete_group) {  
                 ccs_put_name(group->group_name);  
                 ccs_memory_free(group, sizeof(*group));  
         }  
90  }  }
91    
92  static LIST_HEAD(ccs_address_list);  LIST_HEAD(ccs_address_list);
93    
94  /**  /**
95   * ccs_get_ipv6_address - Keep the given IPv6 address on the RAM.   * ccs_get_ipv6_address - Keep the given IPv6 address on the RAM.
# Line 189  const struct in6_addr *ccs_get_ipv6_addr Line 107  const struct in6_addr *ccs_get_ipv6_addr
107          int error = -ENOMEM;          int error = -ENOMEM;
108          if (!addr)          if (!addr)
109                  return NULL;                  return NULL;
110          entry = kzalloc(sizeof(*entry), GFP_KERNEL);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
111          mutex_lock(&ccs_policy_lock);          mutex_lock(&ccs_policy_lock);
112          list_for_each_entry(ptr, &ccs_address_list, list) {          list_for_each_entry(ptr, &ccs_address_list, list) {
113                  if (memcmp(&ptr->addr, addr, sizeof(*addr)))                  if (memcmp(&ptr->addr, addr, sizeof(*addr)))
# Line 210  const struct in6_addr *ccs_get_ipv6_addr Line 128  const struct in6_addr *ccs_get_ipv6_addr
128          return ptr ? &ptr->addr : NULL;          return ptr ? &ptr->addr : NULL;
129  }  }
130    
 /**  
  * ccs_put_ipv6_address - Delete the given IPv6 address on the RAM.  
  *  
  * @addr: Pointer to "struct in6_addr".  
  */  
 void ccs_put_ipv6_address(const struct in6_addr *addr)  
 {  
         struct ccs_ipv6addr_entry *ptr;  
         bool can_delete = false;  
         if (!addr)  
                 return;  
         ptr = container_of(addr, struct ccs_ipv6addr_entry, addr);  
         mutex_lock(&ccs_policy_lock);  
         if (atomic_dec_and_test(&ptr->users)) {  
                 list_del(&ptr->list);  
                 can_delete = true;  
         }  
         mutex_unlock(&ccs_policy_lock);  
         if (can_delete)  
                 ccs_memory_free(ptr, sizeof(*ptr));  
 }  
   
 /**  
  * ccs_put_condition - Delete memory for "struct ccs_condition".  
  *  
  * @cond: Pointer to "struct ccs_condition".  
  */  
 void ccs_put_condition(struct ccs_condition *cond)  
 {  
         const struct ccs_condition_element *condp;  
         struct ccs_number_union *numbers_p;  
         struct ccs_name_union *names_p;  
         const struct ccs_argv_entry *argv;  
         const struct ccs_envp_entry *envp;  
         u16 condc;  
         u16 numbers_count;  
         u16 names_count;  
         u16 argc;  
         u16 envc;  
         u16 i;  
         bool can_delete = false;  
         if (!cond)  
                 return;  
         mutex_lock(&ccs_policy_lock);  
         if (atomic_dec_and_test(&cond->users)) {  
                 list_del(&cond->list);  
                 can_delete = true;  
         }  
         mutex_unlock(&ccs_policy_lock);  
         if (!can_delete)  
                 return;  
         condc = cond->condc;  
         numbers_count = cond->numbers_count;  
         names_count = cond->names_count;  
         argc = cond->argc;  
         envc = cond->envc;  
         condp = (const struct ccs_condition_element *) (cond + 1);  
         numbers_p = (struct ccs_number_union *) (condp + condc);  
         names_p = (struct ccs_name_union *) (numbers_p + numbers_count);  
         argv = (const struct ccs_argv_entry *) (names_p + names_count);  
         envp = (const struct ccs_envp_entry *) (argv + argc);  
         for (i = 0; i < cond->numbers_count; i++)  
                 ccs_put_number_union(numbers_p++);  
         for (i = 0; i < cond->names_count; i++)  
                 ccs_put_name_union(names_p++);  
         for (i = 0; i < argc; argv++, i++)  
                 ccs_put_name(argv->value);  
         for (i = 0; i < envc; envp++, i++) {  
                 ccs_put_name(envp->name);  
                 ccs_put_name(envp->value);  
         }  
         ccs_memory_free(cond, cond->size);  
 }  
   
 static unsigned int ccs_string_memory_size;  
 static unsigned int ccs_quota_for_string;  
   
 #define CCS_MAX_HASH 256  
   
 /* Structure for string data. */  
 struct ccs_name_entry {  
         struct list_head list;  
         atomic_t users;  
         int size;  
         struct ccs_path_info entry;  
 };  
   
131  /* The list for "struct ccs_name_entry". */  /* The list for "struct ccs_name_entry". */
132  static struct list_head ccs_name_list[CCS_MAX_HASH];  struct list_head ccs_name_list[CCS_MAX_HASH];
 static DEFINE_MUTEX(ccs_name_list_lock);  
133    
134  /**  /**
135   * ccs_get_name - Allocate memory for string data.   * ccs_get_name - Allocate memory for string data.
# Line 314  const struct ccs_path_info *ccs_get_name Line 144  const struct ccs_path_info *ccs_get_name
144          unsigned int hash;          unsigned int hash;
145          int len;          int len;
146          int allocated_len;          int allocated_len;
147            struct list_head *head;
148    
149          if (!name)          if (!name)
150                  return NULL;                  return NULL;
151          len = strlen(name) + 1;          len = strlen(name) + 1;
         if (len > CCS_MAX_PATHNAME_LEN) {  
                 printk(KERN_WARNING "ERROR: Name too long. (%s)\n", __func__);  
                 return NULL;  
         }  
152          hash = full_name_hash((const unsigned char *) name, len - 1);          hash = full_name_hash((const unsigned char *) name, len - 1);
153          /***** EXCLUSIVE SECTION START *****/  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
154          mutex_lock(&ccs_name_list_lock);          head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
155          list_for_each_entry(ptr, &ccs_name_list[hash % CCS_MAX_HASH], list) {  #else
156            head = &ccs_name_list[hash % CCS_MAX_HASH];
157    #endif
158            mutex_lock(&ccs_policy_lock);
159            list_for_each_entry(ptr, head, list) {
160                  if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))                  if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
161                          continue;                          continue;
162                  atomic_inc(&ptr->users);                  atomic_inc(&ptr->users);
163                  goto out;                  goto out;
164          }          }
165          ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);          allocated_len = ccs_round2(sizeof(*ptr) + len);
166          allocated_len = ptr ? sizeof(*ptr) + len : 0;          ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
167          ccs_string_memory_size += allocated_len;          if (!ptr || (ccs_quota_for_policy &&
168          if (!allocated_len ||                       atomic_read(&ccs_policy_memory_size) + allocated_len
169              (ccs_quota_for_string &&                       > ccs_quota_for_policy)) {
              ccs_string_memory_size > ccs_quota_for_string)) {  
                 ccs_string_memory_size -= allocated_len;  
170                  kfree(ptr);                  kfree(ptr);
171                  ptr = NULL;                  ptr = NULL;
172                  printk(KERN_WARNING "ERROR: Out of memory. (%s)\n", __func__);                  ccs_warn_oom(__func__);
                 if (!ccs_policy_loaded)  
                         panic("MAC Initialization failed.\n");  
173                  goto out;                  goto out;
174          }          }
175            atomic_add(allocated_len, &ccs_policy_memory_size);
176          ptr->entry.name = ((char *) ptr) + sizeof(*ptr);          ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
177          memmove((char *) ptr->entry.name, name, len);          memmove((char *) ptr->entry.name, name, len);
178          atomic_set(&ptr->users, 1);          atomic_set(&ptr->users, 1);
179          ccs_fill_path_info(&ptr->entry);          ccs_fill_path_info(&ptr->entry);
180          ptr->size = allocated_len;          ptr->size = allocated_len;
181          list_add_tail(&ptr->list, &ccs_name_list[hash % CCS_MAX_HASH]);          list_add_tail(&ptr->list, head);
182   out:   out:
183          mutex_unlock(&ccs_name_list_lock);          mutex_unlock(&ccs_policy_lock);
         /***** EXCLUSIVE SECTION END *****/  
184          return ptr ? &ptr->entry : NULL;          return ptr ? &ptr->entry : NULL;
185  }  }
186    
187  /**  /**
188   * ccs_put_name - Delete shared memory for string data.   * ccs_mm_init - Initialize mm related code.
  *  
  * @name: Pointer to "struct ccs_path_info".  
  */  
 void ccs_put_name(const struct ccs_path_info *name)  
 {  
         struct ccs_name_entry *ptr;  
         bool can_delete = false;  
         if (!name)  
                 return;  
         ptr = container_of(name, struct ccs_name_entry, entry);  
         /***** EXCLUSIVE SECTION START *****/  
         mutex_lock(&ccs_name_list_lock);  
         if (atomic_dec_and_test(&ptr->users)) {  
                 list_del(&ptr->list);  
                 ccs_string_memory_size -= ptr->size;  
                 can_delete = true;  
         }  
         mutex_unlock(&ccs_name_list_lock);  
         /***** EXCLUSIVE SECTION END *****/  
         if (can_delete)  
                 kfree(ptr);  
 }  
   
 struct srcu_struct ccs_ss;  
   
 /**  
  * ccs_realpath_init - Initialize realpath related code.  
  *  
  * Returns 0.  
189   */   */
190  static int __init ccs_realpath_init(void)  void __init ccs_mm_init(void)
191  {  {
192          int i;          int i;
         /* Constraint for ccs_get_name(). */  
         if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE)  
                 panic("Bad size.");  
         /* Constraint for "struct ccs_execve_entry"->tmp users. */  
         if (CCS_MAX_PATHNAME_LEN > CCS_EXEC_TMPSIZE)  
                 panic("Bad size.");  
         if (init_srcu_struct(&ccs_ss))  
                 panic("Out of memory.");  
193          for (i = 0; i < CCS_MAX_HASH; i++)          for (i = 0; i < CCS_MAX_HASH; i++)
194                  INIT_LIST_HEAD(&ccs_name_list[i]);                  INIT_LIST_HEAD(&ccs_name_list[i]);
195          INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);          INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
# Line 407  static int __init ccs_realpath_init(void Line 197  static int __init ccs_realpath_init(void
197          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
198          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)
199                  panic("Can't register ccs_kernel_domain");                  panic("Can't register ccs_kernel_domain");
 #ifdef CONFIG_CCSECURITY_BUILTIN_INITIALIZERS  
200          {          {
201                  /* Load built-in policy. */                  /* Load built-in policy. */
202                  static char ccs_builtin_initializers[] __initdata                  static char ccs_builtin_initializers[] __initdata
# Line 422  static int __init ccs_realpath_init(void Line 211  static int __init ccs_realpath_init(void
211                          cp = cp2;                          cp = cp2;
212                  }                  }
213          }          }
 #endif  
         return 0;  
214  }  }
215    
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)  
 __initcall(ccs_realpath_init);  
 #else  
 core_initcall(ccs_realpath_init);  
 #endif  
   
216  unsigned int ccs_audit_log_memory_size;  unsigned int ccs_audit_log_memory_size;
217  unsigned int ccs_quota_for_audit_log;  unsigned int ccs_quota_for_audit_log;
218    
# Line 442  unsigned int ccs_quota_for_query; Line 223  unsigned int ccs_quota_for_query;
223   * ccs_read_memory_counter - Check for memory usage.   * ccs_read_memory_counter - Check for memory usage.
224   *   *
225   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
  *  
  * Returns memory usage.  
226   */   */
227  int ccs_read_memory_counter(struct ccs_io_buffer *head)  void ccs_read_memory_counter(struct ccs_io_buffer *head)
228  {  {
229          if (!head->read_eof) {          const unsigned int usage[3] = {
230                  const unsigned int string = ccs_string_memory_size;                  atomic_read(&ccs_policy_memory_size),
231                  const unsigned int nonstring                  ccs_audit_log_memory_size,
232                          = atomic_read(&ccs_non_string_memory_size);                  ccs_query_memory_size
233                  const unsigned int audit_log = ccs_audit_log_memory_size;          };
234                  const unsigned int query = ccs_query_memory_size;          const unsigned int quota[3] = {
235                  char buffer[64];                  ccs_quota_for_policy,
236                  memset(buffer, 0, sizeof(buffer));                  ccs_quota_for_audit_log,
237                  if (ccs_quota_for_string)                  ccs_quota_for_query
238                          snprintf(buffer, sizeof(buffer) - 1,          };
239                                   "   (Quota: %10u)", ccs_quota_for_string);          static const char *header[4] = {
240                  else                  "Policy:     ",
241                          buffer[0] = '\0';                  "Audit logs: ",
242                  ccs_io_printf(head, "Policy (string):         %10u%s\n",                  "Query lists:",
243                                string, buffer);                  "Total:      "
244                  if (ccs_quota_for_non_string)          };
245                          snprintf(buffer, sizeof(buffer) - 1,          unsigned int total = 0;
246                                   "   (Quota: %10u)", ccs_quota_for_non_string);          int i;
247                  else          if (head->read_eof)
248                          buffer[0] = '\0';                  return;
249                  ccs_io_printf(head, "Policy (non-string):     %10u%s\n",          for (i = 0; i < 3; i++) {
250                                nonstring, buffer);                  total += usage[i];
251                  if (ccs_quota_for_audit_log)                  ccs_io_printf(head, "%s %10u", header[i], usage[i]);
252                          snprintf(buffer, sizeof(buffer) - 1,                  if (quota[i])
253                                   "   (Quota: %10u)", ccs_quota_for_audit_log);                          ccs_io_printf(head, "   (Quota: %10u)", quota[i]);
254                  else                  ccs_io_printf(head, "\n");
                         buffer[0] = '\0';  
                 ccs_io_printf(head, "Audit logs:              %10u%s\n",  
                               audit_log, buffer);  
                 if (ccs_quota_for_query)  
                         snprintf(buffer, sizeof(buffer) - 1,  
                                  "   (Quota: %10u)", ccs_quota_for_query);  
                 else  
                         buffer[0] = '\0';  
                 ccs_io_printf(head, "Interactive enforcement: %10u%s\n",  
                               query, buffer);  
                 ccs_io_printf(head, "Total:                   %10u\n",  
                               string + nonstring + audit_log + query);  
                 head->read_eof = true;  
255          }          }
256          return 0;          ccs_io_printf(head, "%s %10u\n", header[3], total);
257            head->read_eof = true;
258  }  }
259    
260  /**  /**
# Line 501  int ccs_write_memory_quota(struct ccs_io Line 268  int ccs_write_memory_quota(struct ccs_io
268  {  {
269          char *data = head->write_buf;          char *data = head->write_buf;
270          unsigned int size;          unsigned int size;
271          if (sscanf(data, "Policy (string): %u", &size) == 1)          if (sscanf(data, "Policy: %u", &size) == 1)
272                  ccs_quota_for_string = size;                  ccs_quota_for_policy = size;
         else if (sscanf(data, "Policy (non-string): %u", &size) == 1)  
                 ccs_quota_for_non_string = size;  
273          else if (sscanf(data, "Audit logs: %u", &size) == 1)          else if (sscanf(data, "Audit logs: %u", &size) == 1)
274                  ccs_quota_for_audit_log = size;                  ccs_quota_for_audit_log = size;
275          else if (sscanf(data, "Interactive enforcement: %u", &size) == 1)          else if (sscanf(data, "Query lists: %u", &size) == 1)
276                  ccs_quota_for_query = size;                  ccs_quota_for_query = size;
277          return 0;          return 0;
278  }  }

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

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