Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/genfs Call VOP_ABORTOP in genfs_eopnotsupp. This...
details: https://anonhg.NetBSD.org/src/rev/32267e360c97
branches: trunk
changeset: 753735:32267e360c97
user: pooka <pooka%NetBSD.org@localhost>
date: Thu Apr 08 15:56:26 2010 +0000
description:
Call VOP_ABORTOP in genfs_eopnotsupp. This prevents file system
authors from having to get down on their knees and pray they won't
get POGA'd(*) again.
This plugs componentname leaks in at least smbfs and buggy puffs
servers (buggy servers shouldn't be able to leak kernel memory).
*) principle of greatest astonishment
diffstat:
sys/miscfs/genfs/genfs_vnops.c | 34 ++++++++++++++++++++++++++++------
1 files changed, 28 insertions(+), 6 deletions(-)
diffs (67 lines):
diff -r fc899b86c8e0 -r 32267e360c97 sys/miscfs/genfs/genfs_vnops.c
--- a/sys/miscfs/genfs/genfs_vnops.c Thu Apr 08 15:03:33 2010 +0000
+++ b/sys/miscfs/genfs/genfs_vnops.c Thu Apr 08 15:56:26 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: genfs_vnops.c,v 1.176 2010/01/27 15:52:31 uebayasi Exp $ */
+/* $NetBSD: genfs_vnops.c,v 1.177 2010/04/08 15:56:26 pooka Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.176 2010/01/27 15:52:31 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.177 2010/04/08 15:56:26 pooka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -170,7 +170,8 @@
/*
* Called when an fs doesn't support a particular vop.
- * This takes care to vrele, vput, or vunlock passed in vnodes.
+ * This takes care to vrele, vput, or vunlock passed in vnodes
+ * and calls VOP_ABORTOP for a componentname (in non-rename VOP).
*/
int
genfs_eopnotsupp(void *v)
@@ -181,14 +182,35 @@
} */ *ap = v;
struct vnodeop_desc *desc = ap->a_desc;
struct vnode *vp, *vp_last = NULL;
- int flags, i, j, offset;
+ int flags, i, j, offset_cnp, offset_vp;
+
+ KASSERT(desc->vdesc_offset != VOP_LOOKUP_DESCOFFSET);
+ KASSERT(desc->vdesc_offset != VOP_ABORTOP_DESCOFFSET);
+
+ /*
+ * Free componentname that lookup potentially SAVENAMEd.
+ *
+ * As is logical, componentnames for VOP_RENAME are handled by
+ * the caller of VOP_RENAME. Yay, rename!
+ */
+ if (desc->vdesc_offset != VOP_RENAME_DESCOFFSET &&
+ (offset_vp = desc->vdesc_vp_offsets[0]) != VDESC_NO_OFFSET &&
+ (offset_cnp = desc->vdesc_componentname_offset) != VDESC_NO_OFFSET){
+ struct componentname *cnp;
+ struct vnode *dvp;
+
+ dvp = *VOPARG_OFFSETTO(struct vnode **, offset_vp, ap);
+ cnp = *VOPARG_OFFSETTO(struct componentname **, offset_cnp, ap);
+
+ VOP_ABORTOP(dvp, cnp);
+ }
flags = desc->vdesc_flags;
for (i = 0; i < VDESC_MAX_VPS; flags >>=1, i++) {
- if ((offset = desc->vdesc_vp_offsets[i]) == VDESC_NO_OFFSET)
+ if ((offset_vp = desc->vdesc_vp_offsets[i]) == VDESC_NO_OFFSET)
break; /* stop at end of list */
if ((j = flags & VDESC_VP0_WILLPUT)) {
- vp = *VOPARG_OFFSETTO(struct vnode **, offset, ap);
+ vp = *VOPARG_OFFSETTO(struct vnode **, offset_vp, ap);
/* Skip if NULL */
if (!vp)
Home |
Main Index |
Thread Index |
Old Index