Race condition in shlock.c (time window between ValidLock and unlink)

Berend Reitsma berend at asset-control.com
Tue Aug 27 11:24:07 UTC 2002



Hello,

As far as I can tell there is a time window between the ValidLock
returning FALSE and the unlink after that.
There is no guarantee that you are unlinking the same file you just
checked. This means that there is a posibility that two (or more) shlocks
will succeed when they should not ...

In fact I can reliable reproduce it with the following script while
forcing the system into swap.

If this already a known fact, it would be nice to have this at least in
the documentation.

PS: Please don't post my email address to any mailing list or forum or
use it in any source file. Only use my name if you want to refer to me.


--cut-here--

#!/bin/bash

cmd='if shlock -p $$ -f testlock.pid; then p=`cat testlock.pid`
[ $? -eq 0 ] && [ $$ -eq $p ] ||
echo "shlock race condition, testlock.pid=\"$p\" \$\$=\"$$\""
fi'
pids=""
for n in x x x x x x x x x x; do
  (trap "exit 0" 15; while :; do sh -c "$cmd"; done) &
  pids="$pids $!"
done
sleep 30
kill $pids
wait

--cut-here--

A typical run gives the following output:

Can't unlink "testlock.pid", No such file or directory
shlock race condition, testlock.pid="27681" $$="27678"
shlock race condition, testlock.pid="27681" $$="27677"
shlock race condition, testlock.pid="27718" $$="27728"
shlock race condition, testlock.pid="27718" $$="27723"
shlock race condition, testlock.pid="27740" $$="27725"
Can't unlink "testlock.pid", No such file or directory
Can't unlink "testlock.pid", No such file or directory

--cut-here--


Running two shlocks A and B can result in the following
schedule:

Version: inn-2.3.3
File: backends/shlock.c
Format: process linenr line

A 194      while (link(tmp, name) < 0)
A 195          switch (errno) {
A 202          case EEXIST:
A 204              if (ValidLock(name, FALSE))

	B 194      while (link(tmp, name) < 0)
	B 195          switch (errno) {
	B 202          case EEXIST:
	B 204              if (ValidLock(name, FALSE))

A 206              if (unlink(name) < 0) {
A 209              }
A 210          }
A 194      while (link(tmp, name) < 0)
A 212      UnlinkAndExit(tmp, 0);

	B 206              if (unlink(name) < 0) {
	B 209              }
	B 210          }
	B 194      while (link(tmp, name) < 0)
	B 212      UnlinkAndExit(tmp, 0);



-- 

Berend Reitsma

  Asset Control International  |  Phone: +31 (0)512 389100
  It Merkelan 24A              |  Fax:   +31 (0)512 389101
  9244 CX  Beetsterzwaag       |  Email: berend at asset-control.com
  The Netherlands              |  Web:   www.asset-control.com





More information about the inn-bugs mailing list