Blame 00DCACHE

Packit 6f02de
Packit 6f02de
    	Configuring The Device Cache File Path
Packit 6f02de
Packit 6f02de
			    Contents
Packit 6f02de
Packit 6f02de
		A.  Introduction and History
Packit 6f02de
		B.  Device Cache File Format
Packit 6f02de
		    1.	Integrity Checks
Packit 6f02de
		    2.	The Setgid and Setuid-root States
Packit 6f02de
		C. Device Cache File Path Options
Packit 6f02de
		    1.	Path Named by ``-D''
Packit 6f02de
		    2.	Path Named in Environment Variable
Packit 6f02de
		    3.	Default System-wide Path
Packit 6f02de
			a.  Build Procedure
Packit 6f02de
		    4.	Default Personal Path
Packit 6f02de
		    5.	Modified Default Personal Path
Packit 6f02de
		D. Displaying the Default Path
Packit 6f02de
		Appendix A, Unix Dialects Without a Device Cache
Packit 6f02de
		Appendix B, Lsof Dialects and Their Permissions
Packit 6f02de
		    1.	Setuid-root Lsof Dialects 
Packit 6f02de
		    2.	Setgid Lsof Dialects That Surrender Setgid
Packit 6f02de
		   	Permission
Packit 6f02de
Packit 6f02de
Packit 6f02de
A. Introduction and History
Packit 6f02de
===========================
Packit 6f02de
Packit 6f02de
Lsof writes a file of information about the contents of the nodes
Packit 6f02de
in /dev (or /devices) to reduce its startup overhead on later calls.
Packit 6f02de
It does this for all Unix dialects, except those noted in Appendix A.
Packit 6f02de
Packit 6f02de
This file, called the device cache file, enables lsof to avoid
Packit 6f02de
calling the kernel stat(2) function on every node in /dev (or
Packit 6f02de
/devices) from which it builds a table of correspondence between
Packit 6f02de
major/minor device numbers and device names.
Packit 6f02de
Packit 6f02de
A full scan of /dev (or /devices) on some systems may involve
Packit 6f02de
calling the sometimes-slow stat(2) function 10,000 times or more.
Packit 6f02de
Furthermore, each stat(2) call consumes space in the kernel's name
Packit 6f02de
cache, forcing from it path name components that would be more
Packit 6f02de
useful when lsof tries to associate them with open files.
Packit 6f02de
Packit 6f02de
While it's hard to question the usefulness of the device cache,
Packit 6f02de
it's also hard to decide where it should be written.  When the
Packit 6f02de
feature was first added, the device cache file was written to /tmp,
Packit 6f02de
and its ownership was set to that of the real user ID (UID) under
Packit 6f02de
which the creating lsof process was run.  However, to enable any
Packit 6f02de
process to update it when /dev (or /devices) changed, lsof set its
Packit 6f02de
modes to 0666, thus allowing anyone to read or write it.
Packit 6f02de
Packit 6f02de
The writing of a world-readable and world-writable device cache
Packit 6f02de
file to any place has security weaknesses.  A clever intruder who
Packit 6f02de
carefully preserves the integrity of the file might be able to
Packit 6f02de
remove devices that would prevent lsof from observing the intruder's
Packit 6f02de
files.  A clever intruder might also be able to put a symbolic link
Packit 6f02de
in place and trick lsof into writing to the link's destination with
Packit 6f02de
its effective permissions, thus bypassing the real user's (possibly
Packit 6f02de
weaker) permissions.
Packit 6f02de
Packit 6f02de
Later the location of the device cache file was changed.  It was
Packit 6f02de
converted to a personal file, located in the home directory of each
Packit 6f02de
real UID that executed lsof, and owned by that UID.  Thus it was
Packit 6f02de
no longer possible for one user to affect lsof's access to the
Packit 6f02de
device cache file, nor was it possible for a user to mount a symbolic
Packit 6f02de
link attack on a restricted file, but the result was that each lsof
Packit 6f02de
user had a private copy of the device cache file.
Packit 6f02de
Packit 6f02de
The device cache file feature has undergone some further refinements
Packit 6f02de
in path name formation to reach its present state.  This documentation
Packit 6f02de
describes the path name formation options open to the lsof builder
Packit 6f02de
and user after those refinements, and how lsof attempts to insure
Packit 6f02de
that none of the options presents a security risk.
Packit 6f02de
Packit 6f02de
Packit 6f02de
B. Device Cache File Format
Packit 6f02de
===========================
Packit 6f02de
Packit 6f02de
The device cache file is a flat file of ASCII text.  It has an
Packit 6f02de
initial statement of how many sections the file might contain --
Packit 6f02de
the possible sections are character devices, block devices, clone
Packit 6f02de
devices, pseudo devices, and checksum.  The character devices and
Packit 6f02de
checksum sections are always present.
Packit 6f02de
Packit 6f02de
Each section has a header that numbers the entries in the section.
Packit 6f02de
Packit 6f02de
The last section is a checksum section that contains a 16 bit cyclic
Packit 6f02de
redundancy (CRC) checksum of everything in the file but the checksum
Packit 6f02de
section itself.
Packit 6f02de
Packit 6f02de
Lsof always sets the permission modes of the device cache file to
Packit 6f02de
0600, and the owner to the real UID of the process that executes
Packit 6f02de
lsof; the group, the real group ID (GID) of the lsof process.
Packit 6f02de
Packit 6f02de
Setting the permission modes to 0600 means that a system-wide device
Packit 6f02de
cache file won't be usable unless the procedure that builds it
Packit 6f02de
changes the modes after lsof has written it.  A suitable procedure
Packit 6f02de
for building a system-wide device cache that shows how to adjust
Packit 6f02de
these inadequate permission modes is given in the Default System-wide
Packit 6f02de
Path section.
Packit 6f02de
Packit 6f02de
Packit 6f02de
B.1. Integrity Checks
Packit 6f02de
=====================
Packit 6f02de
Packit 6f02de
When lsof opens the device cache file it makes these integrity
Packit 6f02de
checks:
Packit 6f02de
Packit 6f02de
    1.  Lsof must gain permission from access(2) to be able to
