Module Name: src Committed By: maxv Date: Sat Jun 28 11:39:15 UTC 2014
Modified Files: src/sys/compat/netbsd32: netbsd32_netbsd.c Log Message: Sync getfh() with the native implementation. It also fixes: a) a return value b) a vnode lock c) a user-controlled memory allocation ok christos@, on tech-kern To generate a diff of this commit: cvs rdiff -u -r1.190 -r1.191 src/sys/compat/netbsd32/netbsd32_netbsd.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/compat/netbsd32/netbsd32_netbsd.c diff -u src/sys/compat/netbsd32/netbsd32_netbsd.c:1.190 src/sys/compat/netbsd32/netbsd32_netbsd.c:1.191 --- src/sys/compat/netbsd32/netbsd32_netbsd.c:1.190 Sun Jun 22 19:09:39 2014 +++ src/sys/compat/netbsd32/netbsd32_netbsd.c Sat Jun 28 11:39:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_netbsd.c,v 1.190 2014/06/22 19:09:39 maxv Exp $ */ +/* $NetBSD: netbsd32_netbsd.c,v 1.191 2014/06/28 11:39:15 maxv Exp $ */ /* * Copyright (c) 1998, 2001, 2008 Matthew R. Green @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.190 2014/06/22 19:09:39 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.191 2014/06/28 11:39:15 maxv Exp $"); #if defined(_KERNEL_OPT) #include "opt_ddb.h" @@ -1302,7 +1302,7 @@ netbsd32___getfh30(struct lwp *l, const int error; struct pathbuf *pb; struct nameidata nd; - netbsd32_size_t sz32; + netbsd32_size_t usz32, sz32; size_t sz; /* @@ -1312,7 +1312,6 @@ netbsd32___getfh30(struct lwp *l, const 0, NULL, NULL, NULL); if (error) return (error); - fh = NULL; error = pathbuf_copyin(SCARG_P32(uap, fname), &pb); if (error) { @@ -1328,30 +1327,29 @@ netbsd32___getfh30(struct lwp *l, const vp = nd.ni_vp; pathbuf_destroy(pb); - error = copyin(SCARG_P32(uap, fh_size), &sz32, - sizeof(netbsd32_size_t)); - if (error) { - vput(vp); + error = vfs_composefh_alloc(vp, &fh); + vput(vp); + if (error != 0) { return error; } - fh = kmem_alloc(sz32, KM_SLEEP); - if (fh == NULL) - return EINVAL; - sz = sz32; - error = vfs_composefh(vp, fh, &sz); - vput(vp); + error = copyin(SCARG_P32(uap, fh_size), &usz32, sizeof(usz32)); + if (error != 0) { + goto out; + } + sz = FHANDLE_SIZE(fh); + sz32 = sz; - if (error == 0) { - const netbsd32_size_t nsz32 = sz; - error = copyout(&nsz32, SCARG_P32(uap, fh_size), - sizeof(netbsd32_size_t)); - if (!error) { - error = copyout(fh, SCARG_P32(uap, fhp), sz); - } - } else if (error == E2BIG) { - error = copyout(&sz, SCARG_P32(uap, fh_size), sizeof(size_t)); + error = copyout(&sz32, SCARG_P32(uap, fh_size), sizeof(sz32)); + if (error != 0) { + goto out; + } + if (usz32 >= sz32) { + error = copyout(fh, SCARG_P32(uap, fhp), sz); + } else { + error = E2BIG; } - kmem_free(fh, sz32); +out: + vfs_composefh_free(fh); return (error); }