#include <linux/audit.h>
#include <linux/uaccess.h>
#include <linux/kobject.h>
+ #include <linux/ctype.h>
/* selinuxfs pseudo filesystem for exporting the security policy API.
Based on the proc code and the fs/nfsd/nfsctl.c code. */
length = -ENOMEM;
if (count >= PAGE_SIZE)
- goto out;;
+ goto out;
/* No partial writes. */
length = -EINVAL;
return length;
}
+ static inline int hexcode_to_int(int code) {
+ if (code == '\0' || !isxdigit(code))
+ return -1;
+ if (isdigit(code))
+ return code - '0';
+ return tolower(code) - 'a' + 10;
+ }
+
static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{
char *scon = NULL, *tcon = NULL;
nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
if (nargs < 3 || nargs > 4)
goto out;
- if (nargs == 4)
+ if (nargs == 4) {
+ /*
+ * If and when the name of new object to be queried contains
+ * either whitespace or multibyte characters, they shall be
+ * encoded based on the percentage-encoding rule.
+ * If not encoded, the sscanf logic picks up only left-half
+ * of the supplied name; splitted by a whitespace unexpectedly.
+ */
+ char *r, *w;
+ int c1, c2;
+
+ r = w = namebuf;
+ do {
+ c1 = *r++;
+ if (c1 == '+')
+ c1 = ' ';
+ else if (c1 == '%') {
+ if ((c1 = hexcode_to_int(*r++)) < 0)
+ goto out;
+ if ((c2 = hexcode_to_int(*r++)) < 0)
+ goto out;
+ c1 = (c1 << 4) | c2;
+ }
+ *w++ = c1;
+ } while (c1 != '\0');
+
objname = namebuf;
+ }
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
if (length)
length = task_has_security(current, SECURITY__COMPUTE_USER);
if (length)
- goto out;;
+ goto out;
length = -ENOMEM;
con = kzalloc(size + 1, GFP_KERNEL);
if (!con)
- goto out;;
+ goto out;
length = -ENOMEM;
user = kzalloc(size + 1, GFP_KERNEL);
length = -ENOMEM;
scon = kzalloc(size + 1, GFP_KERNEL);
if (!scon)
- goto out;;
+ goto out;
length = -ENOMEM;
tcon = kzalloc(size + 1, GFP_KERNEL);
if (v == SEQ_START_TOKEN)
seq_printf(seq, "lookups hits misses allocations reclaims "
"frees\n");
- else
- seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups,
- st->hits, st->misses, st->allocations,
+ else {
+ unsigned int lookups = st->lookups;
+ unsigned int misses = st->misses;
+ unsigned int hits = lookups - misses;
+ seq_printf(seq, "%u %u %u %u %u %u\n", lookups,
+ hits, misses, st->allocations,
st->reclaims, st->frees);
+ }
return 0;
}