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

Subversion リポジトリの参照

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

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

trunk/1.7.x/ccs-patch/security/ccsecurity/memory.c revision 3131 by kumaneko, Tue Nov 3 03:51:07 2009 UTC branches/ccs-patch/security/ccsecurity/memory.c revision 3731 by kumaneko, Fri Jun 4 01:42:54 2010 UTC
# Line 1  Line 1 
1  /*  /*
2   * security/ccsecurity/memory.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.1-pre   2009/11/03   * Version: 1.7.2+   2010/06/04
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    /**
19     * ccs_warn_oom - Print out of memory warning message.
20     *
21     * @function: Function's name.
22     */
23  void ccs_warn_oom(const char *function)  void ccs_warn_oom(const char *function)
24  {  {
25          /* Reduce error messages. */          /* Reduce error messages. */
# Line 26  void ccs_warn_oom(const char *function) Line 34  void ccs_warn_oom(const char *function)
34                  panic("MAC Initialization failed.\n");                  panic("MAC Initialization failed.\n");
35  }  }
36    
37    /* Memory allocated for policy. */
38  static atomic_t ccs_policy_memory_size;  static atomic_t ccs_policy_memory_size;
39    /* Quota for holding policy. */
40  static unsigned int ccs_quota_for_policy;  static unsigned int ccs_quota_for_policy;
41    
42  /**  /**
# Line 51  bool ccs_memory_ok(const void *ptr, cons Line 61  bool ccs_memory_ok(const void *ptr, cons
61  }  }
62    
63  /**  /**
64   * ccs_commit_ok - Check memory quota.   * ccs_commit_ok - Allocate memory and check memory quota.
65   *   *
  * @ptr:    Pointer to allocated memory.  
66   * @data:   Data to copy from.   * @data:   Data to copy from.
67   * @size:   Size in byte.   * @size:   Size in byte.
68   *   *
69   * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.   * Returns pointer to allocated memory on success, NULL otherwise.
70     * @data is zero-cleared on success.
71   */   */
72  bool ccs_commit_ok(void *ptr, void *data, const unsigned int size)  void *ccs_commit_ok(void *data, const unsigned int size)
73  {  {
74            void *ptr = kmalloc(size, CCS_GFP_FLAGS);
75          if (ccs_memory_ok(ptr, size)) {          if (ccs_memory_ok(ptr, size)) {
76                  memmove(ptr, data, size);                  memmove(ptr, data, size);
77                  memset(data, 0, size);                  memset(data, 0, size);
78                  return true;                  return ptr;
79          }          }
80          return false;          kfree(ptr);
81            return NULL;
82  }  }
83    
   
84  /**  /**
85   * ccs_memory_free - Free memory for elements.   * ccs_memory_free - Free memory for elements.
86   *   *
# Line 82  void ccs_memory_free(const void *ptr, si Line 93  void ccs_memory_free(const void *ptr, si
93          kfree(ptr);          kfree(ptr);
94  }  }
95    
96  LIST_HEAD(ccs_address_list);  /**
97     * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group".
98     *
99     * @group_name: The name of address group.
100     * @idx:        Index number.
101     *
102     * Returns pointer to "struct ccs_group" on success, NULL otherwise.
103     */
104    struct ccs_group *ccs_get_group(const char *group_name, const u8 idx)
105    {
106            struct ccs_group e = { };
107            struct ccs_group *group = NULL;
108            bool found = false;
109            if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
110                    return NULL;
111            e.group_name = ccs_get_name(group_name);
112            if (!e.group_name)
113                    return NULL;
114            if (mutex_lock_interruptible(&ccs_policy_lock))
115                    goto out;
116            list_for_each_entry(group, &ccs_group_list[idx], head.list) {
117                    if (e.group_name != group->group_name)
118                            continue;
119                    atomic_inc(&group->head.users);
120                    found = true;
121                    break;
122            }
123            if (!found) {
124                    struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e));
125                    if (entry) {
126                            INIT_LIST_HEAD(&entry->member_list);
127                            atomic_set(&entry->head.users, 1);
128                            list_add_tail_rcu(&entry->head.list,
129                                              &ccs_group_list[idx]);
130                            group = entry;
131                            found = true;
132                    }
133            }
134            mutex_unlock(&ccs_policy_lock);
135     out:
136            ccs_put_name(e.group_name);
137            return found ? group : NULL;
138    }
139    
140  /**  /**
141   * 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 95  LIST_HEAD(ccs_address_list); Line 148  LIST_HEAD(ccs_address_list);
148   */   */
149  const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr)  const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr)
150  {  {
151          struct ccs_ipv6addr_entry *entry;          struct ccs_ipv6addr *entry;
152          struct ccs_ipv6addr_entry *ptr;          struct ccs_ipv6addr *ptr = NULL;
153          int error = -ENOMEM;          int error = -ENOMEM;
154          if (!addr)          if (!addr)
155                  return NULL;                  return NULL;
156          entry = kzalloc(sizeof(*entry), GFP_KERNEL);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
157          mutex_lock(&ccs_policy_lock);          if (mutex_lock_interruptible(&ccs_policy_lock))
158          list_for_each_entry(ptr, &ccs_address_list, list) {                  goto out;
159            list_for_each_entry(ptr, &ccs_shared_list[CCS_IPV6ADDRESS_LIST],
160                                head.list) {
161                  if (memcmp(&ptr->addr, addr, sizeof(*addr)))                  if (memcmp(&ptr->addr, addr, sizeof(*addr)))
162                          continue;                          continue;
163                  atomic_inc(&ptr->users);                  atomic_inc(&ptr->head.users);
164                  error = 0;                  error = 0;
165                  break;                  break;
166          }          }
167          if (error && ccs_memory_ok(entry, sizeof(*entry))) {          if (error && ccs_memory_ok(entry, sizeof(*entry))) {
168                  ptr = entry;                  ptr = entry;
169                  ptr->addr = *addr;                  ptr->addr = *addr;
170                  atomic_set(&ptr->users, 1);                  atomic_set(&ptr->head.users, 1);
171                  list_add_tail(&ptr->list, &ccs_address_list);                  list_add_tail(&ptr->head.list,
172                                  &ccs_shared_list[CCS_IPV6ADDRESS_LIST]);
173                  entry = NULL;                  entry = NULL;
174                    error = 0;
175          }          }
176          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
177     out:
178          kfree(entry);          kfree(entry);
179          return ptr ? &ptr->addr : NULL;          return !error ? &ptr->addr : NULL;
180  }  }
181    
182  /* The list for "struct ccs_name_entry". */  /* The list for "struct ccs_name". */
183  struct list_head ccs_name_list[CCS_MAX_HASH];  struct list_head ccs_name_list[CCS_MAX_HASH];
 DEFINE_MUTEX(ccs_name_list_lock);  