Packit 6f02de
	open the file for reading.  If lsof is writing the file,
Packit 6f02de
	it usually cedes permission control to the applicable
Packit 6f02de
	directory and file modes and ownerships.  (Some additional
Packit 6f02de
	checks apply and they're described in the sections on path
Packit 6f02de
	options.)
Packit 6f02de
Packit 6f02de
	By explicit design lsof never writes to the system-wide
Packit 6f02de
	device cache file, even when the real UID of its process
Packit 6f02de
	is root.  The system-wide device cache file must be written
Packit 6f02de
	with a root-owned procedure via the ``-D[b|u<path>'' options
Packit 6f02de
	-- i.e., under the system administrator's control.  (See
Packit 6f02de
	the Build Procedure sub-section of the Default System-wide
Packit 6f02de
	Path section.)
Packit 6f02de
Packit 6f02de
    2.  The device cache file's modes must be 0600 (0644 if lsof
Packit 6f02de
	is reading a system-wide device cache file) and its size
Packit 6f02de
	must be non-zero.
Packit 6f02de
Packit 6f02de
    3.  There must be a correctly formatted section count line
Packit 6f02de
	at the beginning of the file.
Packit 6f02de
Packit 6f02de
    4.  Each section must have a header line with a count that
Packit 6f02de
	properly numbers the lines in the section.  The first words
Packit 6f02de
	of legal section titles are "device", "block", "clone",
Packit 6f02de
	"pseudo", and "CRC".
Packit 6f02de
Packit 6f02de
    5.  The lines of a section must have the proper format.
Packit 6f02de
Packit 6f02de
    6.  All lines are included in a 16 bit CRC, and it is recorded
Packit 6f02de
	in a non-checksummed section line at the end of the file.
Packit 6f02de
Packit 6f02de
    7.  The checksum computed when the file is read must match the
Packit 6f02de
	checksum recorded when the file was written.
Packit 6f02de
Packit 6f02de
    8.  The checksum section line must be followed by end-of-
Packit 6f02de
	information.
Packit 6f02de
Packit 6f02de
    9.  Lsof must be able to get matching results from stat(2)
Packit 6f02de
	on a randomly chosen entry of the device section.
Packit 6f02de
Packit 6f02de
Packit 6f02de
B.2. The Setgid and Setuid-root States
Packit 6f02de
======================================
Packit 6f02de
Packit 6f02de
There are two fundamental ways in which lsof is granted access to
Packit 6f02de
restricted system resources.  Both access methods are related to the
Packit 6f02de
effective permissions given the lsof binary or executable.
Packit 6f02de
Packit 6f02de
The first and preferable way to grant lsof access to system resources
Packit 6f02de
through the permissions endowed on its executable is the giving of
Packit 6f02de
set group ID (setgid) permission.  The group is the one that has
Packit 6f02de
permission to read the kernel memory and swap devices -- e.g., /dev/kmem,
Packit 6f02de
/dev/mem, /dev/swap, etc.
Packit 6f02de
Packit 6f02de
This method of granting access is called setgid mode because it
Packit 6f02de
enables lsof to run with an effective group ID set to the one
Packit 6f02de
granted by the permissions of its executable file and by the group
Packit 6f02de
that owns the executable file.  See the getegid(2) man page for a
Packit 6f02de
further discussion of effective group ID.
Packit 6f02de
Packit 6f02de
Usually lsof only needs setgid permission to open access to the
Packit 6f02de
kernel memory files.  After they're open, lsof drops its setgid
Packit 6f02de
permission.
Packit 6f02de
Packit 6f02de
The second and least preferable way to grant lsof access to system
Packit 6f02de
resources through the permissions endowed on its executable is the
Packit 6f02de
giving of set user ID to root (setuid-root) permission.  This is
Packit 6f02de
much too strong a permission, but necessary: to use the -X option
Packit 6f02de
fully for the version of lsof for AIX 5 and above; to use the
Packit 6f02de
version of lsof for HP-UX 11.11 and above; and to use the version
Packit 6f02de
of lsof for Linux 2.1.72 and above.  These lsof implementations
Packit 6f02de
require setuid-root permission to be able to access restricted
Packit 6f02de
resources -- e.g., the individual files of the /proc file system.
Packit 6f02de
(But note that the setuid-root Linux lsof doesn't need and has no
Packit 6f02de
device cache support.)
Packit 6f02de
Packit 6f02de
Lsof never drops setuid-root permission, because it needs that
Packit 6f02de
power throughout its execution.  However, when the lsof process is
Packit 6f02de
setuid-root, lsof disallows these device cache file path options:
Packit 6f02de
Packit 6f02de
    1.  It ignores the ``-D[b|r|u]<path>'' options.  It accepts
