-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
file searches fail when procfs is mounted at multiple mount points #185
Comments
DamjanJovanovic
added a commit
to DamjanJovanovic/lsof
that referenced
this issue
Dec 19, 2021
…ntpoints. Fixes issue lsof-org#185 for FreeBSD.
DamjanJovanovic
added a commit
to DamjanJovanovic/lsof
that referenced
this issue
Jun 23, 2022
…ntpoints. Fixes issue lsof-org#185 for FreeBSD.
lrosenman
pushed a commit
that referenced
this issue
Sep 16, 2022
* [FreeBSD] use the kern.proc.proc/kern.proc.all sysctls instead of kvm_getprocs() to list process. * [FreeBSD] allow kvm_open() to fail, make kread() also fail afterwards. * [FreeBSD] Read the system-wide file table (kern.file sysctl) for later use. * [FreeBSD] link to libutil, and use its kinfo_getfile() function to retrieve file descriptors, which will be processed, for now, exactly like before. * [FreeBSD] Start using the libutil-based process_file_descriptors() function. Remove the old code. This finally gets lsof working without root access, but it won't show much details about the files yet as it still uses kvm access to get them. * [FreeBSD] implement process_kinfo_file(), our own version of the lib/prfd.c process_file() function, but do it using "struct kinfo_file" and "struct xfile", giving us the freedom to incrementally change processing per file type to not use kvm, unlike the process_file() function which forces the functions it calls to use kvm. * [FreeBSD] implement pipes using "struct kinfo_file", falling back to kvm where possible for missing functionality. * [FreeBSD] implement ptys using "struct kinfo_file" exclusively. * [FreeBSD] add some functions for reading socket PCBs for future use. * [FreeBSD] implement sockets using only kinfo_file and PCBs. Undefine USE_LIB_PROCESS_FILE since it can't link any more. Remove INRIA-specific IPv6 code as it died out decades ago. * [FreeBSD] read "struct xvnode" list for future use. * [FreeBSD] begin converting process_node() to usermode data only. Rename process_node() to process_vnode() as the former is declared for all dialects and can't be changed. Reimplement readvfs() using the statfs() call (whose prototype had to be re-declared as the _KERNEL define hides it and other things break without it). Also add the ability to search for filesystems by filename, which also helps as KERN_VNODE is completely broken. Use the system-wide xvnode array to find the matching xvnode for each xfile, and pass it to process_node(). There, make reading the kernel "struct vnode" optional for now, and start using kinfo_file, xfile and xvnode fields in favour of the kernel's "struct vnode". * [FreeBSD] initialize the uninitialized socket and PCB pointers. * [FreeBSD] use get_lock_state() on all possible filesystems, not just UFS and ZFS. * [FreeBSD] obtain the inode number from kinfo_file instead of the kernel. * [FreeBSD] use kinfo_file's vnode type instead of vnode's which may be absent. * [FreeBSD] use kinfo_file's dev and rdev instead of filesystems'. * [FreeBSD] obtain the file size using kinfo_file only. * [FreeBSD] get the link count using a stat() call. * [FreeBSD] kernel filesystem-specific data was used to extract the dev, inode, link count and size. Since we get those from userspace data now, we no longer need that code. Begin by removing msdosfs, cd9660 and fusefs specific code. * [FreeBSD] we don't need ZFS-specific code either. * [FreeBSD] no need for NFS-specific code. * [FreeBSD] no fdescfs-specific code is necessary either. * [FreeBSD] remove pseudofs-specific code too. * [FreeBSD] no more tmpfs-specific code. * [FreeBSD] remove the devfs-specific code. * [FreeBSD] no more UFS-specific code. * [FreeBSD] remove some device related unused variables. * [FreeBSD] remove other unused variables. * [FreeBSD] Dev2Udev() is done by the kernel, we don't need it. * [FreeBSD] remove vtags. We only have 2 filesystems needing special cases, and they are easier to check with an if statement. Also it should no longer be an error to have an unknown filesystem. * [FreeBSD] make all further usage of the kernel vnode optional. * [FreeBSD] add the filename, the most important thing lsof does. * [FreeBSD] many procfs fixes. Instead of only supporting procfs on FreeBSD < 5, and building pseudofs otherwise, enable it unconditionally and enable pseudofs as available. Detect procfs presence at runtime instead of compile time. Stop using kernel structures for procfs and derive the TYPE from the kinfo_file path. Remove the /proc/<pid>/ctl entry which doesn't exist. * [FreeBSD] refactor procfs path parsing code into its own function. * [FreeBSD] fix a crash when listing a nullfs node whose kernel vnode we can't read. * [FreeBSD] FreeBSD < 13 didn't always have struct xtcpcb field t_maxseg. * [FreeBSD] make the socket code compatible with FreeBSD < 12. * [FreeBSD] make the vnode code compatible with FreeBSD < 12. * [FreeBSD] retrieve the PCB pointer of the peer UNIX socket from struct kinfo_file's kf_un.kf_sock.kf_sock_unpconn instead of struct xunpcb's unp_conn, as the former worked in earlier FreeBSD versions. * [FreeBSD] deal with struct xtcpcb on FreeBSD < 1200026. * [FreeBSD] link to libutil on all FreeBSD versions that had it. * [FreeBSD] fix some procfs regressions. Call strrchr() on the right string. If there is a single procfs mount, store it in Mtprocfs. * [FreeBSD] fix procfs file searches when there are multiple procfs mountpoints. Fixes issue #185 for FreeBSD. * [FreeBSD] disable HASNCACHE. We use struct kinfo_file's kf_path instead. * [FreeBSD] update 00DIST, add a note to 00PORTING, and change to Github username in 00CREDITS. * [FreeBSD] use the so_state field from struct kinfo_file. Also fix the regression in 94f3db7 where the wrong snd state was being checked. * [FreeBSD] No more ncache. Get the vnode address from the xfile, if not in xvnode. * [FreeBSD] for kernel version >= 1400052, use the new struct kinfo_file instead of KVM access. * [FreeBSD] fix a build error on FreeBSD 13 due to a duplicate definition of struct syscall_args. * [FreeBSD] eliminate the use of struct xvnode, it doesn't work and isn't feasible (sysctl disabled, would need to fetch 10^6 nodes) or necessary. * [FreeBSD] distinguish mountpoints by fsid, not the kernel struct mount pointer. * [FreeBSD] pre-cache mount info from all files before processing them, as files without paths may need it from other files on their fs with paths. * [FreeBSD] add support for eventfd file descriptors. * [FreeBSD] print the eventfd address where available. * [FreeBSD] add support for the SHM file type. Derive file flags from kinfo_file flags when the struct xfile is not available. * [FreeBSD] F_RDLCK and F_WRLCK were never lock flags, they're mutually exclusive lock types. * [FreeBSD] use the new kern.lockf sysctl to retrieve file lock info where available, instead of kvm access. * [FreeBSD] eliminate kvm access for nullfs, modify the path based on the l_vfs entry for the file instead. * [FreeBSD] eliminate all kvm access on new enough FreeBSD versions * [FreeBSD] add support for the PROCDESC file type. * [FreeBSD] Use the advisory lock lookup API that actually exists in FreeBSD CURRENT, instead of the experimental one I developed. * [FreeBSD] Check for the released version of the kernel patch. * [FreeBSD] FreeBSD 9 under-reports the memory requires for the KERN_FILE sysctl, so increase it ourselves.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With HASPROCFS enabled, and procfs mounted in multiple places (eg. main system and a nested chroot), "lsof /proc/1/map" can fail to find anything, even though "lsof | grep /proc/1/map" works.
On multiple dialects (du, freebsd, n+obsd, sun, uw; Linux might be unaffected), the following seems to happen. There is a general filename search code path (running through multiple files), and a procfs-specific code path. The choice between them begins in dmnt.c: it populates Mtprocfs if exactly one procfs mountpoint is found to activate the procfs-specific code path, otherwise it is set to NULL to fall back to the general code path. Then in arg.c that populates other variables.
Later in dnode.c, at the bottom of process_node(), if Ntype == N_PROC, the procfs-specific search takes place. If Mtprocfs was set then Procfsid will be set, and custom logic compares pids and inodes. If multiple procfs mountpoints existed, Mtprocfs wouldn't have been set, Procfsid is NULL, and nothing will ever match.
Even hacking around that, to make procfs files go through the general path (the Ntype != N_PROC case), it still fails to match. This is because is_file_named() requires a match on both dev and inode, and earlier in process_node(), N_PROC files have this run on them:
causing is_file_named() to also never match.
Both issues should be fixed. If multiple procfs mounts should fall back to the general case, then it should fall back properly: the condition shouldn't be
if (Ntype == N_PROC)
but rather something likeif (Ntype == N_PROC && Procfsid)
. Then either the dev on procfs should be treated as valid (with dev_def=1) (on FreeBSD it is valid and differs between mountpoints), or is_file_named() should have a custom search mode purely for procfs inodes that ignores dev.(I also don't understand why we have the procfs-specific search path in the first place.)
I'll try fix to this in FreeBSD's dnode.c, but other dialects are beyond me.
The text was updated successfully, but these errors were encountered: