From 39f1e86852529fc74a36b893f2a15c7e6a88ec2d Mon Sep 17 00:00:00 2001 From: riastradh Date: Fri, 28 Jul 2017 15:34:06 +0000 Subject: [PATCH] Fail, don't panic, on bad dirents from file system. Controllable via puffs from userland. From Ilja Van Sprundel. --- sys/compat/common/vfs_syscalls_12.c | 10 ++++++---- sys/compat/common/vfs_syscalls_43.c | 10 ++++++---- sys/compat/ibcs2/ibcs2_misc.c | 10 ++++++---- sys/compat/linux/common/linux_file64.c | 10 ++++++---- sys/compat/linux/common/linux_misc.c | 10 ++++++---- sys/compat/linux32/common/linux32_dirent.c | 10 ++++++---- sys/compat/osf1/osf1_file.c | 10 ++++++---- sys/compat/sunos/sunos_misc.c | 10 ++++++---- sys/compat/sunos32/sunos32_misc.c | 10 ++++++---- sys/compat/svr4/svr4_misc.c | 16 ++++++++++------ sys/compat/svr4_32/svr4_32_misc.c | 10 ++++++---- .../kern/lib/libsys_sunos/rump_sunos_compat.c | 8 +++++--- 12 files changed, 75 insertions(+), 49 deletions(-) diff --git a/sys/compat/common/vfs_syscalls_12.c b/sys/compat/common/vfs_syscalls_12.c index 15f2de142227..11b4d5500f16 100644 --- a/sys/compat/common/vfs_syscalls_12.c +++ b/sys/compat/common/vfs_syscalls_12.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls_12.c,v 1.33 2017/01/13 22:29:59 christos Exp $ */ +/* $NetBSD: vfs_syscalls_12.c,v 1.34 2017/07/28 15:34:06 riastradh Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_12.c,v 1.33 2017/01/13 22:29:59 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_12.c,v 1.34 2017/07/28 15:34:06 riastradh Exp $"); #include #include @@ -171,8 +171,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic(__func__); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) diff --git a/sys/compat/common/vfs_syscalls_43.c b/sys/compat/common/vfs_syscalls_43.c index cafde5ff555d..3e287ab9a498 100644 --- a/sys/compat/common/vfs_syscalls_43.c +++ b/sys/compat/common/vfs_syscalls_43.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls_43.c,v 1.59 2017/01/13 20:25:35 christos Exp $ */ +/* $NetBSD: vfs_syscalls_43.c,v 1.60 2017/07/28 15:34:06 riastradh Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_43.c,v 1.59 2017/01/13 20:25:35 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_43.c,v 1.60 2017/07/28 15:34:06 riastradh Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -451,8 +451,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic(__func__); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) diff --git a/sys/compat/ibcs2/ibcs2_misc.c b/sys/compat/ibcs2/ibcs2_misc.c index 65e15d6815e9..df5568cd6b8f 100644 --- a/sys/compat/ibcs2/ibcs2_misc.c +++ b/sys/compat/ibcs2/ibcs2_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: ibcs2_misc.c,v 1.113 2014/09/05 09:21:54 matt Exp $ */ +/* $NetBSD: ibcs2_misc.c,v 1.114 2017/07/28 15:34:06 riastradh Exp $ */ /* * Copyright (c) 1992, 1993 @@ -95,7 +95,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.113 2014/09/05 09:21:54 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.114 2017/07/28 15:34:06 riastradh Exp $"); #include #include @@ -427,8 +427,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("ibcs2_getdents: bad reclen"); + if (reclen & 3) { + error = EIO; + goto out; + } if (cookie && (*cookie >> 32) != 0) { compat_offseterr(vp, "ibcs2_getdents"); error = EINVAL; diff --git a/sys/compat/linux/common/linux_file64.c b/sys/compat/linux/common/linux_file64.c index e54db931de45..5247672b2387 100644 --- a/sys/compat/linux/common/linux_file64.c +++ b/sys/compat/linux/common/linux_file64.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_file64.c,v 1.58 2017/01/28 15:01:01 christos Exp $ */ +/* $NetBSD: linux_file64.c,v 1.59 2017/07/28 15:34:06 riastradh Exp $ */ /*- * Copyright (c) 1995, 1998, 2000, 2008 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.58 2017/01/28 15:01:01 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.59 2017/07/28 15:34:06 riastradh Exp $"); #include #include @@ -325,8 +325,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("linux_readdir"); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) diff --git a/sys/compat/linux/common/linux_misc.c b/sys/compat/linux/common/linux_misc.c index 6490e8990401..071a7cda6e1f 100644 --- a/sys/compat/linux/common/linux_misc.c +++ b/sys/compat/linux/common/linux_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_misc.c,v 1.238 2017/05/06 21:34:51 joerg Exp $ */ +/* $NetBSD: linux_misc.c,v 1.239 2017/07/28 15:34:06 riastradh Exp $ */ /*- * Copyright (c) 1995, 1998, 1999, 2008 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.238 2017/05/06 21:34:51 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.239 2017/07/28 15:34:06 riastradh Exp $"); #include #include @@ -748,8 +748,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("linux_readdir"); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) diff --git a/sys/compat/linux32/common/linux32_dirent.c b/sys/compat/linux32/common/linux32_dirent.c index faf7f42e4a1c..2aa9017530be 100644 --- a/sys/compat/linux32/common/linux32_dirent.c +++ b/sys/compat/linux32/common/linux32_dirent.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_dirent.c,v 1.17 2017/01/28 21:54:57 christos Exp $ */ +/* $NetBSD: linux32_dirent.c,v 1.18 2017/07/28 15:34:06 riastradh Exp $ */ /*- * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. @@ -33,7 +33,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: linux32_dirent.c,v 1.17 2017/01/28 21:54:57 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_dirent.c,v 1.18 2017/07/28 15:34:06 riastradh Exp $"); #include #include @@ -178,8 +178,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("linux32_readdir"); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) diff --git a/sys/compat/osf1/osf1_file.c b/sys/compat/osf1/osf1_file.c index 6dd941a1ea97..f978af4dcf2d 100644 --- a/sys/compat/osf1/osf1_file.c +++ b/sys/compat/osf1/osf1_file.c @@ -1,4 +1,4 @@ -/* $NetBSD: osf1_file.c,v 1.43 2014/09/05 09:21:54 matt Exp $ */ +/* $NetBSD: osf1_file.c,v 1.44 2017/07/28 15:34:06 riastradh Exp $ */ /* * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved. @@ -58,7 +58,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: osf1_file.c,v 1.43 2014/09/05 09:21:54 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: osf1_file.c,v 1.44 2017/07/28 15:34:06 riastradh Exp $"); #if defined(_KERNEL_OPT) #include "opt_syscall_debug.h" @@ -201,8 +201,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("osf1_sys_getdirentries: bad reclen"); + if (reclen & 3) { + error = EIO; + goto out; + } if (cookie) off = *cookie++; /* each entry points to the next */ else diff --git a/sys/compat/sunos/sunos_misc.c b/sys/compat/sunos/sunos_misc.c index 07363e0c5465..e23d5dd12d8d 100644 --- a/sys/compat/sunos/sunos_misc.c +++ b/sys/compat/sunos/sunos_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: sunos_misc.c,v 1.170 2015/10/23 19:40:11 maxv Exp $ */ +/* $NetBSD: sunos_misc.c,v 1.171 2017/07/28 15:34:06 riastradh Exp $ */ /* * Copyright (c) 1992, 1993 @@ -50,7 +50,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sunos_misc.c,v 1.170 2015/10/23 19:40:11 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunos_misc.c,v 1.171 2017/07/28 15:34:06 riastradh Exp $"); #include #include @@ -414,8 +414,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("sunos_getdents"); + if (reclen & 3) { + error = EIO; + goto out; + } if ((*cookie >> 32) != 0) { compat_offseterr(vp, "sunos_getdents"); error = EINVAL; diff --git a/sys/compat/sunos32/sunos32_misc.c b/sys/compat/sunos32/sunos32_misc.c index 88eb58c5d9c1..9eb56caa5bff 100644 --- a/sys/compat/sunos32/sunos32_misc.c +++ b/sys/compat/sunos32/sunos32_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: sunos32_misc.c,v 1.77 2016/02/28 23:24:35 khorben Exp $ */ +/* $NetBSD: sunos32_misc.c,v 1.78 2017/07/28 15:34:06 riastradh Exp $ */ /* from :NetBSD: sunos_misc.c,v 1.107 2000/12/01 19:25:10 jdolecek Exp */ /* @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sunos32_misc.c,v 1.77 2016/02/28 23:24:35 khorben Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunos32_misc.c,v 1.78 2017/07/28 15:34:06 riastradh Exp $"); #define COMPAT_SUNOS 1 @@ -659,8 +659,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("sunos_getdents"); + if (reclen & 3) { + error = EIO; + goto out; + } if (cookie && (*cookie >> 32) != 0) { compat_offseterr(vp, "sunos_getdents"); error = EINVAL; diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 3e0335be3467..d1a315787b44 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_misc.c,v 1.157 2016/11/10 17:00:51 christos Exp $ */ +/* $NetBSD: svr4_misc.c,v 1.158 2017/07/28 15:34:07 riastradh Exp $ */ /*- * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: svr4_misc.c,v 1.157 2016/11/10 17:00:51 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svr4_misc.c,v 1.158 2017/07/28 15:34:07 riastradh Exp $"); #include #include @@ -264,8 +264,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("svr4_getdents64: bad reclen"); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) @@ -388,8 +390,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("svr4_getdents: bad reclen"); + if (reclen & 3) { + error = EIO; + goto out; + } if (cookie) off = *cookie++; /* each entry points to the next */ else diff --git a/sys/compat/svr4_32/svr4_32_misc.c b/sys/compat/svr4_32/svr4_32_misc.c index 551631b31d31..a33caf054278 100644 --- a/sys/compat/svr4_32/svr4_32_misc.c +++ b/sys/compat/svr4_32/svr4_32_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_32_misc.c,v 1.77 2016/11/10 17:00:51 christos Exp $ */ +/* $NetBSD: svr4_32_misc.c,v 1.78 2017/07/28 15:34:07 riastradh Exp $ */ /*- * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: svr4_32_misc.c,v 1.77 2016/11/10 17:00:51 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svr4_32_misc.c,v 1.78 2017/07/28 15:34:07 riastradh Exp $"); #include #include @@ -263,8 +263,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("svr4_32_getdents64: bad reclen"); + if (reclen & 3) { + error = EIO; + goto out; + } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ if (cookie) diff --git a/sys/rump/kern/lib/libsys_sunos/rump_sunos_compat.c b/sys/rump/kern/lib/libsys_sunos/rump_sunos_compat.c index c7d7b99c0c86..c48cf3b6fb7e 100644 --- a/sys/rump/kern/lib/libsys_sunos/rump_sunos_compat.c +++ b/sys/rump/kern/lib/libsys_sunos/rump_sunos_compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: rump_sunos_compat.c,v 1.1 2013/04/09 13:08:33 pooka Exp $ */ +/* $NetBSD: rump_sunos_compat.c,v 1.2 2017/07/28 15:34:07 riastradh Exp $ */ /* * Copyright (c) 2013 Antti Kantee. All Rights Reserved. @@ -313,8 +313,10 @@ again: for (cookie = cookiebuf; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; - if (reclen & 3) - panic("sunos_getdents"); + if (reclen & 3) { + error = EIO; + goto out; + } if ((*cookie >> 32) != 0) { printf("rump_sunos_sys_getdents: offset too large\n"); error = EINVAL;