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

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 trunk/1.8.x/ccs-patch/security/ccsecurity/memory.c revision 3875 by kumaneko, Sun Aug 1 11:39:42 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.8.0-pre   2010/08/01
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            for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++)
244                    INIT_LIST_HEAD(&ccs_acl_group[idx].acl_info_list);
245          INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);          INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
246          ccs_kernel_domain.domainname = ccs_get_name(ROOT_NAME);          ccs_kernel_domain.domainname = ccs_get_name(CCS_ROOT_NAME);
247          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
248          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)          idx = ccs_read_lock();
249            if (ccs_find_domain(CCS_ROOT_NAME) != &ccs_kernel_domain)
250                  panic("Can't register ccs_kernel_domain");                  panic("Can't register ccs_kernel_domain");
251          {          {
252                  /* Load built-in policy. */                  /* Load built-in policy. */
# Line 197  static int __init ccs_mm_init(void) Line 258  static int __init ccs_mm_init(void)
258                          char *cp2 = strchr(cp, ' ');                          char *cp2 = strchr(cp, ' ');
259                          if (cp2)                          if (cp2)
260                                  *cp2++ = '\0';                                  *cp2++ = '\0';
261                          ccs_write_domain_initializer_policy(cp, false, false);                          ccs_write_transition_control(cp, false,
262                                         CCS_TRANSITION_CONTROL_INITIALIZE);
263                          cp = cp2;                          cp = cp2;
264                  }                  }
265          }          }
266          return 0;          ccs_read_unlock(idx);
267  }  }
268    
269  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)  /* Memory allocated for audit logs. */
270  __initcall(ccs_mm_init);  unsigned int ccs_log_memory_size;
271  #else  /* Quota for holding audit logs. */
272  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;  
273    
274    /* Memory allocated for query lists. */
275  unsigned int ccs_query_memory_size;  unsigned int ccs_query_memory_size;
276    /* Quota for holding query lists. */
277  unsigned int ccs_quota_for_query;  unsigned int ccs_quota_for_query;
278    
279  /**  /**
# Line 225  void ccs_read_memory_counter(struct ccs_ Line 285  void ccs_read_memory_counter(struct ccs_
285  {  {
286          const unsigned int usage[3] = {          const unsigned int usage[3] = {
287                  atomic_read(&ccs_policy_memory_size),                  atomic_read(&ccs_policy_memory_size),
288                  ccs_audit_log_memory_size,                  ccs_log_memory_size,
289                  ccs_query_memory_size                  ccs_query_memory_size
290          };          };
291          const unsigned int quota[3] = {          const unsigned int quota[3] = {
292                  ccs_quota_for_policy,                  ccs_quota_for_policy,
293                  ccs_quota_for_audit_log,                  ccs_quota_for_log,
294                  ccs_quota_for_query                  ccs_quota_for_query
295          };          };
296          static const char *header[4] = {          static const char *header[4] = {
# Line 241  void ccs_read_memory_counter(struct ccs_ Line 301  void ccs_read_memory_counter(struct ccs_
301          };          };
302          unsigned int total = 0;          unsigned int total = 0;
303          int i;          int i;
304          if (head->read_eof)          if (head->r.eof)
305                  return;                  return;
306          for (i = 0; i < 3; i++) {          for (i = 0; i < 3; i++) {
307                  total += usage[i];                  total += usage[i];
# Line 251  void ccs_read_memory_counter(struct ccs_ Line 311  void ccs_read_memory_counter(struct ccs_
311                  ccs_io_printf(head, "\n");                  ccs_io_printf(head, "\n");
312          }          }
313          ccs_io_printf(head, "%s %10u\n", header[3], total);          ccs_io_printf(head, "%s %10u\n", header[3], total);
314          head->read_eof = true;          head->r.eof = true;
315  }  }
316    
317  /**  /**
# Line 268  int ccs_write_memory_quota(struct ccs_io Line 328  int ccs_write_memory_quota(struct ccs_io
328          if (sscanf(data, "Policy: %u", &size) == 1)          if (sscanf(data, "Policy: %u", &size) == 1)
329                  ccs_quota_for_policy = size;                  ccs_quota_for_policy = size;
330          else if (sscanf(data, "Audit logs: %u", &size) == 1)          else if (sscanf(data, "Audit logs: %u", &size) == 1)
331                  ccs_quota_for_audit_log = size;                  ccs_quota_for_log = size;
332          else if (sscanf(data, "Query lists: %u", &size) == 1)          else if (sscanf(data, "Query lists: %u", &size) == 1)
333                  ccs_quota_for_query = size;                  ccs_quota_for_query = size;
334          return 0;          return 0;

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

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