Packit 6f02de
        only the ``-Di'' and ``-Dr'' options.
Packit 6f02de
Packit 6f02de
    2.	It refuses to recognize a path supplied via an environment
Packit 6f02de
	variable.
Packit 6f02de
Packit 6f02de
    3.  It refuses to accept an additional path component from an
Packit 6f02de
	environment variable to be inserted in the middle of a
Packit 6f02de
	personal device cache file path.
Packit 6f02de
Packit 6f02de
Each restriction is imposed because setuid-root power might allow
Packit 6f02de
a malicious user to form a device cache file path that would give
Packit 6f02de
read access to a normally inaccessible place (That's bad enough.),
Packit 6f02de
or write access to a critical system file (That's the worst case.)
Packit 6f02de
Packit 6f02de
There is one further state that lsof can enter that is slightly
Packit 6f02de
different from the setuid-root and setgid states.  That state occurs
Packit 6f02de
when lsof is being run from a root shell -- i.e., the lsof real
Packit 6f02de
user ID is root.  To avoid accidental complications, when lsof is
Packit 6f02de
in this state, it ignores all environment variable options.
Packit 6f02de
Packit 6f02de
In the rest of this document you will find more detailed discussion
Packit 6f02de
of the special restrictions caused by the type of permission that
Packit 6f02de
has been given the lsof executable.
Packit 6f02de
Packit 6f02de
Packit 6f02de
C. Device Cache File Path Options
Packit 6f02de
=================================
Packit 6f02de
Packit 6f02de
Lsof offers five options for constructing the path to the device
Packit 6f02de
cache file.  Each has special conditions and safeguards that
Packit 6f02de
surround its use.  The options are:
Packit 6f02de
Packit 6f02de
    1.	A device cache file that is named in the <path> component
Packit 6f02de
	of the parameters of lsof's ``-D'' option.
Packit 6f02de
Packit 6f02de
	=========================================================
Packit 6f02de
	* This is a default option of the lsof distribution.	*
Packit 6f02de
	*							*
Packit 6f02de
	* Paths specified with this option are read-only unless	*
Packit 6f02de
	* the real UID of the lsof process is root (0), or the	*
Packit 6f02de
	* lsof process is able to surrender setgid permission	*
Packit 6f02de
	* (See Appendix B) and it is not setuid-root.		*
Packit 6f02de
	=========================================================
Packit 6f02de
Packit 6f02de
    2.	A device cache file whose name is specified by an environment
Packit 6f02de
	variable.
Packit 6f02de
Packit 6f02de
	=========================================================
Packit 6f02de
	* This is a default option of the lsof distribution.	*
Packit 6f02de
	*							*
Packit 6f02de
	* This option is enabled when the lsof dialect is able	*
Packit 6f02de
	* to surrender setgid permission (See Appendix B.), and	* 
Packit 6f02de
	* the lsof process is not setuid-root.			*
Packit 6f02de
	*							*
Packit 6f02de
	* The environment variable path is read-only if the	*
Packit 6f02de
	* lsof process does not surrender setgid permission	*
Packit 6f02de
	* (See Appendix B.)					*
Packit 6f02de
	=========================================================
Packit 6f02de
Packit 6f02de
    3.	A system-wide default device cache file, located at a path
Packit 6f02de
	determined by the builder of lsof.  The lsof builder is also
Packit 6f02de
	responsible for building the device cache file, using a
Packit 6f02de
	different lsof path formation option at a suitable time --
Packit 6f02de
	e.g., when the system is booted.
Packit 6f02de
Packit 6f02de
	=========================================================
Packit 6f02de
	* This is option is disabled by default in the lsof	*
Packit 6f02de
	* distribution.						*
Packit 6f02de
	*							*
Packit 6f02de
	* The path specified with this option is read-only.	*
Packit 6f02de
	=========================================================
Packit 6f02de
Packit 6f02de
    4.	A default personal device cache file, located in the UID's
Packit 6f02de
	home directory.
Packit 6f02de
Packit 6f02de
	=========================================================
Packit 6f02de
	* This is a default option of the lsof distribution.	*
Packit 6f02de
	=========================================================
Packit 6f02de
Packit 6f02de
    5.	A personal device cache file whose name is modified by an
Packit 6f02de
	environment variable.
Packit 6f02de
Packit 6f02de
	=========================================================
Packit 6f02de
	* This is a default option of the lsof distribution.	*
Packit 6f02de
	*							*
Packit 6f02de
	* The modified personal path is read-only if the lsof	*
Packit 6f02de
	* process does not surrender setgid permission.		*
Packit 6f02de
	*							*
Packit 6f02de
	* This option is disabled when the lsof process is	*
Packit 6f02de
	* setuid-root or its real UID is root (0).	   	*
Packit 6f02de
	=========================================================
Packit 6f02de
Packit 6f02de
When there are multiple choices for the device cache file path,
Packit 6f02de
lsof chooses from the above list in the order the list is given,
Packit 6f02de
subject to restrictions based on the effective group and user IDs
Packit 6f02de
that are in effect.
Packit 6f02de
Packit 6f02de
Each possible path name is discussed in a later section that
Packit 6f02de
describes the restrictions that apply to it and the method for
Packit 6f02de
building lsof to use it.
Packit 6f02de
Packit 6f02de
In one special case lsof will use two paths in order.  When a
Packit 6f02de
system-wide device cache file is enabled, and lsof finds that it
Packit 6f02de
doesn't exist, lsof will attempt to use a personal device cache
Packit 6f02de
file.
Packit 6f02de
Packit 6f02de
Packit 6f02de
C.1. Path Named by ``-D''
Packit 6f02de
=========================
Packit 6f02de
Packit 6f02de
The ``-D[b|r|u]<path>'' option can name a path for the device cache
Packit 6f02de
file where it is unconditionally built (`b'); read, but never
Packit 6f02de
rebuilt (`r'); and read and rebuilt, if necessary (`u').
Packit 6f02de
Packit 6f02de
If the lsof process is setuid-root, no path may be specified with
Packit 6f02de
the ``-D'' option -- i.e., only the `i' function is accepted.  The
Packit 6f02de
`r' option may be used if it doesn't have a path argument.
Packit 6f02de
Packit 6f02de
If the lsof process is not setuid-root, nor is the real UID of the
Packit 6f02de
lsof process root, a path may accompany the `b', `r', and `u'
Packit 6f02de
functions if the lsof process surrenders setgid permission.  (See
Packit 6f02de
Appendix B.)  If the process doesn't surrender setgid permission,
Packit 6f02de
then a path may accompany only `r'.
Packit 6f02de
Packit 6f02de
Lsof's permission to access a device cache file at a path specified
Packit 6f02de
with ``-D[b|r|u]<path>'' depends completely on the permission modes
Packit 6f02de
and ownerships of the file and its directory components.
Packit 6f02de
Packit 6f02de
When the real UID of the lsof process is root (0), paths may be
Packit 6f02de
specified with ``-D[b|r|u]''.
Packit 6f02de
Packit 6f02de
====================================================================
Packit 6f02de
*								   *
Packit 6f02de
* The ``-D[b|r|u]<path>'' option is enabled by default in the lsof *
Packit 6f02de
* distribution by the following definition in the dialect's	   *
Packit 6f02de
* machine.h header file:					   *
Packit 6f02de
*								   *
Packit 6f02de
*	#define HASDCACHE 1					   *
Packit 6f02de
*								   *
Packit 6f02de
* To disable all device cache file options, including all ``-D''   *
Packit 6f02de
* forms, change the above line in the dialect's machine.h file to: *
Packit 6f02de
*								   *
Packit 6f02de
*	/* #define HASDCACHE 1 */				   *
Packit 6f02de
*								   *
Packit 6f02de
* or remove it.							   *
Packit 6f02de
*								   *
Packit 6f02de
* The ``-D[b|r|u]<path>'' options are disabled when the lsof	   *
Packit 6f02de
* process is setuid-root.  If the lsof process isn't setuid-root,  *
Packit 6f02de
* nor is its real UID root (0), and if the lsof process surrenders *
Packit 6f02de
* setgid permission, ``-D[b|r|u]'' may be accompanied by a path.   *
Packit 6f02de
*								   *
Packit 6f02de
* A path may accompany ``-D[b|u]'' when the real UID of the lsof   *
Packit 6f02de
* process is root.						   *
Packit 6f02de
*								   *
Packit 6f02de
* ``-Dr'' without a path name argument is always acceptable.	   *
Packit 6f02de
*								   *
Packit 6f02de
====================================================================
Packit 6f02de
Packit 6f02de
Packit 6f02de
C.2. Path Named in Environment Variable
Packit 6f02de
=======================================
Packit 6f02de
Packit 6f02de
A device cache file path may be declared in an environment variable.
Packit 6f02de
This option is defined in the dialect's machine.h header file with
Packit 6f02de
the HASENVDC definition.  The value of the HASENVDC definition is
Packit 6f02de
the environment variable's name.
Packit 6f02de
Packit 6f02de
Lsof will use the value of the environment variable named by HASENVDC
Packit 6f02de
for the device cache file path unless either of the following
Packit 6f02de
conditions apply:
Packit 6f02de
Packit 6f02de
    1.	The lsof process is in the setuid-root state.
Packit 6f02de
or
Packit 6f02de
    2.	The effective and real UIDs of the lsof process are root
Packit 6f02de
	(0).
Packit 6f02de
Packit 6f02de
Lsof uses the value of the HASENVDC environment variable as the
Packit 6f02de
device cache file path after it senses there is no path declared by
Packit 6f02de
a ``-D'' option.
Packit 6f02de
Packit 6f02de
A path from an environment variable is read-only unless the lsof
Packit 6f02de
process surrenders setgid permission.  (See Appendix B.)
Packit 6f02de
Packit 6f02de
====================================================================
Packit 6f02de
*								   *
Packit 6f02de
* The path name environment variable option is enabled by default, *
Packit 6f02de
* and the environment variable is named LSOFDEVCACHE in the lsof   *
Packit 6f02de
* distribution by the following definition in the dialect's	   *
Packit 6f02de
* machine.h header file:					   *
Packit 6f02de
*								   *
Packit 6f02de
*	#define HASENVDC "LSOFDEVCACHE"				   *
Packit 6f02de
*								   *
Packit 6f02de
* To disable the path name environment variable option, change	   *
Packit 6f02de
* the above line in the dialect's machine.h header file to:	   *
Packit 6f02de
*								   *
Packit 6f02de
*	/* #define HASENVDC "LSOFDEVCACHE" */			   *
Packit 6f02de
*								   *
Packit 6f02de
* or remove it.  To change the name of the environment variable,   *
Packit 6f02de
* change the quoted value of the HASENVDC definition -- e.g., this *
Packit 6f02de
* form changes the environment variable name to "FOOBAR":	   *
Packit 6f02de
*								   *
Packit 6f02de
*	#define HASENVDC "FOOBAR"				   *
Packit 6f02de
*								   *
Packit 6f02de
* You can disable the path name environment option by disabling	   *
Packit 6f02de
* all device cache file processing when you remove or by disabling *
Packit 6f02de
* the HASDCACHE definition in the dialect's machine.h header file. *
Packit 6f02de
*								   *
Packit 6f02de
* The path name environment option is disabled when the lsof	   *
Packit 6f02de
* process is setuid-root or when the real UID of the lsof process  *
Packit 6f02de
* is root (0).							   *
Packit 6f02de
*								   *
Packit 6f02de
* The path named in an environment variable is read-only unless    *
Packit 6f02de
* the lsof process surrenders setgid permission.  (See Appendix    *
Packit 6f02de
* B.)								   *
Packit 6f02de
*								   *
Packit 6f02de
====================================================================
Packit 6f02de
Packit 6f02de
Packit 6f02de
C.3. Default System-wide Path
Packit 6f02de
=============================
Packit 6f02de
Packit 6f02de
When a default system-wide device cache file path is defined (It's
Packit 6f02de
not enabled by default in the lsof distribution.), lsof will use
Packit 6f02de
it after it discovers no path has been specified by a ``-D'' option
Packit 6f02de
and no path has been specified in the environment variable named
Packit 6f02de
in the string #define HASENVDC of the dialect's machine.h header
Packit 6f02de
file.
Packit 6f02de
Packit 6f02de
Lsof must be able to open the system-wide device cache file --
Packit 6f02de
i.e., it must have read access to the file and search access to
Packit 6f02de
the directories that lead it.  As part of its integrity checks,
Packit 6f02de
lsof requires that the system-wide device cache file's permission
Packit 6f02de
modes be 0644.
Packit 6f02de
Packit 6f02de
When lsof discovers that the named system-wide device cache file
Packit 6f02de
doesn't exist, it will attempt to open a personal device cache file
Packit 6f02de
should that path formation option be enabled.  This is the *only*
Packit 6f02de
case where lsof will attempt to use two device cache file paths.
Packit 6f02de
Packit 6f02de
The system-wide device cache file is read-only; lsof will never
Packit 6f02de
attempt to write to it.  However, when the real UID of the lsof
Packit 6f02de
process is root, that process may name the system-wide device
Packit 6f02de
cache file with ``-D[b|u]<path>''.
Packit 6f02de
Packit 6f02de
====================================================================
Packit 6f02de
*								   *
Packit 6f02de
* The system-wide file path option is disabled by default in the   *
Packit 6f02de
* lsof distribution.  This place-marking definition in a dialect's *
Packit 6f02de
* machine.h header file may be altered to enable a system-wide	   *
Packit 6f02de
* device cache file path:					   *
Packit 6f02de
*								   *
Packit 6f02de
*	/* #define HASSYSDC "/your/choice/of/path" */		   *
Packit 6f02de
*								   *
Packit 6f02de
* To enable the system-wide name option, declaring that its path   *
Packit 6f02de
* is ``/foo/bar/lsof.dc'', change the above line in the dialect's   *
Packit 6f02de
* machine.h header file to:					   *
Packit 6f02de
*								   *
Packit 6f02de
*	#define HASSYSDC "/foo/bar/lsof.dc"			   *
Packit 6f02de
*								   *
Packit 6f02de
* or change the quoted string of the definition to the path of	   *
Packit 6f02de
* your choice.							   *
Packit 6f02de
*								   *
Packit 6f02de
* You can disable the path name environment option by disabling	   *
Packit 6f02de
* all device cache file processing when you remove or disable the  *
Packit 6f02de
* HASDCACHE definition in the dialect's machine.h header file.	   *
Packit 6f02de
*								   *
Packit 6f02de
* The system-wide device cache file is read-only.		   *
Packit 6f02de
*								   *
Packit 6f02de
====================================================================
Packit 6f02de
Packit 6f02de
Packit 6f02de
C.3.a. Build Procedure
Packit 6f02de
======================
Packit 6f02de
Packit 6f02de
The system administrator must build the system-wide device cache
Packit 6f02de
file at an appropriate time -- e.g., each time the system is booted,
Packit 6f02de
and each time a node is added, deleted or modified in /dev (or
Packit 6f02de
/devices).  The procedure that builds the system-wide device cache
Packit 6f02de
file must use lsof's ``-D[b|u]<path>'' options to build the file,
Packit 6f02de
and must change the file's permission modes to 0644 after it has
Packit 6f02de
been built.
Packit 6f02de
Packit 6f02de
Here's a simple shell script procedure to build a system-wide device
Packit 6f02de
cache file.  It assumes:
Packit 6f02de
Packit 6f02de
    1.  The Unix dialect's kernel supports the interpreter script
Packit 6f02de
	execution option -- i.e., a script whose first line has
Packit 6f02de
	the form ``#!<path_to_interpreter>''.
Packit 6f02de
    
Packit 6f02de
    2.	The chmod, echo, rm, sh, and test programs are located
Packit 6f02de
	in ``/bin''. 
Packit 6f02de
Packit 6f02de
    3.	The string value of the HASSYSDC definition in the dialect's
Packit 6f02de
	machine.h header file is the path ``/your/choice/of/path''.
Packit 6f02de
Packit 6f02de
    4.	The lsof executable is located in ``/usr/local/etc''.
Packit 6f02de
Packit 6f02de
	#!/bin/sh
Packit 6f02de
	#
Packit 6f02de
	# Simple script to build a system-wide device cache file
Packit 6f02de
	# for lsof.
Packit 6f02de
Packit 6f02de
	HASSYSDC=/your/choice/of/path
Packit 6f02de
	/bin/rm -f $HASSYSDC
Packit 6f02de
	/usr/local/etc/lsof -Du$HASSYSDC > /dev/null 2>&1
Packit 6f02de
	if /bin/test $? -ne 0
Packit 6f02de
	then
Packit 6f02de
		/bin/echo "WARNING: failed to create $HASSYSDC"
Packit 6f02de
		exit 1
Packit 6f02de
	fi
Packit 6f02de
	/bin/chmod 0644 $HASSYSDC
Packit 6f02de
	exit 0
Packit 6f02de
Packit 6f02de
The invocation of lsof uses the ``-Du$HASSYSDC'' option to read
Packit 6f02de
the device cache file and recreate it if necessary.  The invocation
Packit 6f02de
can be made more efficient if a known process PID -- e.g., ``-p1''
Packit 6f02de
-- can be specified.  However, if that PID is not always active
Packit 6f02de
when lsof is called, lsof might set its exit code non-zero, causing
Packit 6f02de
the subsequent test to believe that the lsof call failed.  When in
Packit 6f02de
doubt, omit the PID specification and accept the extra lsof processing
Packit 6f02de
time for reporting and discarding all open file information.
Packit 6f02de
Packit 6f02de
Packit 6f02de
C.4. Default Personal Path
Packit 6f02de
==========================
Packit 6f02de
Packit 6f02de
The default personal path option is defined by default in the lsof
Packit 6f02de
distribution.  The path is formed of the home directory of the real
Packit 6f02de
UID of the lsof process, followed optionally by the contents of
Packit 6f02de
the HASPERSDCPATH environment variable, followed by ``.lsof_'',
Packit 6f02de
followed by the first component (characters up to the first period)
Packit 6f02de
of the name returned by gethostname(2).
Packit 6f02de
Packit 6f02de
If gethostname(2) returns nothing, then nothing will follow the
Packit 6f02de
``.lsof_'' string.  If the first character of what gethostname(2)
Packit 6f02de
returns is a `.', then all the gethostname(2) value will follow
Packit 6f02de
the ``/lsof_'' string.  (See the ``%l'' conversion for a way to
Packit 6f02de
make lsof include the entire host name in the path.)
Packit 6f02de
Packit 6f02de
====================================================================
Packit 6f02de
*								   *
Packit 6f02de
* The personal path option is enabled by default in the lsof	   *
Packit 6f02de
* distribution.  The HASPERSDC #define in a dialect's machine.h	   *
Packit 6f02de
* header is a format specification that tells lsof how to form the *
Packit 6f02de
* personal device cache file path.  The conversions in the format  *
Packit 6f02de
* specification begin with `%' , ala the printf(3) function of the *
Packit 6f02de
* standard I/O library.  These conversions are supported:	   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%%''	causes a single `%' to appear in the path.	   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%0''	is a separator that marks the beginning of a path  *
Packit 6f02de
*		for a setuid-root lsof process or one whose real   *
Packit 6f02de
*		UID is 0.  When lsof reaches this conversion and   *
Packit 6f02de
*		the process is setuid-root or has a real UID of    *
Packit 6f02de
*		root, it erases any previously formed path and	   *
Packit 6f02de
*		restarts with the next HASPERSDC format character. *
Packit 6f02de
*		If lsof reaches this conversion and the process is *
Packit 6f02de
*		not setuid-root and its real UID is not root, path *
Packit 6f02de
*		formation is ended.				   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%h''	causes the home directory of the real UID of the   *
Packit 6f02de
*		lsof process to appear in the path.		   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%l''	causes the full name returned by gethostname(2) to *
Packit 6f02de
*		appear in the path.				   *
Packit 6f02de
*								   * 
Packit 6f02de
*	``%L''	causes the first component of the name returned by *
Packit 6f02de
*		gethostname(2) to appear in the path.  The first   *
Packit 6f02de
*		component is defined to be what appears to the	   *
Packit 6f02de
*		left of the first `.'.  If nothing appears to the  *
Packit 6f02de
*		left then everything will appear in the path.	   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%p''	causes the value of (HASPERSDCPATH) from the	   *
Packit 6f02de
*		process environment to appear in the path.  If the *
Packit 6f02de
*		(HASPERSDCPATH) value doesn't end in a '/', one	   *
Packit 6f02de
*		will be added.					   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%u''	causes the login name associated with the real UID *
Packit 6f02de
*		of the lsof process to appear in the path.	   *
Packit 6f02de
*								   *
Packit 6f02de
*	``%U''	causes the real UID of the lsof process, converted *
Packit 6f02de
*		to a decimal string, to appear in the path.	   *
Packit 6f02de
*								   *
Packit 6f02de
*	All other characters are copied from the format to the	   *
Packit 6f02de
*	path.  CAUTION: THINK VERY CAREFULLY ABOUT THE EFFECT OF   *
Packit 6f02de
*	USING CHARACTERS THAT FORM AN ABSOLUTE COMPONENT LIKE	   *
Packit 6f02de
*	``/tmp'' IN THE FORMAT.  Consider what power your dialect  *
Packit 6f02de
*	might have (e.g., if it is setuid-root) when lsof must	   *
Packit 6f02de
*	create a device cache file at the path.  Consider using a  *
Packit 6f02de
*	``%0'' conversion to declare an alternate path for lsof    *
Packit 6f02de
*	processes that are setuid-root or whose real uid is root.  *
Packit 6f02de
*	See the "How do I put the personal device cache file in    *
Packit 6f02de
*	/tmp?" question and answer in 00FAQ for an explanation of  *
Packit 6f02de
*	this example:						   *
Packit 6f02de
*								   *
Packit 6f02de
*	    #define HASPERSDC "/tmp/.lsof_%u_%l_pers%0%h/.lsof_%L" *
Packit 6f02de
*								   *
Packit 6f02de
* This is the format specification that appears in the machine.h   *
Packit 6f02de
* header files of the lsof distribution:			   *
Packit 6f02de
*								   *
Packit 6f02de
*	#define HASPERSDC "%h/%p.lsof_%L"			   *
Packit 6f02de
*								   *
Packit 6f02de
* It causes the path to be formed from the home directory of the   *
Packit 6f02de
* real UID of the lsof process (``%h''), followed by `/', followed *
Packit 6f02de
* by the contents of the environment variable named by		   *
Packit 6f02de
* HASPERSDCPATH and a trailing `/', as needed (``%p''), followed   *
Packit 6f02de
* by the string ``.lsof_'', and terminated with the first	   *
Packit 6f02de
* component of the host's name (``%L'').			   *
Packit 6f02de
*								   *
Packit 6f02de
* To change the personal path option, change the HASPERSDC string  *
Packit 6f02de
* and recompile lsof.  To disable the personal path option, remove *
Packit 6f02de
* or disable HASPERSDC.  The personal path option is disabled when *
Packit 6f02de
* HASDCACHE is not defined.					   *
Packit 6f02de
*								   *
Packit 6f02de
====================================================================
Packit 6f02de
Packit 6f02de
Packit 6f02de
C.5. Modified Default Personal Path
Packit 6f02de
===================================
Packit 6f02de
Packit 6f02de
The modified default personal path form is a special case of the
Packit 6f02de
default personal path.  In this form the value of the environment
Packit 6f02de
variable named by the HASPERSDCPATH #define is inserted in the
Packit 6f02de
personal path when the ``%p'' conversion appears in the HASPERSDC
Packit 6f02de
format specification.
Packit 6f02de
Packit 6f02de
This allows, for example, the lsof user to move personal device
Packit 6f02de
cache files to another branch of the home directory, perhaps to a
Packit 6f02de
sub-directory where multiple device cache files may appear from
Packit 6f02de
different machines that use the same NFS- mounted home directory.
Packit 6f02de
Packit 6f02de
The HASPERSDCPATH definition of the dialect's machine.h header file
Packit 6f02de
names the environment variable.  By default in the lsof distribution
Packit 6f02de
it is LSOFPERSDCPATH.
Packit 6f02de
Packit 6f02de
The modified personal path component is ignored when lsof process
Packit 6f02de
is setuid-root is root, lest it be maliciously or accidentally used in
Packit 6f02de
some convoluted form to access paths the real UID cannot.  The
Packit 6f02de
modified personal path component is also ignored when the real UID
Packit 6f02de
of the lsof process is root (0), so that lsof will not accidentally
Packit 6f02de
use a personal environment value.
Packit 6f02de
Packit 6f02de
If the lsof process surrenders setgid permission (See Appendix B.),
Packit 6f02de
lsof can read from and write to the modified personal path.  If,
Packit 6f02de
however, the lsof process doesn't surrender setgid permission, the
Packit 6f02de
modified personal path is read-only.
Packit 6f02de
Packit 6f02de
If your dialect runs setuid-root or doesn't surrender its setgid
Packit 6f02de
permission, and you want to use the LSOFPERSDCPATH environment
Packit 6f02de
variable to address a collection of device cache files in a
Packit 6f02de
subdirectory, you will have to gather the collection in the
Packit 6f02de
subdirectory yourself with shell copy or move commands.
Packit 6f02de
Packit 6f02de
====================================================================
Packit 6f02de
*								   *
Packit 6f02de
* The modified personal path option is enabled by default in the   *
Packit 6f02de
* lsof distribution with these definitions in the dialect's	   *
Packit 6f02de
* machine.h header file:					   *
Packit 6f02de
*								   *
Packit 6f02de
*	#define HASPERSDCPATH "LSOFPERSDCPATH"			   *
Packit 6f02de
* and								   *
Packit 6f02de
*	#define HASPERSDC "%h/%p.lsof_%L"			   *
Packit 6f02de
*								   *
Packit 6f02de
* The value of the definition is the name of the environment	   *
Packit 6f02de
* variable that contains the modified personal path name	   *
Packit 6f02de
* component that is inserted in the personal path when ``%p''      *
Packit 6f02de
* appears in HASPERSDC.  See the Default Personal Path section	   *
Packit 6f02de
* for a complete description of the ``%p'' conversion.		   *
Packit 6f02de
*								   *
Packit 6f02de
* To disable the modified personal path name component, disable	   *
Packit 6f02de
* the HASPERSDCPATH definition in the dialect's machine.h header   *
Packit 6f02de
* file -- e.g., change it to:					   *
Packit 6f02de
*								   *
Packit 6f02de
*	/* #define HASPERSDCPATH "LSOFPERSDCPATH" */		   *
Packit 6f02de
*								   *
Packit 6f02de
* or remove the definition altogether.  If you do this, don't	   *
Packit 6f02de
* forget to remove any ``%p'' conversion from HASPERSDC.	   *
Packit 6f02de
*								   *
Packit 6f02de
* The modified personal path option is disabled when HASDCACHE is  *
Packit 6f02de
* not defined.							   *
Packit 6f02de
*								   *
Packit 6f02de
* The modified personal path environment variable value is ignored *
Packit 6f02de
* when the lsof process is setuid-root or when the real UID of	   *
Packit 6f02de
* the lsof process is root (0).					   *
Packit 6f02de
*								   *
Packit 6f02de
* The modified personal path is read-only when the lsof process	   *
Packit 6f02de
* doesn't surrender its setgid permission.			   *
Packit 6f02de
*								   *
Packit 6f02de
====================================================================
Packit 6f02de
Packit 6f02de
Packit 6f02de
D. Displaying the Default Path
Packit 6f02de
==============================
Packit 6f02de
Packit 6f02de
Whatever device cache file path formation options you decide to
Packit 6f02de
use, remember that the lsof help output, displayed in response to
Packit 6f02de
its ``-h'' or ``-?'' help options, will display the read-mode
Packit 6f02de
default (the highest numbered) path that lsof has been enabled to
Packit 6f02de
form from which it will read.
Packit 6f02de
Packit 6f02de
Since some paths are read-only, the path displayed in help option
Packit 6f02de
output may not be the one to which lsof will write, should that
Packit 6f02de
become necessary.  To see the read-only and write device cache file
Packit 6f02de
paths, environment variable names, and the personal device cache
Packit 6f02de
file format specification (HASPERSDC), use the -D? option.
Packit 6f02de
Packit 6f02de
Packit 6f02de
Appendix A, Unix Dialects Without a Device Cache
Packit 6f02de
================================================
Packit 6f02de
Packit 6f02de
Linux lsof implementations that obtain their information from files
Packit 6f02de
in the /proc file system do not have device cache support.  Generally
Packit 6f02de
lsof for Linux versions 2.1.72 and greater are /proc based.
Packit 6f02de
Packit 6f02de
Packit 6f02de
Appendix B, Lsof Dialects and Their Permissions
Packit 6f02de
===============================================
Packit 6f02de
Packit 6f02de
These are the permissions recommended in the lsof distribution.
Packit 6f02de
Packit 6f02de
Packit 6f02de
Appendix B.1 Setuid-root Lsof Dialects 
Packit 6f02de
======================================
Packit 6f02de
Packit 6f02de
These dialect versions of lsof need root permission.  For general
Packit 6f02de
use they may have to be installed setuid-root.
Packit 6f02de
Packit 6f02de
    Apple Darwin 9 and Mac OS X 10.[567]
Packit 6f02de
    HP-UX 11.11 and 11.23
Packit 6f02de
    Linux (no device cache support needed)
Packit 6f02de
Packit 6f02de
Packit 6f02de
Appendix B.2 Setgid Lsof Dialects That Surrender Setgid Permission
Packit 6f02de
==================================================================
Packit 6f02de
Packit 6f02de
Lsof versions for these dialects have WILLDROPGID defined in their
Packit 6f02de
machine.h header files.
Packit 6f02de
Packit 6f02de
    AIX 5.[12] and 5.3-ML1
Packit 6f02de
    FreeBSD 4.x, 4.1x, 5.x and [6789].x for x86-based systems
Packit 6f02de
    FreeBSD 5.x, [6789].x and 1[012].x for Alpha, AMD64 and Sparc64
Packit 6f02de
	based systems
Packit 6f02de
    HP-UX 11.00
Packit 6f02de
    NetBSD 1.[456], 2.x and 3.x for Alpha, x86, and SPARC-based
Packit 6f02de
	systems
Packit 6f02de
    NEXTSTEP 3.[13]
Packit 6f02de
    OpenBSD 2.[89] and 3.[0-9] for x86-based systems
Packit 6f02de
    OPENSTEP 4.x
Packit 6f02de
    SCO OpenServer Release 5.0.4 for x86-based systems
Packit 6f02de
    SCO|Caldera UnixWare 7.1.4 for x86-based systems
Packit 6f02de
    Solaris 2.6, 8, 9 and 10
Packit 6f02de
    Tru64 UNIX 5.1
Packit 6f02de
Packit 6f02de
Packit 6f02de
Vic Abell <abe@purdue.edu>
Packit 6f02de
February 14, 2018