FAILED: patch "[PATCH] printk: prevent userland from spoofing kernel messages" failed to apply to 3.14-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 3.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
3824657c522f19f85a76bd932821174a5557a382Mon Sep 17 00:00:00 2001
From: Mathias Krause <[email protected]>
Date: Fri, 6 Nov 2015 16:30:38 -0800
Subject: [PATCH] printk: prevent userland from spoofing kernel messages
The following statement of ABI/testing/dev-kmsg is not quite right:
It is not possible to inject messages from userspace with the facility number LOG_KERN (0), to make sure that the origin of the messages can always be reliably determined.
Userland actually can inject messages with a facility of 0 by abusing the fact that the facility is stored in a u8 data type. By using a facility which is a multiple of 256 the assignment of msg->facility in log_store() implicitly truncates it to 0, i.e. LOG_KERN, allowing users of /dev/kmsg to spoof kernel messages as shown below:
The following call...
# printf '<%d>Kernel panic - not syncing: beer empty\n' 0 >/dev/kmsg ...leads to the following log entry (dmesg -x | tail -n 1): user :emerg : [ 66.137758] Kernel panic - not syncing: beer empty
However, this call...
# printf '<%d>Kernel panic - not syncing: beer empty\n' 0x800 >/dev/kmsg ...leads to the slightly different log entry (note the kernel facility): kern :emerg : [ 74.177343] Kernel panic - not syncing: beer empty
Fix that by limiting the user provided facility to 8 bit right from the beginning and catch the truncation early.
kernel/printk/printk.c +8 -5
@@ -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;