diff options
Diffstat (limited to 'security/smack')
-rw-r--r-- | security/smack/smack_lsm.c | 2 | ||||
-rw-r--r-- | security/smack/smackfs.c | 29 |
2 files changed, 26 insertions, 5 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 716433e63052..d37c1963e8ca 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1513,8 +1513,6 @@ static int smack_inode_getsecurity(const struct inode *inode, * @inode: the object * @buffer: where they go * @buffer_size: size of buffer - * - * Returns 0 on success, -EINVAL otherwise */ static int smack_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 94bd9e41c9ec..df082648eb0a 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -912,11 +912,21 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, else rule += strlen(skp->smk_known) + 1; + if (rule > data + count) { + rc = -EOVERFLOW; + goto out; + } + ret = sscanf(rule, "%d", &maplevel); - if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) + if (ret != 1 || maplevel < 0 || maplevel > SMACK_CIPSO_MAXLEVEL) goto out; rule += SMK_DIGITLEN; + if (rule > data + count) { + rc = -EOVERFLOW; + goto out; + } + ret = sscanf(rule, "%d", &catlen); if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) goto out; @@ -929,6 +939,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, for (i = 0; i < catlen; i++) { rule += SMK_DIGITLEN; + if (rule > data + count) { + rc = -EOVERFLOW; + goto out; + } ret = sscanf(rule, "%u", &cat); if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM) goto out; @@ -2781,7 +2795,6 @@ static int smk_open_relabel_self(struct inode *inode, struct file *file) static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct task_smack *tsp = current_security(); char *data; int rc; LIST_HEAD(list_tmp); @@ -2811,11 +2824,21 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf, kfree(data); if (!rc || (rc == -EINVAL && list_empty(&list_tmp))) { + struct cred *new; + struct task_smack *tsp; + + new = prepare_creds(); + if (!new) { + rc = -ENOMEM; + goto out; + } + tsp = new->security; smk_destroy_label_list(&tsp->smk_relabel); list_splice(&list_tmp, &tsp->smk_relabel); + commit_creds(new); return count; } - +out: smk_destroy_label_list(&list_tmp); return rc; } |