NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: bin/60493: autofs does not handle chroot
The following reply was made to PR bin/60493; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Simon Gerraty <sjg%crufty.net@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Subject: Re: bin/60493: autofs does not handle chroot
Date: Thu, 6 Aug 2026 19:52:39 +0000
This is a multi-part message in MIME format.
--=_nsoQjY3CD7bBvFEdm/FiyAa+axP8majm
Updated patch -- this one initializes chrootpath as the somewhat
sharp-edged getcwd_common expects, so it doesn't lead to immediate
null pointer dereference.
--=_nsoQjY3CD7bBvFEdm/FiyAa+axP8majm
Content-Type: text/plain; charset="ISO-8859-1"; name="pr60493-autofschroot-v2"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="pr60493-autofschroot-v2.patch"
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1784864508 0
# Fri Jul 24 03:41:48 2026 +0000
# Branch trunk
# Node ID 6a1f5812e6f2eea24edafcaceba580dea93e45e2
# Parent b125bad3265e13dfd5a772b3676744fca85ce488
# EXP-Topic riastradh-pr60493-autofschroot
WIP: autofs: Support running inside a chroot.
PR kern/60493: autofs does not handle chroot
diff -r b125bad3265e -r 6a1f5812e6f2 sys/fs/autofs/autofs.c
--- a/sys/fs/autofs/autofs.c Mon Aug 03 19:24:48 2026 +0000
+++ b/sys/fs/autofs/autofs.c Fri Jul 24 03:41:48 2026 +0000
@@ -75,6 +75,7 @@
#include "ioconf.h"
=20
#include <sys/atomic.h>
+#include <sys/filedesc.h>
#include <sys/queue.h>
#include <sys/signalvar.h>
=20
@@ -451,16 +452,70 @@ autofs_trigger(struct autofs_node *anp,=20
static int
autofs_ioctl_request(struct autofs_daemon_request *adr)
{
+ struct lwp *l =3D curlwp;
+ struct proc *p =3D curproc;
+ struct cwdinfo *cwdi =3D p->p_cwdi;
struct autofs_request *ar;
+ char *chrootpathbuf =3D NULL, *chrootpath =3D NULL;
+ size_t chrootpathlen =3D 0;
+ const char *path;
+ int error;
=20
+ /*
+ * If we're chrooted, find the prefix to match in requests and
+ * strip off.
+ *
+ * If we're not chrooted, don't bother with any of it: no need
+ * to allocate a pathbuf and compute getcwd(). If another
+ * thread chroots while we're working, tough.
+ */
+ if (atomic_load_relaxed(&cwdi->cwdi_rdir) !=3D NULL) {
+ /*
+ * getcwd_common builds a path backwards from the end
+ * in a given buffer. So allocate a buffer,
+ * NUL-terminate it at the end, and start with a
+ * pointer to the NUL byte. Even though PNBUF_GET
+ * allocates a buffer of MAXPATHLEN bytes (including
+ * NUL), we clamp the length of the chroot prefix
+ * somewhat arbitrarily to MAXPATHLEN/2 just like
+ * statvfs(2) and getvfsstat(2).
+ */
+ chrootpathbuf =3D PNBUF_GET();
+ chrootpath =3D chrootpathbuf + MAXPATHLEN;
+ *--chrootpath =3D '\0';
+
+ rw_enter(&cwdi->cwdi_lock, RW_READER);
+ error =3D getcwd_common(cwdi->cwdi_rdir, rootvnode, &chrootpath,
+ chrootpathbuf, MAXPATHLEN/2, 0, l);
+ rw_exit(&cwdi->cwdi_lock);
+ if (error)
+ goto out;
+ chrootpathlen =3D strlen(chrootpath);
+ }
+
+ /*
+ * Wait until there is a request that is:
+ *
+ * (a) not done,
+ * (b) not in progress by another thread,
+ * (c) if we're chrooted, within our chroot.
+ *
+ * Once we have one, mark it in progress so other threads don't
+ * take it.
+ */
mutex_enter(&autofs_softc->sc_lock);
for (;;) {
- int error;
TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
if (ar->ar_done)
continue;
if (ar->ar_in_progress)
continue;
+ if (chrootpathlen > 1 &&
+ (strncmp(ar->ar_path, chrootpath, chrootpathlen)
+ !=3D 0 ||
+ (ar->ar_path[chrootpathlen] !=3D '/' &&
+ ar->ar_path[chrootpathlen] !=3D '\0')))
+ continue;
break;
}
=20
@@ -471,16 +526,34 @@ autofs_ioctl_request(struct autofs_daemo
&autofs_softc->sc_lock);
if (error) {
mutex_exit(&autofs_softc->sc_lock);
- return error;
+ goto out;
}
}
=20
ar->ar_in_progress =3D true;
mutex_exit(&autofs_softc->sc_lock);
=20
+ /*
+ * If we're chrooted, strip the chroot prefix off ar->ar_path.
+ * Otherwise, just use ar->ar_path as is for the adr->adr_path
+ * we return to userland.
+ */
+ if (chrootpathlen > 1) {
+ KASSERT(strncmp(ar->ar_path, chrootpath, chrootpathlen) =3D=3D 0);
+ KASSERT(ar->ar_path[chrootpathlen] =3D=3D '/' ||
+ ar->ar_path[chrootpathlen] =3D=3D '\0');
+ if (ar->ar_path[chrootpathlen] =3D=3D '\0')
+ path =3D "/";
+ else
+ path =3D ar->ar_path + chrootpathlen;
+ KASSERT(path[0] =3D=3D '/');
+ } else {
+ path =3D ar->ar_path;
+ }
+
adr->adr_id =3D ar->ar_id;
strlcpy(adr->adr_from, ar->ar_from, sizeof(adr->adr_from));
- strlcpy(adr->adr_path, ar->ar_path, sizeof(adr->adr_path));
+ strlcpy(adr->adr_path, path, sizeof(adr->adr_path));
strlcpy(adr->adr_prefix, ar->ar_prefix, sizeof(adr->adr_prefix));
strlcpy(adr->adr_key, ar->ar_key, sizeof(adr->adr_key));
strlcpy(adr->adr_options, ar->ar_options, sizeof(adr->adr_options));
@@ -489,7 +562,11 @@ autofs_ioctl_request(struct autofs_daemo
autofs_softc->sc_dev_sid =3D curproc->p_pgrp->pg_id;
mutex_exit(&proc_lock);
=20
- return 0;
+ error =3D 0;
+
+out: if (chrootpathbuf)
+ PNBUF_PUT(chrootpathbuf);
+ return error;
}
=20
static int
--=_nsoQjY3CD7bBvFEdm/FiyAa+axP8majm--
Home |
Main Index |
Thread Index |
Old Index