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

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 3167 by kumaneko, Tue Nov 10 11:55:04 2009 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-2009  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0-pre   2009/08/08   * Version: 1.7.1   2009/11/11
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 - Check memory quota.
58   *   *
59   * @ptr:  Pointer to allocated memory.   * @ptr:    Pointer to allocated memory.
60   * @size: Size in byte.   * @data:   Data to copy from.
61   */   * @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".  
62   *   *
63   * @group: Pointer to "struct ccs_path_group".   * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
64   */   */
65  void ccs_put_path_group(struct ccs_path_group *group)  bool ccs_commit_ok(void *ptr, void *data, const unsigned int size)
66  {  {
67          struct ccs_path_group_member *member;          if (ccs_memory_ok(ptr, size)) {
68          struct ccs_path_group_member *next_member;                  memmove(ptr, data, size);
69          LIST_HEAD(q);                  memset(data, 0, size);
70          bool can_delete_group = false;                  return true;
         if (!group)  
                 return;  
         mutex_lock(&ccs_policy_lock);  
         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));  
71          }          }
72            return false;
73  }  }
74    
 /**  
  * 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));  
         }  
 }  
75    
76  /**  /**
77   * ccs_put_number_group - Delete memory for "struct ccs_number_group".   * ccs_memory_free - Free memory for elements.
78   *   *
79   * @group: Pointer to "struct ccs_number_group".   * @ptr:  Pointer to allocated memory.
80     * @size: Size in byte.
81   */   */
82  void ccs_put_number_group(struct ccs_number_group *group)  void ccs_memory_free(const void *ptr, size_t size)
83  {  {
84          struct ccs_number_group_member *member;          atomic_sub(ccs_round2(size), &ccs_policy_memory_size);
85          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));  
         }  
86  }  }
87    
88  static LIST_HEAD(ccs_address_list);  LIST_HEAD(ccs_address_list);
89    
90  /**  /**
91   * 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 210  const struct in6_addr *ccs_get_ipv6_addr Line 124  const struct in6_addr *ccs_get_ipv6_addr
124          return ptr ? &ptr->addr : NULL;          return ptr ? &ptr->addr : NULL;
125  }  }
126    
 /**  
  * 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;  
 };  
   
127  /* The list for "struct ccs_name_entry". */  /* The list for "struct ccs_name_entry". */
128  static struct list_head ccs_name_list[CCS_MAX_HASH];  struct list_head ccs_name_list[CCS_MAX_HASH];
129  static DEFINE_MUTEX(ccs_name_list_lock);  DEFINE_MUTEX(ccs_name_list_lock);
130    
131  /**  /**
132   * 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 141  const struct ccs_path_info *ccs_get_name
141          unsigned int hash;          unsigned int hash;
142          int len;          int len;
143          int allocated_len;          int allocated_len;
144            struct list_head *head;
145    
146          if (!name)          if (!name)
147                  return NULL;                  return NULL;
148          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;  
         }  
149          hash = full_name_hash((const unsigned char *) name, len - 1);          hash = full_name_hash((const unsigned char *) name, len - 1);
150          /***** EXCLUSIVE SECTION START *****/  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
151            head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
152    #else
153            head = &ccs_name_list[hash % CCS_MAX_HASH];
154    #endif
155          mutex_lock(&ccs_name_list_lock);          mutex_lock(&ccs_name_list_lock);
156          list_for_each_entry(ptr, &ccs_name_list[hash % CCS_MAX_HASH], list) {          list_for_each_entry(ptr, head, list) {
157                  if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))                  if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
158                          continue;                          continue;
159                  atomic_inc(&ptr->users);                  atomic_inc(&ptr->users);
160                  goto out;                  goto out;
161          }          }
162          ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);          allocated_len = ccs_round2(sizeof(*ptr) + len);
163          allocated_len = ptr ? sizeof(*ptr) + len : 0;          ptr = kzalloc(allocated_len, GFP_KERNEL);
164          ccs_string_memory_size += allocated_len;          if (!ptr || (ccs_quota_for_policy &&
165          if (!allocated_len ||                       atomic_read(&ccs_policy_memory_size) + allocated_len
166              (ccs_quota_for_string &&                       > ccs_quota_for_policy)) {
              ccs_string_memory_size > ccs_quota_for_string)) {  
                 ccs_string_memory_size -= allocated_len;  
167                  kfree(ptr);                  kfree(ptr);
168                  ptr = NULL;                  ptr = NULL;
169                  printk(KERN_WARNING "ERROR: Out of memory. (%s)\n", __func__);                  ccs_warn_oom(__func__);
                 if (!ccs_policy_loaded)  
                         panic("MAC Initialization failed.\n");  
170                  goto out;                  goto out;
171          }          }
172            atomic_add(allocated_len, &ccs_policy_memory_size);
173          ptr->entry.name = ((char *) ptr) + sizeof(*ptr);          ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
174          memmove((char *) ptr->entry.name, name, len);          memmove((char *) ptr->entry.name, name, len);
175          atomic_set(&ptr->users, 1);          atomic_set(&ptr->users, 1);
176          ccs_fill_path_info(&ptr->entry);          ccs_fill_path_info(&ptr->entry);
177          ptr->size = allocated_len;          ptr->size = allocated_len;
178          list_add_tail(&ptr->list, &ccs_name_list[hash % CCS_MAX_HASH]);          list_add_tail(&ptr->list, head);
179   out:   out:
180          mutex_unlock(&ccs_name_list_lock);          mutex_unlock(&ccs_name_list_lock);
         /***** EXCLUSIVE SECTION END *****/  
