int mls_read_perm(struct perm_datum *perdatum, void *fp)
{
- u32 *buf;
+ u32 buf[1];
+ int rc;
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
return -EINVAL;
perdatum->base_perms = le32_to_cpu(buf[0]);
return 0;
struct mls_level *mls_read_level(void *fp)
{
struct mls_level *l;
- u32 *buf;
+ u32 buf[1];
+ int rc;
l = kmalloc(sizeof(*l), GFP_ATOMIC);
if (!l) {
}
memset(l, 0, sizeof(*l));
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0) {
printk(KERN_ERR "security: mls: truncated level\n");
goto bad;
}
*/
static int mls_read_range_helper(struct mls_range *r, void *fp)
{
- u32 *buf;
- int items, rc = -EINVAL;
+ u32 buf[2], items;
+ int rc;
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto out;
items = le32_to_cpu(buf[0]);
- buf = next_entry(fp, sizeof(u32) * items);
- if (!buf) {
+ if (items > ARRAY_SIZE(buf)) {
+ printk(KERN_ERR "security: mls: range overflow\n");
+ rc = -EINVAL;
+ goto out;
+ }
+ rc = next_entry(buf, fp, sizeof(u32) * items);
+ if (rc < 0) {
printk(KERN_ERR "security: mls: truncated range\n");
goto out;
}
int mls_read_class(struct class_datum *cladatum, void *fp)
{
struct mls_perms *p = &cladatum->mlsperms;
- u32 *buf;
+ u32 buf[4];
+ int rc;
- buf = next_entry(fp, sizeof(u32)*4);
- if (!buf) {
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0) {
printk(KERN_ERR "security: mls: truncated mls permissions\n");
return -EINVAL;
}
int mls_read_user(struct user_datum *usrdatum, void *fp)
{
struct mls_range_list *r, *l;
- int rc = 0;
+ int rc;
u32 nel, i;
- u32 *buf;
+ u32 buf[1];
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto out;
- }
nel = le32_to_cpu(buf[0]);
l = NULL;
for (i = 0; i < nel; i++) {
int mls_read_nlevels(struct policydb *p, void *fp)
{
- u32 *buf;
+ u32 buf[1];
+ int rc;
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
return -EINVAL;
p->nlevels = le32_to_cpu(buf[0]);
return 0;
char *key = NULL;
struct level_datum *levdatum;
int rc;
- u32 *buf, len;
+ u32 buf[2], len;
levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
if (!levdatum) {
}
memset(levdatum, 0, sizeof(*levdatum));
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
levdatum->isalias = le32_to_cpu(buf[1]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_ATOMIC);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
levdatum->level = mls_read_level(fp);
char *key = NULL;
struct cat_datum *catdatum;
int rc;
- u32 *buf, len;
+ u32 buf[3], len;
catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
if (!catdatum) {
}
memset(catdatum, 0, sizeof(*catdatum));
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
catdatum->value = le32_to_cpu(buf[1]);
catdatum->isalias = le32_to_cpu(buf[2]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_ATOMIC);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
rc = hashtab_insert(h, key, catdatum);