Tue Jun 23 18:30:17 2020 UTC ()
Hum. Fix NULL deref triggerable with just write(0).

Reported-by: syzbot+45b31355bf880e175b73@syzkaller.appspotmail.com


(maxv)
diff -r1.158 -r1.159 src/sys/net/if_tun.c

cvs diff -r1.158 -r1.159 src/sys/net/if_tun.c (expand / switch to unified diff)

--- src/sys/net/if_tun.c 2020/01/29 04:34:10 1.158
+++ src/sys/net/if_tun.c 2020/06/23 18:30:17 1.159
@@ -1,35 +1,35 @@ @@ -1,35 +1,35 @@
1/* $NetBSD: if_tun.c,v 1.158 2020/01/29 04:34:10 thorpej Exp $ */ 1/* $NetBSD: if_tun.c,v 1.159 2020/06/23 18:30:17 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5 * Nottingham University 1987. 5 * Nottingham University 1987.
6 * 6 *
7 * This source may be freely distributed, however I would be interested 7 * This source may be freely distributed, however I would be interested
8 * in any changes that are made. 8 * in any changes that are made.
9 * 9 *
10 * This driver takes packets off the IP i/f and hands them up to a 10 * This driver takes packets off the IP i/f and hands them up to a
11 * user process to have its wicked way with. This driver has its 11 * user process to have its wicked way with. This driver has its
12 * roots in a similar driver written by Phil Cockcroft (formerly) at 12 * roots in a similar driver written by Phil Cockcroft (formerly) at
13 * UCL. This driver is based much more on read/write/poll mode of 13 * UCL. This driver is based much more on read/write/poll mode of
14 * operation though. 14 * operation though.
15 */ 15 */
16 16
17/* 17/*
18 * tun - tunnel software network interface. 18 * tun - tunnel software network interface.
19 */ 19 */
20 20
21#include <sys/cdefs.h> 21#include <sys/cdefs.h>
22__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.158 2020/01/29 04:34:10 thorpej Exp $"); 22__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.159 2020/06/23 18:30:17 maxv Exp $");
23 23
24#ifdef _KERNEL_OPT 24#ifdef _KERNEL_OPT
25#include "opt_inet.h" 25#include "opt_inet.h"
26#endif 26#endif
27 27
28#include <sys/param.h> 28#include <sys/param.h>
29 29
30#include <sys/buf.h> 30#include <sys/buf.h>
31#include <sys/conf.h> 31#include <sys/conf.h>
32#include <sys/cpu.h> 32#include <sys/cpu.h>
33#include <sys/device.h> 33#include <sys/device.h>
34#include <sys/file.h> 34#include <sys/file.h>
35#include <sys/ioctl.h> 35#include <sys/ioctl.h>
@@ -847,26 +847,29 @@ tunwrite(dev_t dev, struct uio *uio, int @@ -847,26 +847,29 @@ tunwrite(dev_t dev, struct uio *uio, int
847 tp = tun_find_unit(dev); 847 tp = tun_find_unit(dev);
848 if (tp == NULL) { 848 if (tp == NULL) {
849 /* Interface was "destroyed" already. */ 849 /* Interface was "destroyed" already. */
850 return ENXIO; 850 return ENXIO;
851 } 851 }
852 852
853 /* Unlock until we've got the data */ 853 /* Unlock until we've got the data */
854 mutex_exit(&tp->tun_lock); 854 mutex_exit(&tp->tun_lock);
855 855
856 ifp = &tp->tun_if; 856 ifp = &tp->tun_if;
857 857
858 TUNDEBUG("%s: tunwrite\n", ifp->if_xname); 858 TUNDEBUG("%s: tunwrite\n", ifp->if_xname);
859 859
 860 if (uio->uio_resid == 0)
 861 return 0;
 862
860 if (tp->tun_flags & TUN_PREPADDR) { 863 if (tp->tun_flags & TUN_PREPADDR) {
861 if (uio->uio_resid < sizeof(dst)) { 864 if (uio->uio_resid < sizeof(dst)) {
862 error = EIO; 865 error = EIO;
863 goto out0; 866 goto out0;
864 } 867 }
865 error = uiomove((void *)&dst, sizeof(dst), uio); 868 error = uiomove((void *)&dst, sizeof(dst), uio);
866 if (dst.sa_len > sizeof(dst)) { 869 if (dst.sa_len > sizeof(dst)) {
867 /* Duh.. */ 870 /* Duh.. */
868 int n = dst.sa_len - sizeof(dst); 871 int n = dst.sa_len - sizeof(dst);
869 while (n--) { 872 while (n--) {
870 char discard; 873 char discard;
871 error = uiomove(&discard, 1, uio); 874 error = uiomove(&discard, 1, uio);
872 if (error) { 875 if (error) {