#include "security.h"
#include "conditional.h"
+#include "policydb.h"
#include "services.h"
/*
if (len == 0)
return 0;
+ /* avtab_read_item() reads at least 96 bytes for any valid entry */
+ rc = size_check(3 * sizeof(u32), len, fp);
+ if (rc)
+ return rc;
+
list->nodes = kzalloc_objs(*list->nodes, len);
if (!list->nodes)
return -ENOMEM;
/* expr */
len = le32_to_cpu(buf[1]);
+
+ /* we will read 64 bytes per node */
+ rc = size_check(2 * sizeof(u32), len, fp);
+ if (rc)
+ return rc;
+
node->expr.nodes = kzalloc_objs(*node->expr.nodes, len);
if (!node->expr.nodes)
return -ENOMEM;
len = le32_to_cpu(buf[0]);
+ /* cond_read_node() reads at least 128 bytes for any valid node */
+ rc = size_check(4 * sizeof(u32), len, fp);
+ if (rc)
+ return rc;
+
p->cond_list = kzalloc_objs(*p->cond_list, len);
if (!p->cond_list)
return -ENOMEM;
if ((len == 0) || (len == (u32)-1))
return -EINVAL;
+ if (size_check(sizeof(char), len, fp))
+ return -EINVAL;
+
str = kmalloc(len + 1, flags | __GFP_NOWARN);
if (!str)
return -ENOMEM;
if (nel > SEL_VEC_MAX)
goto bad;
+ /* perm_read() reads at least 64 bytes for any valid permission */
+ rc = size_check(2 * sizeof(u32), nel, fp);
+ if (rc)
+ goto bad;
+
rc = symtab_init(&comdatum->permissions, nel);
if (rc)
goto bad;
goto bad;
cladatum->value = val;
+ /* perm_read() reads at least 64 bytes for any valid permission */
+ rc = size_check(2 * sizeof(u32), nel, fp);
+ if (rc)
+ goto bad;
+
rc = symtab_init(&cladatum->permissions, nel);
if (rc)
goto bad;
nel = le32_to_cpu(buf[0]);
+ /* we read at least 64 bytes and mls_read_range_helper() 32 bytes
+ * for any valid range-transition
+ */
+ rc = size_check(3 * sizeof(u32), nel, fp);
+ if (rc)
+ return rc;
+
rc = hashtab_init(&p->range_tr, nel);
if (rc)
return rc;
nprim = le32_to_cpu(buf[0]);
nel = le32_to_cpu(buf[1]);
+ /* every read_f() implementation reads at least 128 bytes
+ * for any valid entry
+ */
+ rc = size_check(4 * sizeof(u32), nel, fp);
+ if (rc)
+ goto out;
+
rc = symtab_init(&p->symtab[i], nel);
if (rc)
goto out;
goto bad;
nel = le32_to_cpu(buf[0]);
+ /* we read at least 96 bytes for any valid role-transition */
+ rc = size_check(3 * sizeof(u32), nel, fp);
+ if (rc)
+ goto bad;
+
rc = hashtab_init(&p->role_tr, nel);
if (rc)
goto bad;
struct policy_file *fp;
};
+static inline int size_check(size_t bytes, size_t num,
+ const struct policy_file *fp)
+{
+ size_t len;
+
+ if (unlikely(check_mul_overflow(bytes, num, &len)))
+ return -EINVAL;
+
+ if (unlikely(len > fp->len))
+ return -EINVAL;
+
+ return 0;
+}
+
static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
{
if (bytes > fp->len)