printk: prevent userland from spoofing kernel messages
[firefly-linux-kernel-4.4.55.git] / kernel / printk / printk.c
index b16f35487b67985275169cc0bbaa4efc6cce171d..2ce8826f1053d801f0b003f5a3e67de0fdfe8e30 100644 (file)
@@ -269,6 +269,9 @@ static u32 clear_idx;
 #define PREFIX_MAX             32
 #define LOG_LINE_MAX           (1024 - PREFIX_MAX)
 
+#define LOG_LEVEL(v)           ((v) & 0x07)
+#define LOG_FACILITY(v)                ((v) >> 3 & 0xff)
+
 /* record buffer */
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
 #define LOG_ALIGN 4
@@ -612,7 +615,6 @@ struct devkmsg_user {
 static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
 {
        char *buf, *line;
-       int i;
        int level = default_message_loglevel;
        int facility = 1;       /* LOG_USER */
        size_t len = iov_iter_count(from);
@@ -642,12 +644,13 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
        line = buf;
        if (line[0] == '<') {
                char *endp = NULL;
+               unsigned int u;
 
-               i = simple_strtoul(line+1, &endp, 10);
+               u = simple_strtoul(line + 1, &endp, 10);
                if (endp && endp[0] == '>') {
-                       level = i & 7;
-                       if (i >> 3)
-                               facility = i >> 3;
+                       level = LOG_LEVEL(u);
+                       if (LOG_FACILITY(u) != 0)
+                               facility = LOG_FACILITY(u);
                        endp++;
                        len -= endp - line;
                        line = endp;