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

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 3512 by kumaneko, Fri Mar 19 08:37:22 2010 UTC trunk/1.8.x/ccs-patch/security/ccsecurity/memory.c revision 3924 by kumaneko, Thu Aug 26 11:01:19 2010 UTC
# Line 3  Line 3 
3   *   *
4   * Copyright (C) 2005-2010  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.2-pre   2010/03/08   * 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 15  Line 15 
15  #include <linux/hash.h>  #include <linux/hash.h>
16  #endif  #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 29  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 65  bool ccs_memory_ok(const void *ptr, cons Line 72  bool ccs_memory_ok(const void *ptr, cons
72  void *ccs_commit_ok(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);          void *ptr = kmalloc(size, CCS_GFP_FLAGS);
         if (!ptr)  
                 return NULL;  
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);
# Line 76  void *ccs_commit_ok(void *data, const un Line 81  void *ccs_commit_ok(void *data, const un
81          return NULL;          return NULL;
82  }  }
83    
   
84  /**  /**
85   * ccs_memory_free - Free memory for elements.   * ccs_memory_free - Free memory for elements.
86   *   *
# Line 89  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 102  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), CCS_GFP_FLAGS);          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 141  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;
# Line 156  const struct ccs_path_info *ccs_get_name Line 206  const struct ccs_path_info *ccs_get_name
206  #else  #else
207          head = &ccs_name_list[hash % CCS_MAX_HASH];          head = &ccs_name_list[hash % CCS_MAX_HASH];
208  #endif  #endif
209          mutex_lock(&ccs_name_list_lock);          if (mutex_lock_interruptible(&ccs_policy_lock))
210          list_for_each_entry(ptr, head, list) {                  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, CCS_GFP_FLAGS);          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, head);  
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    
# Line 190  const struct ccs_path_info *ccs_get_name Line 237  const struct ccs_path_info *ccs_get_name
237   */   */
238  void __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_kernel_domain.acl_info_list);          for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++) {
244          ccs_kernel_domain.domainname = ccs_get_name(ROOT_NAME);                  INIT_LIST_HEAD(&ccs_acl_group[idx].acl_info_list[0]);
245                    INIT_LIST_HEAD(&ccs_acl_group[idx].acl_info_list[1]);
246            }
247            INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list[0]);
248            INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list[1]);
249            ccs_kernel_domain.domainname = ccs_get_name(CCS_ROOT_NAME);
250          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);          list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
251          if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)          idx = ccs_read_lock();
252            if (ccs_find_domain(CCS_ROOT_NAME) != &ccs_kernel_domain)
253                  panic("Can't register ccs_kernel_domain");                  panic("Can't register ccs_kernel_domain");
254          {          {
255                  /* Load built-in policy. */                  /* Load built-in policy. */
# Line 208  void __init ccs_mm_init(void) Line 261  void __init ccs_mm_init(void)
261                          char *cp2 = strchr(cp, ' ');                          char *cp2 = strchr(cp, ' ');
262                          if (cp2)                          if (cp2)
263                                  *cp2++ = '\0';                                  *cp2++ = '\0';
264                          ccs_write_domain_initializer_policy(cp, false, false);                          ccs_write_transition_control(cp, false,
265                                         CCS_TRANSITION_CONTROL_INITIALIZE);
266                          cp = cp2;                          cp = cp2;
267                  }                  }
268          }          }
269            ccs_read_unlock(idx);
270  }  }
271    
272  unsigned int ccs_audit_log_memory_size;  /* Memory allocated for audit logs. */
273  unsigned int ccs_quota_for_audit_log;  unsigned int ccs_log_memory_size;
274    /* Quota for holding audit logs. */
275    unsigned int ccs_quota_for_log;
276    
277    /* Memory allocated for query lists. */
278  unsigned int ccs_query_memory_size;  unsigned int ccs_query_memory_size;
279    /* Quota for holding query lists. */
280  unsigned int ccs_quota_for_query;  unsigned int ccs_quota_for_query;
281    
282  /**  /**
# Line 229  void ccs_read_memory_counter(struct ccs_ Line 288  void ccs_read_memory_counter(struct ccs_
288  {  {
289          const unsigned int usage[3] = {          const unsigned int usage[3] = {
290                  atomic_read(&ccs_policy_memory_size),                  atomic_read(&ccs_policy_memory_size),
291                  ccs_audit_log_memory_size,                  ccs_log_memory_size,
292                  ccs_query_memory_size                  ccs_query_memory_size
293          };          };
294          const unsigned int quota[3] = {          const unsigned int quota[3] = {
295                  ccs_quota_for_policy,                  ccs_quota_for_policy,
296                  ccs_quota_for_audit_log,                  ccs_quota_for_log,
297                  ccs_quota_for_query                  ccs_quota_for_query
298          };          };
299          static const char *header[4] = {          static const char *header[4] = {
# Line 245  void ccs_read_memory_counter(struct ccs_ Line 304  void ccs_read_memory_counter(struct ccs_
304          };          };
305          unsigned int total = 0;          unsigned int total = 0;
306          int i;          int i;
307          if (head->read_eof)          if (head->r.eof)
308                  return;                  return;
309          for (i = 0; i < 3; i++) {          for (i = 0; i < 3; i++) {
310                  total += usage[i];                  total += usage[i];
# Line 255  void ccs_read_memory_counter(struct ccs_ Line 314  void ccs_read_memory_counter(struct ccs_
314                  ccs_io_printf(head, "\n");                  ccs_io_printf(head, "\n");
315          }          }
316          ccs_io_printf(head, "%s %10u\n", header[3], total);          ccs_io_printf(head, "%s %10u\n", header[3], total);
317          head->read_eof = true;          head->r.eof = true;
318  }  }
319    
320  /**  /**
# Line 272  int ccs_write_memory_quota(struct ccs_io Line 331  int ccs_write_memory_quota(struct ccs_io
331          if (sscanf(data, "Policy: %u", &size) == 1)          if (sscanf(data, "Policy: %u", &size) == 1)
332                  ccs_quota_for_policy = size;                  ccs_quota_for_policy = size;
333          else if (sscanf(data, "Audit logs: %u", &size) == 1)          else if (sscanf(data, "Audit logs: %u", &size) == 1)
334                  ccs_quota_for_audit_log = size;                  ccs_quota_for_log = size;
335          else if (sscanf(data, "Query lists: %u", &size) == 1)          else if (sscanf(data, "Query lists: %u", &size) == 1)
336                  ccs_quota_for_query = size;                  ccs_quota_for_query = size;
337          return 0;          return 0;

Legend:
Removed from v.3512  
changed lines
  Added in v.3924

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