Link to home
Start Free TrialLog in
Avatar of Dragon_Krome
Dragon_Krome

asked on

procfs detection

Hi,

I need a reliable method of detecting a proc filesystem mounted under an directory (not necessarily /proc) which would work under Linux, *BSD and Solaris (and eventually other UNIX-like systems).

This is more like a programming issue, but i'm only interested in a method, a system call (even platform specific) or something, but *reliable*. It also needs to detect a procfs if mounted via --bind (on linux).

The methods i've thought of are: parsing /etc/mtab and using statfs(), both of them not so reliable..

Does anybody else know other methods?

Thank you
Avatar of gheist
gheist
Flag of Belgium image

There is no reliable way as you noticed. There is no standard purpose for procfs either.
Avatar of leisner
leisner

agree with gheist -- there's no standard...

You may as well have seperate conditional stanzas for each system -- then use the right stanza
for each system...the information is different, and common information is presented differently...

What do you want to accomplish?
Avatar of Dragon_Krome

ASKER

I'm trying to do something like a file integrity checker and i need to skip over procfs, sysfs etc.. stuff like that.
oh, look how gnu find and df work...df can identify file systems --  see how df handles the -T
option to detect file systems...but you'll have to do system calls on each directory to
see if its a mount point (I think stat) and there's an fstype for proc file systems...

(I'm on a windows system right now and don't have a linux system I can go to right now...)

If you have any quesitons about the source, feel free to ask...

locate also has a syntax where you can specify what types of file systems to skip -- look at updatedb
to see how they do it...
nor find nor df open the files... the problem i'm afraid of is getting stuck in a file like /proc/kcore and/or checksumming useless files (like the others in /proc).

Of course, i could create an exclusion list, but this will be kinda hard to mantain and useless if a procfs is mounted in a non-standard place...

I'm going to take a look at find and df though, to see if i find something useful. But i have a hunch that df uses /etc/mtab.
ASKER CERTIFIED SOLUTION
Avatar of leisner
leisner

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You know /dev is even not always a filesystem, but better avoid it anyway.
Avatar of Arty K
So the question may be reformulated: is there a relyable way to detect local disk based file systems?

gheist righ, there is no reliable and portable way to detect memory based or 'generated' filesystems.

One 'hack' soltion however exists.
It may be based on that fact, that 'procfs' driver _typically_ doesn't support 'mmap' functionality. And mmap() syscall is portable.
You just need to find first file below the mounted point in question, open it RD_ONLY and try to mmap().
If you will get an error like 'ENOSYS' then you are probably on wrong FS (this may be not procfs, but any other no mmap() support).


Interesting idea that mmap() thing, but also unreliable.

I could try to use statfs(), but  the filesystem id-s are not standardized in any way, afaik, so i can't rely on those values not changing (i'm kinda trying to build a closed source solution, so compiling on the specific platform from source code would be  out of the question :-s ).
You cannot have that all in single source file without #IFDEF.
i'm aware of that...  i think i'm going to #ifdef even if I use statfs or getmntent or such...
i was just hoping that these things would be standardised by now and it wouldn't be such a problem. :-s
One is called PASC thet makes POSIX standard, another is LSB - Linux Standard Base. Newer Linuces obey "Filesystem Hirearchy Standard", ask google, maybe you dig up least common denominator of some function that gives you what you need.
1 #!/bin/bash
   2 # pid-identifier.sh: Gives complete path name to process associated with pid.
   3
   4 ARGNO=1  # Number of arguments the script expects.
   5 E_WRONGARGS=65
   6 E_BADPID=66
   7 E_NOSUCHPROCESS=67
   8 E_NOPERMISSION=68
   9 PROCFILE=exe
  10
  11 if [ $# -ne $ARGNO ]
  12 then
  13   echo "Usage: `basename $0` PID-number" >&2  # Error message >stderr.
  14   exit $E_WRONGARGS
  15 fi  
  16
  17 pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 )
  18 # Checks for pid in "ps" listing, field #1.
  19 # Then makes sure it is the actual process, not the process invoked by this script.
  20 # The last "grep $1" filters out this possibility.
  21 if [ -z "$pidno" ]  # If, after all the filtering, the result is a zero-length string,
  22 then                # no running process corresponds to the pid given.
  23   echo "No such process running."
  24   exit $E_NOSUCHPROCESS
  25 fi  
  26
  27 # Alternatively:
  28 #   if ! ps $1 > /dev/null 2>&1
  29 #   then                # no running process corresponds to the pid given.
  30 #     echo "No such process running."
  31 #     exit $E_NOSUCHPROCESS
  32 #    fi
  33
  34 # To simplify the entire process, use "pidof".
  35
  36
  37 if [ ! -r "/proc/$1/$PROCFILE" ]  # Check for read permission.
  38 then
  39   echo "Process $1 running, but..."
  40   echo "Can't get read permission on /proc/$1/$PROCFILE."
  41   exit $E_NOPERMISSION  # Ordinary user can't access some files in /proc.
  42 fi  
  43
  44 # The last two tests may be replaced by:
  45 #    if ! kill -0 $1 > /dev/null 2>&1 # '0' is not a signal, but
  46                                       # this will test whether it is possible
  47                                       # to send a signal to the process.
  48 #    then echo "PID doesn't exist or you're not its owner" >&2
  49 #    exit $E_BADPID
  50 #    fi
  51
  52
  53
  54 exe_file=$( ls -l /proc/$1 | grep "exe" | awk '{ print $11 }' )
  55 # Or       exe_file=$( ls -l /proc/$1/exe | awk '{print $11}' )
  56 #
  57 # /proc/pid-number/exe is a symbolic link
  58 # to the complete path name of the invoking process.
  59
  60 if [ -e "$exe_file" ]  # If /proc/pid-number/exe exists...
  61 then                 # the corresponding process exists.
  62   echo "Process #$1 invoked by $exe_file."
  63 else
  64   echo "No such process running."
  65 fi  
  66
  67
  68 # This elaborate script can *almost* be replaced by
  69 # ps ax | grep $1 | awk '{ print $5 }'
  70 # However, this will not work...
  71 # because the fifth field of 'ps' is argv[0] of the process,
  72 # not the executable file path.
  73 #
  74 # However, either of the following would work.
  75 #       find /proc/$1/exe -printf '%l\n'
  76 #       lsof -aFn -p $1 -d txt | sed -ne 's/^n//p'
  77
  78 # Additional commentary by Stephane Chazelas.
  79
  80 exit 0
sorry, but i fail to see how this would help me
Dragon_Krome, gheist give the best answer - no reliable and portable way. It's better to ask user which FS to exclude and use /proc by default
:)

Wouldn't be funny for a "security" tool to ask the user where he has mounted his proc?  :)

In the mean while, since i haven't found a reliable way, i'm using  getmntent() (and similar on other OS) and with a little bit of parsing tricks i managed to detect even --bind ed  procfs'
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept leisner http:#16295106

Any objections should be posted here in the next 4 days. After that time, the question will be closed.

gheist
EE Cleanup Volunteer
Closest to your described solution.