Module Name:    src
Committed By:   bouyer
Date:           Mon Jan 17 11:20:00 UTC 2022

Modified Files:
        src/sys/miscfs/procfs: procfs.h procfs_vfsops.c procfs_vnops.c

Log Message:
If the calling process is running under linux emulation, make /proc/xxx/fd/
return only symlinks pointing to the original file in the filesystem,
instead of a hard link. This matches the linux behavior, and some
linux programs relies on it (they unconditionally call readlink() on
/proc/xxx/fd/yy and don't deal with it returning EINVAL).
Proposed on tech-kern@ in
http://mail-index.netbsd.org/tech-kern/2022/01/11/msg027877.html


To generate a diff of this commit:
cvs rdiff -u -r1.80 -r1.81 src/sys/miscfs/procfs/procfs.h
cvs rdiff -u -r1.110 -r1.111 src/sys/miscfs/procfs/procfs_vfsops.c
cvs rdiff -u -r1.226 -r1.227 src/sys/miscfs/procfs/procfs_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/procfs/procfs.h
diff -u src/sys/miscfs/procfs/procfs.h:1.80 src/sys/miscfs/procfs/procfs.h:1.81
--- src/sys/miscfs/procfs/procfs.h:1.80	Wed Apr 29 07:18:24 2020
+++ src/sys/miscfs/procfs/procfs.h	Mon Jan 17 11:20:00 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs.h,v 1.80 2020/04/29 07:18:24 riastradh Exp $	*/
+/*	$NetBSD: procfs.h,v 1.81 2022/01/17 11:20:00 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -213,6 +213,14 @@ struct mount;
 
 struct proc *procfs_proc_find(struct mount *, pid_t);
 bool procfs_use_linux_compat(struct mount *);
+
+static inline bool
+procfs_proc_is_linux_compat(void)
+{
+	const char *emulname = curlwp->l_proc->p_emul->e_name;
+	return (strncmp(emulname, "linux", 5) == 0);
+}
+
 int procfs_proc_lock(struct mount *, int, struct proc **, int);
 void procfs_proc_unlock(struct proc *);
 int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int);

Index: src/sys/miscfs/procfs/procfs_vfsops.c
diff -u src/sys/miscfs/procfs/procfs_vfsops.c:1.110 src/sys/miscfs/procfs/procfs_vfsops.c:1.111
--- src/sys/miscfs/procfs/procfs_vfsops.c:1.110	Mon Dec 28 22:36:16 2020
+++ src/sys/miscfs/procfs/procfs_vfsops.c	Mon Jan 17 11:20:00 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_vfsops.c,v 1.110 2020/12/28 22:36:16 riastradh Exp $	*/
+/*	$NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.110 2020/12/28 22:36:16 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -343,7 +343,8 @@ procfs_loadvnode(struct mount *mp, struc
 				 * We make symlinks for directories
 				 * to avoid cycles.
 				 */
-				if (vxp->v_type == VDIR)
+				if (vxp->v_type == VDIR ||
+				    procfs_proc_is_linux_compat())
 					goto symlink;
 				vp->v_type = vxp->v_type;
 				break;

Index: src/sys/miscfs/procfs/procfs_vnops.c
diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.226 src/sys/miscfs/procfs/procfs_vnops.c:1.227
--- src/sys/miscfs/procfs/procfs_vnops.c:1.226	Fri Jan 14 23:46:56 2022
+++ src/sys/miscfs/procfs/procfs_vnops.c	Mon Jan 17 11:20:00 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_vnops.c,v 1.226 2022/01/14 23:46:56 christos Exp $	*/
+/*	$NetBSD: procfs_vnops.c,v 1.227 2022/01/17 11:20:00 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
@@ -105,7 +105,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.226 2022/01/14 23:46:56 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.227 2022/01/17 11:20:00 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -1143,7 +1143,8 @@ procfs_lookup(void *v)
 		fvp = fp->f_vnode;
 
 		/* Don't show directories */
-		if (fp->f_type == DTYPE_VNODE && fvp->v_type != VDIR) {
+		if (fp->f_type == DTYPE_VNODE && fvp->v_type != VDIR &&
+		    !procfs_proc_is_linux_compat()) {
 			vref(fvp);
 			closef(fp);
 			procfs_proc_unlock(p);
@@ -1651,7 +1652,8 @@ procfs_readlink(void *v)
 		switch (fp->f_type) {
 		case DTYPE_VNODE:
 			vxp = fp->f_vnode;
-			if (vxp->v_type != VDIR) {
+			if (vxp->v_type != VDIR &&
+			    !procfs_proc_is_linux_compat()) {
 				error = EINVAL;
 				break;
 			}

Reply via email to