On Thu, Nov 17, 2005 at 03:59:58PM +0100, Michael Kerrisk wrote:

> > It appears you *have* to open in blocking mode in order to 
> > open a leased file at all,
> 
> Yes.
> 
> > but that's not clear from the description.
> 
> Again, I would say that's fairly clear from the man page:
> if the open() call returns (i.e., fails) with EWOULDBLOCK, 
> then clearly the file was not opened.  But again, it might 
> help to add a little more text.
> 
> > It wouldn't be so bad to open in blocking mode since a lease is 
> > guaranteed
> > to be broken after a certain timeout.  But a naive implementation would
> > introduce a security hole since the file might be replaced by surprise
> > with a FIFO, which has no open timeout at all.
> 
> I do not understand this last piece.

The above three things tie together: if you're correct and the
lease-breaking steps are followed even with O_NONBLOCK, it's obvious that
you could *potentially* be able to open a leased file with O_NONBLOCK
eventually, by following steps like this:

        - open() -> EWOULDBLOCK
        - wait a while
        - open() -> success

That's because the lease *starts* to get broken on the first open(), and
probably is finished being broken by your second or third try.  So the first
claim above, that you *have* to open in blocking mode, is not strictly true. 
It would be true if opening with O_NONBLOCK definitely *doesn't* ask to
start the lease breaking-steps; that's the part I thought was unclear.  (The
clarification you added about it is good, assuming it's correct.)

But essentially, even if this might work eventually, it's unsafe, because
what *might* happen is this:

        - open() -> EWOULDBLOCK
        - lease gets broken
        - lease gets reacquired
        - open() -> EWOULDBLOCK
        - ...

The only way to guarantee that you'll ever get to open the file within some
reasonable time is to open it in blocking mode.

This might be a very common case.  I know that if I was writing a
lease-using program, and I knew that giving up my lease was part of a chain
of events that guaranteed the next guy he *could* open the file immediately,
and the open succeeded immediately when I gave up my lease, then I might
simply give up the lease and then blocking-reacquire it.  That minimizes the
time I *don't* have my lease, while supposedly not getting in anyone's way.

And so:

>        If the lease breaker's blocked open() or truncate()  is
>        interrupted  by  a signal handler, then the system call
>        fails with the error EINTR, but the other  steps  still
>        occur  as  described  above.   If  the lease breaker is
>        killed by a signal while blocked  in  open()  or  trun-
>        cate(),  then  the other steps still occur as described
>        above.  If the lease breaker specifies  the  O_NONBLOCK
>        flag  when  calling  open(),  then the call immediately
>        fails with the error EWOULDBLOCK, but the  other  steps
>        still occur as described above.

In this paragraph, which generally I find good, you might want to caution
that although the steps still occur with O_NONBLOCK, you introduce a race
condition and are not guaranteed to ever successfully open the file unless
you open it in blocking mode.  So I might do this:

        - open(O_NONBLOCK) -> EWOULDBLOCK
        - (no special time delay)
        - open(^O_NONBLOCK) -> success within a short time

And that leads me to explain my final point about the security problem,
which doesn't seem to have an obvious workaround if you use the above method:

        - open(O_NONBLOCK) -> EWOULDBLOCK
        - someone replaces the leased file with a fifo
        - open(^O_NONBLOCK) -> blocks forever

My totally nonblocking daemon may be forced to block in order to acquire a
lease, but the blocking period has a guaranteed maximum, so it's not so bad. 
However, the file might suddenly become a fifo, which has no guaranteed
maximum timeout, and that's bad.

At this point the workarounds are getting slightly crazy, but it looks like
a fork()-and-open()-with-timeout mechanism might be the only safe way to go.

Not sure if you care to document anything to this extent, but my point is
that you might caution about O_NONBLOCK and leases; basically it's not very
useful because there's no guarantee it'll ever work.

Have fun,

Avery


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to