]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - lib/vsprintf.c
bcm2835-v4l2: Fix buffer overflow problem
[mirror_ubuntu-zesty-kernel.git] / lib / vsprintf.c
index ccb664b54280755779237e213a2c3c8fe1021c89..f51765a7fc5b6355b1647ac43e19b020aad535ad 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/dcache.h>
 #include <linux/cred.h>
+#include <linux/uuid.h>
 #include <net/addrconf.h>
 #ifdef CONFIG_BLOCK
 #include <linux/blkdev.h>
@@ -1304,19 +1305,17 @@ static noinline_for_stack
 char *uuid_string(char *buf, char *end, const u8 *addr,
                  struct printf_spec spec, const char *fmt)
 {
-       char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
+       char uuid[UUID_STRING_LEN + 1];
        char *p = uuid;
        int i;
-       static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
-       static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
-       const u8 *index = be;
+       const u8 *index = uuid_be_index;
        bool uc = false;
 
        switch (*(++fmt)) {
        case 'L':
                uc = true;              /* fall-through */
        case 'l':
-               index = le;
+               index = uuid_le_index;
                break;
        case 'B':
                uc = true;
@@ -1324,7 +1323,10 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
        }
 
        for (i = 0; i < 16; i++) {
-               p = hex_byte_pack(p, addr[index[i]]);
+               if (uc)
+                       p = hex_byte_pack_upper(p, addr[index[i]]);
+               else
+                       p = hex_byte_pack(p, addr[index[i]]);
                switch (i) {
                case 3:
                case 5:
@@ -1337,13 +1339,6 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
 
        *p = 0;
 
-       if (uc) {
-               p = uuid;
-               do {
-                       *p = toupper(*p);
-               } while (*(++p));
-       }
-
        return string(buf, end, uuid, spec);
 }
 
@@ -1475,6 +1470,29 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt)
        return format_flags(buf, end, flags, names);
 }
 
+#ifdef CONFIG_KMSG_IDS
+
+unsigned long long __jhash_string(const char *str);
+
+static noinline_for_stack
+char *jhash_string(char *buf, char *end, const char *str, const char *fmt)
+{
+       struct printf_spec spec;
+       unsigned long long num;
+
+       num = __jhash_string(str);
+
+       spec.type = FORMAT_TYPE_PTR;
+       spec.field_width = 6;
+       spec.flags = SMALL | ZEROPAD;
+       spec.base = 16;
+       spec.precision = -1;
+
+       return number(buf, end, num, spec);
+}
+
+#endif
+
 int kptr_restrict __read_mostly;
 
 /*
@@ -1568,6 +1586,7 @@ int kptr_restrict __read_mostly;
  *       p page flags (see struct page) given as pointer to unsigned long
  *       g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t
  *       v vma flags (VM_*) given as pointer to unsigned long
+ * - 'j' Kernel message catalog jhash for System z
  *
  * ** Please update also Documentation/printk-formats.txt when making changes **
  *
@@ -1723,6 +1742,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 
        case 'G':
                return flags_string(buf, end, ptr, fmt);
+#ifdef CONFIG_KMSG_IDS
+       case 'j':
+               return jhash_string(buf, end, ptr, fmt);
+#endif
        }
        spec.flags |= SMALL;
        if (spec.field_width == -1) {