1

I'm working on security software(SW) for Linux. One thing that our SW does on is that when some process is started, the SW stat()s the process's /proc/ entry and remembers the entry's inode number. When later on the SW needs to ascertain that the process is still running (and hasn't been restarted), it again looks up process's inode and compares to the one remembered. All was fine and dandy until recently I began receiving false alerts for a specifc application - Opera browser 11.10beta. Basically it appears that while Opera was running, the inode number for its /proc/PID entry has changed, which we considered an impossibility. This is a rather big spanner in the works of the SW's security concept - so much relied on the fact that while a process is running, its /proc/ entry's inode remains unchanged.

Could someone please advise as to why such behaviour may be exhibited. Thanks.

abirvalg
  • 128
  • 1
  • 7
  • I now checked other apps, and discovered that this symptom manifests itself with Firefox and Transmission approx after 20mins. of running. – abirvalg Sep 19 '11 at 13:20
  • 1
    What basis did you have for considering the inode changing to be an impossibility? http://lxr.linux.no/linux+v3.0.4/fs/proc/base.c implies otherwise. – Random832 Sep 19 '11 at 14:09

2 Answers2

0

+1 for the defensive programming habits.

Disclaimer In case it isn't obious: I'm just brainstorming along here. It is clear we cannot just give the answer instantaneously, and my thoughts didn't fit in a comment; I will delete this is it doesn't lead to a solution

I'd certainly make sure that the opera hasn't forked/exec-ed itself (sorry that probably insults your intelligence :));

Next, have a look at namespaces and chrooting

Edit

Edit

I'd say that the process ID must have changed (or procfs remounted, visibly to the user process?):

Under /proc we can find general system information and specific process information and statistics. Linux distinguishes different types of information with the inode number. An inode number in Linux is represented as a 32 bit number and a PID (Process Identifier) is represented as a 16 bit number. With this schema, Linux splits the inode number in two halves of 16 bit. The left half is interpreted as a PID number and the right one is interpreted as a class of information. Since a PID=0 is not valid, Linux uses this value to indicate that inode contains global information. (source)

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Hi, I'm sure there was no fork()ing since a forked child would have a different (from the parent) PID. In my case Opera hasn't quit or anything, it had PID 1716 and as I was browsing the web, I did
    if (stat("/proc/1716", &statbuf) == -1) quit(); if (oldinode != stat.st_ino) alert();
    So the inode number for /proc/1716 changed (with opera still running).
    – abirvalg Sep 19 '11 at 13:13
  • @abirvalg: my bet is on the defragmantation, though it requires more (code) analysis; Can you verify that the inodes for non-directories nodes are fixed (or are they changing too, and at the same time)? – sehe Sep 19 '11 at 13:18
  • The above is a mock-up code, of course. All inode values were printf() to the console and checked in /proc with ls -i /proc – abirvalg Sep 19 '11 at 13:24
  • @abirvalg: I never doubted the correctness of the values. I specificly meant that there may be a distinction between the 'permanency' of directory inodes versus _file inodes_ on procfs. From the description, I feel the file inodes should be deterministically dependent on the PID, directory inodes, not so sure – sehe Sep 19 '11 at 13:26
  • 1
    These days, inode numbers are 64 bits while PIDs are 31 bits. Browsing the procfs source code indicates most of the inodes are allocated dynamically when the filesystem is accessed. – Random832 Sep 19 '11 at 14:05
0

Thanks to sehe for pointing in the right direction and to Random832 for finally nailing it. I ran a process and monitored its PID ls -i /proc/21314 . Alas! Every single entry under that directory had its inode number changed after approx. 15 minutes. So inode numbers were never meant to be permanent in procfs :(

abirvalg
  • 128
  • 1
  • 7
  • 1
    It appears you can check the timestamp on the process dir to find the date the process started... maybe this will be a solution for you to guard against the already rather slim chance of a PID being reused before you've had the chance to notice it's exited. – Random832 Sep 27 '11 at 04:33
  • 1
    Thanks for the tip! At the moment I began using /proc/PID/stat's stime(time since the system booted) field. Kernel assigns increasingly larger stime to new processes even if system time gets tampered with. Your proposed solution may be useful in an environment where there is a guarantee that system time can't be tampered with. – abirvalg Sep 29 '11 at 10:50
  • Thanks for the idea to use `/proc/PID/stat`’s starttime field (not stime) (`cut -d' ' -f22`). It would be better if you edit your answer to include this information instead of rambling on without a solution. – Amir Jul 17 '19 at 10:24