aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/selinuxfs.c37
-rw-r--r--security/selinux/ss/policydb.c3
2 files changed, 39 insertions, 1 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 77d44138864f..35459340019e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -29,6 +29,7 @@
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/kobject.h> 31#include <linux/kobject.h>
32#include <linux/ctype.h>
32 33
33/* selinuxfs pseudo filesystem for exporting the security policy API. 34/* selinuxfs pseudo filesystem for exporting the security policy API.
34 Based on the proc code and the fs/nfsd/nfsctl.c code. */ 35 Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -751,6 +752,14 @@ out:
751 return length; 752 return length;
752} 753}
753 754
755static inline int hexcode_to_int(int code) {
756 if (code == '\0' || !isxdigit(code))
757 return -1;
758 if (isdigit(code))
759 return code - '0';
760 return tolower(code) - 'a' + 10;
761}
762
754static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 763static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
755{ 764{
756 char *scon = NULL, *tcon = NULL; 765 char *scon = NULL, *tcon = NULL;
@@ -785,8 +794,34 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
785 nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf); 794 nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
786 if (nargs < 3 || nargs > 4) 795 if (nargs < 3 || nargs > 4)
787 goto out; 796 goto out;
788 if (nargs == 4) 797 if (nargs == 4) {
798 /*
799 * If and when the name of new object to be queried contains
800 * either whitespace or multibyte characters, they shall be
801 * encoded based on the percentage-encoding rule.
802 * If not encoded, the sscanf logic picks up only left-half
803 * of the supplied name; splitted by a whitespace unexpectedly.
804 */
805 char *r, *w;
806 int c1, c2;
807
808 r = w = namebuf;
809 do {
810 c1 = *r++;
811 if (c1 == '+')
812 c1 = ' ';
813 else if (c1 == '%') {
814 if ((c1 = hexcode_to_int(*r++)) < 0)
815 goto out;
816 if ((c2 = hexcode_to_int(*r++)) < 0)
817 goto out;
818 c1 = (c1 << 4) | c2;
819 }
820 *w++ = c1;
821 } while (c1 != '\0');
822
789 objname = namebuf; 823 objname = namebuf;
824 }
790 825
791 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 826 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
792 if (length) 827 if (length)
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 102e9ec1b77a..d246aca3f4fb 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3222,6 +3222,9 @@ static int filename_trans_write(struct policydb *p, void *fp)
3222 __le32 buf[1]; 3222 __le32 buf[1];
3223 int rc; 3223 int rc;
3224 3224
3225 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
3226 return 0;
3227
3225 nel = 0; 3228 nel = 0;
3226 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel); 3229 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3227 if (rc) 3230 if (rc)