184    
185  /**  /**
186   * ccs_get_name - Allocate memory for string data.   * ccs_get_name - Allocate memory for string data.
# Line 134  DEFINE_MUTEX(ccs_name_list_lock); Line 191  DEFINE_MUTEX(ccs_name_list_lock);
191   */   */
192  const struct ccs_path_info *ccs_get_name(const char *name)  const struct ccs_path_info *ccs_get_name(const char *name)
193  {  {
194          struct ccs_name_entry *ptr;          struct ccs_name *ptr;
195          unsigned int hash;          unsigned int hash;
196          int len;          int len;
197          int allocated_len;          int allocated_len;
198            struct list_head *head;
199    
200          if (!name)          if (!name)
201                  return NULL;                  return NULL;
202          len = strlen(name) + 1;          len = strlen(name) + 1;
203          hash = full_name_hash((const unsigned char *) name, len - 1);          hash = full_name_hash((const unsigned char *) name, len - 1);
204          mutex_lock(&ccs_name_list_lock);  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
205          list_for_each_entry(ptr, &ccs_name_list[hash % CCS_MAX_HASH], list) {          head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
206    #else
207            head = &ccs_name_list[hash % CCS_MAX_HASH];
208    #endif
209            if (mutex_lock_interruptible(&ccs_policy_lock))
210                    return NULL;
211            list_for_each_entry(ptr, head, head.list) {
212                  if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))                  if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
213                          continue;                          continue;
214                  atomic_inc(&ptr->users);                  atomic_inc(&ptr->head.users);
215                  goto out;                  goto out;
216          }          }
217          allocated_len = ccs_round2(sizeof(*ptr) + len);          allocated_len = sizeof(*ptr) + len;
218          ptr = kzalloc(allocated_len, GFP_KERNEL);          ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
219          if (!ptr || (ccs_quota_for_policy &&          if (ccs_memory_ok(ptr, allocated_len)) {
220                       atomic_read(&ccs_policy_memory_size) + allocated_len                  ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
221                       > ccs_quota_for_policy)) {                  memmove((char *) ptr->entry.name, name, len);
222                    atomic_set(&ptr->head.users, 1);
223                    ccs_fill_path_info(&ptr->entry);
224                    ptr->size = allocated_len;
225                    list_add_tail(&ptr->head.list, head);
226            } else {
227                  kfree(ptr);                  kfree(ptr);
228                  ptr = NULL;                  ptr = NULL;
                 ccs_warn_oom(__func__);  
                 goto out;  
229          }          }
         atomic_add(allocated_len, &ccs_policy_memory_size);  
         ptr->entry.name = ((char *) ptr) + sizeof(*ptr);  
         memmove((char *) ptr->entry.name, name, len);  
         atomic_set(&ptr->users, 1);  
         ccs_fill_path_info(&ptr->entry);  
         ptr->size = allocated_len;  
         list_add_tail(&ptr->list, &ccs_name_list[hash % CCS_MAX_HASH]);  
