0

I have fooinit.rt process launched at boot (/etc/init.d/boot.local)

Here is boot.local file

...
/bin/fooinit.rt &
...

I create an order list at job in order to kill fooinit.rt. that is Triggered in C code

and I wrote a stop script (in)which kill -9 pidof fooinit.rt is written Here is stop script

#!/bin/sh
proc_file="/tmp/gdg_list$$"
ps -ef | grep $USER > $proc_file
echo "Stop script is invoked!!"
suff=".rt"
pid=`fgrep "$suff" $proc_file | awk '{print $2}'`
echo "pid is '$pid'"
rm $proc_file

When at job timer expires 'kill -9 pid'( of fooinit.rt) command can not terminate fooinit.rt process!!

I checked pid number printed and the sentence "Stop script is invoked!!" is Ok !

Here is "at" job command in C code (I verified that the stop scriptis is called after 1 min later)

...
case 708: /* There is a trigger signal here*/
{
    result = APP_RES_PRG_OK;
    system("echo '/sbin/stop' | at now + 1 min");

 }
...

On the other hand, It works properly in case launching fooinit.rt manually from shell as a ordinary command. (not from /etc/init.d/boot.local). So kill -9 work and terminates fooinit.rt process

Do you have any idea why kill -9 can not terminate foo.rt process if it is launched from /etc/init.d/boot.local

roll
  • 125
  • 13

1 Answers1

0

Your solution is built around a race condition. There is no guarantee it will kill the right process (an unknowable amount of time can pass between the ps call and the attempt to make use of the pid), plus it's also vulnerable to a tmp exploit: someone could create a few thousand symlinks under /tmp called "gdg_list[1-32767]" that point to /etc/shadow and your script would overwrite /etc/shadow if it runs as root.

Another potential problem is the setting of $USER -- have you made sure it's correct? Your at job will be called as the user your C program runs as, which may not be the same user your fooinit.rt runs as.

Also, your script doesn't include a kill command at all.

A much cleaner way of doing this would be to run your fooinit.rt under some process supervisor like runit and use runit to shut it down when it's no longer needed. That avoids the pid bingo as well as the /tmp attack vector.

But even using pkill -u username -f fooinit.rt would be less racy than the script you provided.

András Korn
  • 171
  • 6
  • I'have solved the prob. "Another potential problem is the setting of $USER -- have you made sure it's correct?" it is the a bingo!!.Thanks. – roll Sep 04 '14 at 09:57
  • Although my c code process (in)which at job is deployed is appearing as root user on ps -ef, it prints nothing when i add this into stop script (echo "User is '$USER'" >> $proc_file). Here is the output--> User is ' ' – roll Sep 04 '14 at 10:07
  • In case launching processes, fooinit.rt, invoke.rt(in which at job is deployed), manually from shell The output is--> User is 'root'. And stop script works properly! – roll Sep 04 '14 at 10:12
  • András, just for curousity, would you tell in detail your first guess about race condition. Do you mention that there must be a certain process name instead of a searched pid? – roll Sep 04 '14 at 10:47
  • The reason i used fgrep searched that's because there is few *rt files other than fooinit.rt. (xx1.rt, xx2.rt, xx3.rt etc..) their names are changable.I want to stop all of them and the only identifier is .rt extension(RunTime) – roll Sep 04 '14 at 11:08
  • The race condition arises because you obtain a process list at time A, then process it for a duration of x seconds and finally send a signal at time B. In those x seconds, the process list can change; existing processes can exit and new ones can start. Some of the new ones may receive the PIDs of the ones that existed at time A. So at time B, you may end up killing a process that was started in the last x seconds, instead of the one whose PID you saw in the `ps` output at time A. – András Korn Sep 05 '14 at 08:18