diff options
-rw-r--r-- | security/selinux/selinuxfs.c | 37 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 3 |
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 | ||
755 | static 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 | |||
754 | static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | 763 | static 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) |