181          return ptr ? &ptr->entry : NULL;          return ptr ? &ptr->entry : NULL;
182  }  }
183    
184  /**  /**
185   * 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.  
186   *   *
187   * Returns 0.   * Returns 0.
188   */   */
189  static int __init ccs_realpath_init(void)  static int __init ccs_mm_init(void)
190  {  {
191          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.");  
192          for (i = 0; i < CCS_MAX_HASH; i++)          for (i = 0; i < CCS_MAX_HASH; i++)
193                  INIT_LIST_HEAD(&ccs_name_list[i]);                  INIT_LIST_HEAD(&ccs_name_list[i]);
194          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 196  static int __init ccs_realpath_init(void
196          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
197          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)
198                  panic("Can't register ccs_kernel_domain");                  panic("Can't register ccs_kernel_domain");
 #ifdef CONFIG_CCSECURITY_BUILTIN_INITIALIZERS  
199          {          {
200                  /* Load built-in policy. */                  /* Load built-in policy. */
201                  static char ccs_builtin_initializers[] __initdata                  static char ccs_builtin_initializers[] __initdata
# Line 422  static int __init ccs_realpath_init(void Line 210  static int __init ccs_realpath_init(void
210                          cp = cp2;                          cp = cp2;
211                  }                  }
212          }          }
 #endif  
213          return 0;          return 0;
214  }  }
215    
216  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
217  __initcall(ccs_realpath_init);  __initcall(ccs_mm_init);
218  #else  #else
219  core_initcall(ccs_realpath_init);  core_initcall(ccs_mm_init);
220  #endif  #endif
221    
222  unsigned int ccs_audit_log_memory_size;  unsigned int ccs_audit_log_memory_size;
# Line 442  unsigned int ccs_quota_for_query; Line 229  unsigned int ccs_quota_for_query;
229   * ccs_read_memory_counter - Check for memory usage.   * ccs_read_memory_counter - Check for memory usage.
230   *   *
231   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
  *  
  * Returns memory usage.  
232   */   */
233  int ccs_read_memory_counter(struct ccs_io_buffer *head)  void ccs_read_memory_counter(struct ccs_io_buffer *head)
234  {  {
235          if (!head->read_eof) {          const unsigned int usage[3] = {
236                  const unsigned int string = ccs_string_memory_size;                  atomic_read(&ccs_policy_memory_size),
237                  const unsigned int nonstring                  ccs_audit_log_memory_size,
238                          = atomic_read(&ccs_non_string_memory_size);                  ccs_query_memory_size
239                  const unsigned int audit_log = ccs_audit_log_memory_size;          };
240                  const unsigned int query = ccs_query_memory_size;          const unsigned int quota[3] = {
241                  char buffer[64];                  ccs_quota_for_policy,
242                  memset(buffer, 0, sizeof(buffer));                  ccs_quota_for_audit_log,
243                  if (ccs_quota_for_string)                  ccs_quota_for_query
244                          snprintf(buffer, sizeof(buffer) - 1,          };
245                                   "   (Quota: %10u)", ccs_quota_for_string);          static const char *header[4] = {
246                  else                  "Policy:     ",
247                          buffer[0] = '\0';                  "Audit logs: ",
248                  ccs_io_printf(head, "Policy (string):         %10u%s\n",                  "Query lists:",
249                                string, buffer);                  "Total:      "
250                  if (ccs_quota_for_non_string)          };
251                          snprintf(buffer, sizeof(buffer) - 1,          unsigned int total = 0;
252                                   "   (Quota: %10u)", ccs_quota_for_non_string);          int i;
253                  else          if (head->read_eof)
254                          buffer[0] = '\0';                  return;
255                  ccs_io_printf(head, "Policy (non-string):     %10u%s\n",          for (i = 0; i < 3; i++) {
256                                nonstring, buffer);                  total += usage[i];
257                  if (ccs_quota_for_audit_log)                  ccs_io_printf(head, "%s %10u", header[i], usage[i]);
258                          snprintf(buffer, sizeof(buffer) - 1,                  if (quota[i])
259                                   "   (Quota: %10u)", ccs_quota_for_audit_log);                          ccs_io_printf(head, "   (Quota: %10u)", quota[i]);
260                  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;  
261          }          }
262          return 0;          ccs_io_printf(head, "%s %10u\n", header[3], total);
263            head->read_eof = true;
264  }  }
265    
266  /**  /**
# Line 501  int ccs_write_memory_quota(struct ccs_io Line 274  int ccs_write_memory_quota(struct ccs_io
274  {  {
275          char *data = head->write_buf;          char *data = head->write_buf;
276          unsigned int size;          unsigned int size;
277          if (sscanf(data, "Policy (string): %u", &size) == 1)          if (sscanf(data, "Policy: %u", &size) == 1)
278                  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;  
279          else if (sscanf(data, "Audit logs: %u", &size) == 1)          else if (sscanf(data, "Audit logs: %u", &size) == 1)
280                  ccs_quota_for_audit_log = size;                  ccs_quota_for_audit_log = size;
281          else if (sscanf(data, "Interactive enforcement: %u", &size) == 1)          else if (sscanf(data, "Query lists: %u", &size) == 1)
282                  ccs_quota_for_query = size;                  ccs_quota_for_query = size;
283          return 0;          return 0;
284  }  }

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

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