[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reauthentication implementation flaw due to EINTR

From: Samuel Thibault
Subject: Reauthentication implementation flaw due to EINTR
Date: Mon, 21 Dec 2009 20:43:12 +0100
User-agent: Mutt/1.5.12-2006-07-14


I had been noticing odd issues with sudo when it calls setresuid &
such, it took me some time to understand that there was a flaw in the
reauthentication implementation:

sudo calls setresuid(), which calls setauth(), which (for each FD &
such) allocates a rendez-vous port, calls io_reauthenticate() (RPC
in the underlying FS which calls the auth_server_authenticate()
RPC) and calls the auth_user_authenticate() RPC. These last two
RPCs end up in auth, which uses the rendez-vous port passed along
to make the match. Whichever arrives first leaves information and a
condition variable for the other ; when the latter arrives, it fills its
information and wakes the former.

The issue is that currently, once the user part gets its passthrough
port from the server part, it returns immediately, and setauth() drops
the rendez-vous port, which actually interrupts the server RPCs because
the rendez-vous sender right becomes dead. Quite often scheduling makes
it so that the user is not so fast and the server has time to finish its
duties, but due to the high usage of setresuid in sudo, one every few
tens of sudo calls fail.

The fix I'll use at least on the Debian buildds for now is to make the
auth_user_authenticate() RPC always wait for auth_server_authenticate()
to have called auth_server_authenticate_reply() before returning. I've
been running that in a tight loop the whole afternoon with no issue, so
at least it seems to work much better. However, I'd prefer to make sure
that it works _always_ :)

So my question is: is it sufficient to make the user part wait for
auth_server_authenticate_reply() call completion before freeing the
rendez-vous port, to make sure that auth_server_authenticate() will
never return EINTR because of the death of the rendez-vous port?  Of
course, the rendez-vous port can become dead in the io_reauthenticate()
RPC, but that shouldn't be a problem.

And bonus question: are there other places where we have such
rendez-vous port which might become dead too early and that would need
the same fix?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]