Module Name: src
Committed By: pooka
Date: Thu Apr 8 15:56:26 UTC 2010
Modified Files:
src/sys/miscfs/genfs: genfs_vnops.c
Log Message:
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
To generate a diff of this commit:
cvs rdiff -u -r1.176 -r1.177 src/sys/miscfs/genfs/genfs_vnops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/miscfs/genfs/genfs_vnops.c
diff -u src/sys/miscfs/genfs/genfs_vnops.c:1.176 src/sys/miscfs/genfs/genfs_vnops.c:1.177
--- src/sys/miscfs/genfs/genfs_vnops.c:1.176 Wed Jan 27 15:52:31 2010
+++ src/sys/miscfs/genfs/genfs_vnops.c Thu Apr 8 15:56:26 2010
@@ -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)