From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965954AbdACUvT (ORCPT ); Tue, 3 Jan 2017 15:51:19 -0500 Received: from frisell.zx2c4.com ([192.95.5.64]:38227 "EHLO frisell.zx2c4.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761242AbdACUvH (ORCPT ); Tue, 3 Jan 2017 15:51:07 -0500 From: "Jason A. Donenfeld" To: gregkh@linuxfoundation.org, LKML Cc: "Jason A. Donenfeld" , Robin Murphy , Kefeng Wang Subject: [PATCH] Revert "drivers: char: mem: Check {read,write}_kmem() addresses" Date: Tue, 3 Jan 2017 21:50:52 +0100 Message-Id: <20170103205052.30517-1-Jason@zx2c4.com> X-Mailer: git-send-email 2.11.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This reverts commit 148a1bc84398039e2b96ff78678c4d9a67f81452. This commit was intended to fix a problem, but it did not do so correctly, resulting in /dev/kmem being entirely broken. So, revert this commit until a different solution is found. The following PoC shows breakage bisecting to this commit. On working systems, it returns 0 and prints the last message. On broken systems containing this commit, it exits returning EIO. #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd, sock; FILE *f; char line[256], *ptr; unsigned long addr = 0; struct sockaddr_in saddr = { .sin_family = AF_INET, .sin_port = 55193 }; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("socket"); return errno; } if (bind(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); return errno; } f = fopen("/proc/net/udp", "r"); if (!f) { perror("fopen(/proc/net/udp)"); return errno; } if (!fgets(line, 256, f) || !fgets(line, 256, f)) { perror("fgets"); return errno; } fclose(f); ptr = line + strlen(line) - 1; while (*--ptr == ' '); while (*--ptr != ' '); while (*(--ptr - 1) != ' '); addr = strtoul(ptr, NULL, 16); printf("Attempting to read from skbuff at 0x%lx\n", addr); fd = open("/dev/kmem", O_RDONLY); if (fd < 0) { perror("open(/dev/kmem)"); return errno; } if (lseek(fd, addr, SEEK_SET) == (off_t)-1) { perror("lseek"); return errno; } if (read(fd, &addr, sizeof(addr)) != sizeof(addr)) { perror("read"); return errno; } printf("It worked, reading the value %lx!\n", addr); close(fd); close(sock); return 0; } Signed-off-by: Jason A. Donenfeld Cc: Robin Murphy Cc: Kefeng Wang Cc: Greg Kroah-Hartman --- drivers/char/mem.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 5bb1985ec484..a33163dbb913 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -381,9 +381,6 @@ static ssize_t read_kmem(struct file *file, char __user *buf, char *kbuf; /* k-addr because vread() takes vmlist_lock rwlock */ int err = 0; - if (!pfn_valid(PFN_DOWN(p))) - return -EIO; - read = 0; if (p < (unsigned long) high_memory) { low_count = count; @@ -512,9 +509,6 @@ static ssize_t write_kmem(struct file *file, const char __user *buf, char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ int err = 0; - if (!pfn_valid(PFN_DOWN(p))) - return -EIO; - if (p < (unsigned long) high_memory) { unsigned long to_write = min_t(unsigned long, count, (unsigned long)high_memory - p); -- 2.11.0