Page MenuHomeFreeBSD

D58780.id183859.diff
No OneTemporary

D58780.id183859.diff

diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -1207,6 +1207,47 @@
return (0);
}
+/*
+ * Filler function for proc/pid/exe
+ *
+ * proc_get_binpath() returns a FreeBSD host path. For a binary under the
+ * emulator root that is e.g. /compat/linux/usr/bin/foo, but the Linux ABI
+ * resolves absolute paths from compat.linux.emul_path, so following that
+ * symlink looks up /compat/linux/compat/linux/usr/bin/foo and fails with
+ * ENOENT. Strip the emul prefix so /proc/pid/exe names the executable in
+ * the Linux namespace (readlink, stat, execve), matching Linux.
+ *
+ * For text outside the emulator root (e.g. ports installed under
+ * /usr/local) the host path is already the correct name in both
+ * namespaces; following it relies on namei restarting the lookup in the
+ * native namespace, which requires procfs(5) mounted at /proc.
+ */
+static int
+linprocfs_doprocexe(PFS_FILL_ARGS)
+{
+ char *fullpath, *freepath, *binpath;
+ size_t elen;
+ int error;
+
+ freepath = NULL;
+ binpath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ PROC_LOCK(p);
+ error = proc_get_binpath(p, binpath, &fullpath, &freepath);
+ if (error == 0) {
+ elen = strlen(linux_emul_path);
+ if (elen > 0 && strncmp(fullpath, linux_emul_path, elen) == 0 &&
+ (fullpath[elen] == '/' || fullpath[elen] == '\0')) {
+ fullpath += elen;
+ if (fullpath[0] == '\0')
+ fullpath = "/";
+ }
+ sbuf_cat(sb, fullpath);
+ }
+ free(binpath, M_TEMP);
+ free(freepath, M_TEMP);
+ return (error);
+}
+
/*
* Filler function for proc/pid/root
*/
@@ -2556,7 +2597,7 @@
NULL, 0);
pfs_create_file(dir, NULL, "environ", &linprocfs_doprocenviron, NULL,
&procfs_candebug, NULL, PFS_RD);
- pfs_create_link(dir, NULL, "exe", &procfs_doprocfile, NULL,
+ pfs_create_link(dir, NULL, "exe", &linprocfs_doprocexe, NULL,
&procfs_notsystem, NULL, 0);
pfs_create_file(dir, NULL, "maps", &linprocfs_doprocmaps, NULL, NULL,
NULL, PFS_RD | PFS_AUTODRAIN);
diff --git a/sys/compat/linux/linux_util.h b/sys/compat/linux/linux_util.h
--- a/sys/compat/linux/linux_util.h
+++ b/sys/compat/linux/linux_util.h
@@ -74,6 +74,8 @@
void linux_msg(const struct thread *td, const char *fmt, ...)
__printflike(2, 3);
+extern char linux_emul_path[];
+
struct linux_device_handler {
char *bsd_driver_name;
char *linux_driver_name;

File Metadata

Mime Type
text/plain
Expires
Wed, Aug 26, 1:13 AM (10 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37260293
Default Alt Text
D58780.id183859.diff (2 KB)

Event Timeline