Merge branch 'for-linus' of git://git.infradead.org/users/eparis/selinux into for...
authorJames Morris <jmorris@namei.org>
Tue, 14 Jun 2011 23:41:48 +0000 (09:41 +1000)
committerJames Morris <jmorris@namei.org>
Tue, 14 Jun 2011 23:41:48 +0000 (09:41 +1000)
1  2 
security/selinux/selinuxfs.c

index 77d44138864fd5862a180c5907a81c2a52f1b6ab,19489042fdf7ee6a68b35f67b7698366379153c8..35459340019e44399775c2f96aa9b5871f8d566c
@@@ -29,6 -29,7 +29,7 @@@
  #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. */
@@@ -281,7 -282,7 +282,7 @@@ static ssize_t sel_write_disable(struc
  
        length = -ENOMEM;
        if (count >= PAGE_SIZE)
 -              goto out;;
 +              goto out;
  
        /* No partial writes. */
        length = -EINVAL;
@@@ -751,6 -752,14 +752,14 @@@ out
        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)
@@@ -889,12 -924,12 +924,12 @@@ static ssize_t sel_write_user(struct fi
  
        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);
@@@ -954,7 -989,7 +989,7 @@@ static ssize_t sel_write_member(struct 
        length = -ENOMEM;
        scon = kzalloc(size + 1, GFP_KERNEL);
        if (!scon)
 -              goto out;;
 +              goto out;
  
        length = -ENOMEM;
        tcon = kzalloc(size + 1, GFP_KERNEL);
@@@ -1393,14 -1428,10 +1428,14 @@@ static int sel_avc_stats_seq_show(struc
        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;
  }