230   out:   out:
231          mutex_unlock(&ccs_name_list_lock);          mutex_unlock(&ccs_policy_lock);
232          return ptr ? &ptr->entry : NULL;          return ptr ? &ptr->entry : NULL;
233  }  }
234    
235  /**  /**
236   * ccs_mm_init - Initialize mm related code.   * ccs_mm_init - Initialize mm related code.
  *  
  * Returns 0.  
237   */   */
238  static int __init ccs_mm_init(void)  void __init ccs_mm_init(void)
239  {  {
240          int i;          int idx;
241          for (i = 0; i < CCS_MAX_HASH; i++)          for (idx = 0; idx < CCS_MAX_HASH; idx++)
242                  INIT_LIST_HEAD(&ccs_name_list[i]);                  INIT_LIST_HEAD(&ccs_name_list[idx]);
243            INIT_LIST_HEAD(&ccs_global_domain.acl_info_list);
244          INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);          INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
245          ccs_kernel_domain.domainname = ccs_get_name(ROOT_NAME);          ccs_kernel_domain.domainname = ccs_get_name(CCS_ROOT_NAME);
246          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
247          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)          idx = ccs_read_lock();
248            if (ccs_find_domain(CCS_ROOT_NAME) != &ccs_kernel_domain)
249                  panic("Can't register ccs_kernel_domain");                  panic("Can't register ccs_kernel_domain");
250          {          {
251                  /* Load built-in policy. */                  /* Load built-in policy. */
# Line 197  static int __init ccs_mm_init(void) Line 257  static int __init ccs_mm_init(void)
257                          char *cp2 = strchr(cp, ' ');                          char *cp2 = strchr(cp, ' ');
258                          if (cp2)                          if (cp2)
259                                  *cp2++ = '\0';                                  *cp2++ = '\0';
260                          ccs_write_domain_initializer_policy(cp, false, false);                          ccs_write_domain_initializer(cp, false, false);
261                          cp = cp2;                          cp = cp2;
262                  }                  }
263          }          }
264          return 0;          ccs_read_unlock(idx);
265  }  }
266    
267  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)  /* Memory allocated for audit logs. */
268  __initcall(ccs_mm_init);  unsigned int ccs_log_memory_size;
269  #else  /* Quota for holding audit logs. */
270  core_initcall(ccs_mm_init);  unsigned int ccs_quota_for_log;
 #endif  
   
 unsigned int ccs_audit_log_memory_size;  
 unsigned int ccs_quota_for_audit_log;  
271    
272    /* Memory allocated for query lists. */
273  unsigned int ccs_query_memory_size;  unsigned int ccs_query_memory_size;
274    /* Quota for holding query lists. */
275  unsigned int ccs_quota_for_query;  unsigned int ccs_quota_for_query;
276    
277  /**  /**
# Line 225  void ccs_read_memory_counter(struct ccs_ Line 283  void ccs_read_memory_counter(struct ccs_
283  {  {
284          const unsigned int usage[3] = {          const unsigned int usage[3] = {
285                  atomic_read(&ccs_policy_memory_size),                  atomic_read(&ccs_policy_memory_size),
286                  ccs_audit_log_memory_size,                  ccs_log_memory_size,
287                  ccs_query_memory_size                  ccs_query_memory_size
288          };          };
289          const unsigned int quota[3] = {          const unsigned int quota[3] = {
290                  ccs_quota_for_policy,                  ccs_quota_for_policy,
291                  ccs_quota_for_audit_log,                  ccs_quota_for_log,
292                  ccs_quota_for_query                  ccs_quota_for_query
293          };          };
294          static const char *header[4] = {          static const char *header[4] = {
# Line 268  int ccs_write_memory_quota(struct ccs_io Line 326  int ccs_write_memory_quota(struct ccs_io
326          if (sscanf(data, "Policy: %u", &size) == 1)          if (sscanf(data, "Policy: %u", &size) == 1)
327                  ccs_quota_for_policy = size;                  ccs_quota_for_policy = size;
328          else if (sscanf(data, "Audit logs: %u", &size) == 1)          else if (sscanf(data, "Audit logs: %u", &size) == 1)
329                  ccs_quota_for_audit_log = size;                  ccs_quota_for_log = size;
330          else if (sscanf(data, "Query lists: %u", &size) == 1)          else if (sscanf(data, "Query lists: %u", &size) == 1)
331                  ccs_quota_for_query = size;                  ccs_quota_for_query = size;
332          return 0;          return 0;

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

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