From 7bdd9695970eb8cd5b987e08f99cb8f0c84f30fd Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Wed, 24 Jul 2019 17:04:26 +0800 Subject: char: ppdev: Fix a possible null-pointer dereference in pp_release() In pp_release(), there is an if statement on line 730 to check whether pp->pdev is NULL: else if ((pp->flags & PP_CLAIMED) && pp->pdev && ...) When pp->pdev is NULL, it is used on line 743: info = &pp->pdev->port->ieee1284; and on line 748: parport_release(pp->pdev); Thus, a possible null-pointer dereference may occur. To fix this bug, pp->pdev is checked on line 740. This bug is found by a static analysis tool STCheck written by us. Signed-off-by: Jia-Ju Bai Link: https://lore.kernel.org/r/20190724090426.1401-1-baijiaju1990@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/char/ppdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index f0a8adca1eee..c86f18aa8985 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -737,7 +737,7 @@ static int pp_release(struct inode *inode, struct file *file) "negotiated back to compatibility mode because user-space forgot\n"); } - if (pp->flags & PP_CLAIMED) { + if ((pp->flags & PP_CLAIMED) && pp->pdev) { struct ieee1284_info *info; info = &pp->pdev->port->ieee1284; -- cgit v1.2.3 From 8619e5bdeee8b2c685d686281f2d2a6017c4bc15 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Mon, 26 Aug 2019 22:13:25 +0900 Subject: /dev/mem: Bail out upon SIGKILL. syzbot found that a thread can stall for minutes inside read_mem() or write_mem() after that thread was killed by SIGKILL [1]. Reading from iomem areas of /dev/mem can be slow, depending on the hardware. While reading 2GB at one read() is legal, delaying termination of killed thread for minutes is bad. Thus, allow reading/writing /dev/mem and /dev/kmem to be preemptible and killable. [ 1335.912419][T20577] read_mem: sz=4096 count=2134565632 [ 1335.943194][T20577] read_mem: sz=4096 count=2134561536 [ 1335.978280][T20577] read_mem: sz=4096 count=2134557440 [ 1336.011147][T20577] read_mem: sz=4096 count=2134553344 [ 1336.041897][T20577] read_mem: sz=4096 count=2134549248 Theoretically, reading/writing /dev/mem and /dev/kmem can become "interruptible". But this patch chose "killable". Future patch will make them "interruptible" so that we can revert to "killable" if some program regressed. [1] https://syzkaller.appspot.com/bug?id=a0e3436829698d5824231251fad9d8e998f94f5e Signed-off-by: Tetsuo Handa Cc: stable Reported-by: syzbot Link: https://lore.kernel.org/r/1566825205-10703-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Greg Kroah-Hartman --- drivers/char/mem.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/char') diff --git a/drivers/char/mem.c b/drivers/char/mem.c index b08dc50f9f26..9eb564c002f6 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -97,6 +97,13 @@ void __weak unxlate_dev_mem_ptr(phys_addr_t phys, void *addr) } #endif +static inline bool should_stop_iteration(void) +{ + if (need_resched()) + cond_resched(); + return fatal_signal_pending(current); +} + /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. @@ -175,6 +182,8 @@ static ssize_t read_mem(struct file *file, char __user *buf, p += sz; count -= sz; read += sz; + if (should_stop_iteration()) + break; } kfree(bounce); @@ -251,6 +260,8 @@ static ssize_t write_mem(struct file *file, const char __user *buf, p += sz; count -= sz; written += sz; + if (should_stop_iteration()) + break; } *ppos += written; @@ -468,6 +479,10 @@ static ssize_t read_kmem(struct file *file, char __user *buf, read += sz; low_count -= sz; count -= sz; + if (should_stop_iteration()) { + count = 0; + break; + } } } @@ -492,6 +507,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf, buf += sz; read += sz; p += sz; + if (should_stop_iteration()) + break; } free_page((unsigned long)kbuf); } @@ -544,6 +561,8 @@ static ssize_t do_write_kmem(unsigned long p, const char __user *buf, p += sz; count -= sz; written += sz; + if (should_stop_iteration()) + break; } *ppos += written; @@ -595,6 +614,8 @@ static ssize_t write_kmem(struct file *file, const char __user *buf, buf += sz; virtr += sz; p += sz; + if (should_stop_iteration()) + break; } free_page((unsigned long)kbuf); } -- cgit v1.2.3 From 13c1d4b30e52e8d79b0e01ae3894cf8399572e1d Mon Sep 17 00:00:00 2001 From: Rishi Gupta Date: Sun, 18 Aug 2019 13:04:31 +0530 Subject: toshiba: Add correct printk log level while emitting error log The printk functions are invoked without specifying required log level when printing error messages. This commit replaces all direct uses of printk with their corresponding pr_err/info/debug variant. Signed-off-by: Rishi Gupta Link: https://lore.kernel.org/r/1566113671-8743-1-git-send-email-gupt21@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/char/toshiba.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index 0bdc602f0d48..98f3150e0048 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c @@ -373,7 +373,7 @@ static int tosh_get_machine_id(void __iomem *bios) value. This has been verified on a Satellite Pro 430CDT, Tecra 750CDT, Tecra 780DVD and Satellite 310CDT. */ #if TOSH_DEBUG - printk("toshiba: debugging ID ebx=0x%04x\n", regs.ebx); + pr_debug("toshiba: debugging ID ebx=0x%04x\n", regs.ebx); #endif bx = 0xe6f5; @@ -417,7 +417,7 @@ static int tosh_probe(void) for (i=0;i<7;i++) { if (readb(bios+0xe010+i)!=signature[i]) { - printk("toshiba: not a supported Toshiba laptop\n"); + pr_err("toshiba: not a supported Toshiba laptop\n"); iounmap(bios); return -ENODEV; } @@ -433,7 +433,7 @@ static int tosh_probe(void) /* if this is not a Toshiba laptop carry flag is set and ah=0x86 */ if ((flag==1) || ((regs.eax & 0xff00)==0x8600)) { - printk("toshiba: not a supported Toshiba laptop\n"); + pr_err("toshiba: not a supported Toshiba laptop\n"); iounmap(bios); return -ENODEV; } @@ -486,7 +486,7 @@ static int __init toshiba_init(void) if (tosh_probe()) return -ENODEV; - printk(KERN_INFO "Toshiba System Management Mode driver v" TOSH_VERSION "\n"); + pr_info("Toshiba System Management Mode driver v" TOSH_VERSION "\n"); /* set the port to use for Fn status if not specified as a parameter */ if (tosh_fn==0x00) -- cgit v1.2.3