summaryrefslogtreecommitdiff
path: root/sys/modules
diff options
context:
space:
mode:
authordholland <dholland@NetBSD.org>2021-06-29 22:40:53 +0000
committerdholland <dholland@NetBSD.org>2021-06-29 22:40:53 +0000
commitc3e886adfa3ed5eaaf798d07ae03d6dee7b33895 (patch)
treef8ffbf3ee27e7ce7227ea9b9559712800fbb51ef /sys/modules
parent8c71233578627fdf3fd84886cb3696dfe662b07a (diff)
Add containment for the cloning devices hack in vn_open.
Cloning devices (and also things like /dev/stderr) work by allocating a struct file, stuffing it in the file table (which is a layer violation), stuffing the file descriptor number for it in a magic field of struct lwp (which is gross), and then "failing" with one of two magic errnos, EDUPFD or EMOVEFD. Before this commit, all callers of vn_open in the kernel (there are quite a few) were expected to check for these errors and handle the situation. Needless to say, none of them except for open() itself did, resulting in internal negative errnos being returned to userspace. This hack is fairly deeply rooted and cannot be eliminated all at once. This commit adds logic to handle the magic errnos inside vn_open; now on success vn_open returns either a vnode or an integer file descriptor, along with a flag that says whether the underlying code requested EDUPFD or EMOVEFD. Callers not prepared to cope with file descriptors can pass NULL for the extra return values, in which case if a file descriptor would be produced vn_open fails with EOPNOTSUPP. Since I'm rearranging vn_open's signature anyway, stop exposing struct nameidata. Instead, take three arguments: an optional vnode to use as the starting point (like openat()), the path, and additional namei flags to use, restricted to NOCHROOT and TRYEMULROOT. (Other namei behavior, e.g. NOFOLLOW, can be requested via the open flags.) This change requires a kernel bump. Ride the one an hour ago. (That was supposed to be coordinated; did not intend to let an hour slip by. My fault.)
Diffstat (limited to 'sys/modules')
-rw-r--r--sys/modules/lua/lua.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/sys/modules/lua/lua.c b/sys/modules/lua/lua.c
index 8d9dcc702da..b1e30ccef9c 100644
--- a/sys/modules/lua/lua.c
+++ b/sys/modules/lua/lua.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lua.c,v 1.24 2017/12/26 12:43:59 martin Exp $ */
+/* $NetBSD: lua.c,v 1.25 2021/06/29 22:40:53 dholland Exp $ */
/*
* Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>.
@@ -284,7 +284,7 @@ luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
struct lua_state *s;
struct lua_module *m;
kauth_cred_t cred;
- struct nameidata nd;
+ struct vnode *vp;
struct pathbuf *pb;
struct vattr va;
struct lua_loadstate ls;
@@ -414,8 +414,8 @@ luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
pb = pathbuf_create(load->path);
if (pb == NULL)
return ENOMEM;
- NDINIT(&nd, LOOKUP, FOLLOW | NOCHROOT, pb);
- error = vn_open(&nd, FREAD, 0);
+ error = vn_open(NULL, pb, NOCHROOT, FREAD, 0,
+ &vp, NULL, NULL);
pathbuf_destroy(pb);
if (error) {
if (lua_verbose)
@@ -424,11 +424,11 @@ luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
error);
return error;
}
- error = VOP_GETATTR(nd.ni_vp, &va,
+ error = VOP_GETATTR(vp, &va,
kauth_cred_get());
if (error) {
- VOP_UNLOCK(nd.ni_vp);
- vn_close(nd.ni_vp, FREAD,
+ VOP_UNLOCK(vp);
+ vn_close(vp, FREAD,
kauth_cred_get());
if (lua_verbose)
device_printf(sc->sc_dev,
@@ -437,19 +437,19 @@ luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
return error;
}
if (va.va_type != VREG) {
- VOP_UNLOCK(nd.ni_vp);
- vn_close(nd.ni_vp, FREAD,
+ VOP_UNLOCK(vp);
+ vn_close(vp, FREAD,
kauth_cred_get());
return EINVAL;
}
- ls.vp = nd.ni_vp;
+ ls.vp = vp;
ls.off = 0L;
ls.size = va.va_size;
- VOP_UNLOCK(nd.ni_vp);
+ VOP_UNLOCK(vp);
klua_lock(s->K);
error = lua_load(s->K->L, lua_reader, &ls,
strrchr(load->path, '/') + 1, "bt");
- vn_close(nd.ni_vp, FREAD, cred);
+ vn_close(vp, FREAD, cred);
switch (error) {
case 0: /* no error */
break;