7

Possible Duplicate:
access() Security Hole

I quote from man page access(2):

Warning: Using access() to check if a user is authorized to, for example, open a file before actually doing so using open(2) creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. For this reason, the use of this system call should be avoided.

What does this mean, and in what situation would it be a concern?

Community
  • 1
  • 1
Doddy
  • 1,311
  • 1
  • 17
  • 31

3 Answers3

9

It is a classic "Time of check to time of use" race condition.

Douglas Leeder
  • 52,368
  • 9
  • 94
  • 137
  • In what situation would it be a concern? Don't use it to check a user's permissions to read/write a file before `open(2)`ing it... just `open(2)` the file directly. – Conrad Meyer Jul 17 '12 at 15:07
  • 2
    @Conrad: from the `access` man page, "The check is done with the process’s real UID and GID, rather than with the effective IDs as is done when actually attempting an operation. This is to allow set-user-ID programs to easily determine the invoking user’s authority". So if you just `open(2)`, then you will open files that your elevated setuid can access, but the user can't. The problem is that `access` is really only fit for informing the user whether they can access the file, whereas it is erroneously used by people hoping to avoid mis-using elevated privileges. – Steve Jessop Jul 17 '12 at 15:11
  • 1
    In other words, that note in the man page should have read, "this is to allow set-user-ID programs to easily create exploitable flaws when their expectations exceed what `access` delivers" ;-) – Steve Jessop Jul 17 '12 at 15:15
  • @SteveJessop, Ooh, thanks. I missed that difference. Still: just use `open(2)`. And also drop your privileges as appropriate... =) – Conrad Meyer Jul 17 '12 at 15:20
4

This is a security concern only for Set-user-ID and set-group-ID applications. For applications running as the user itself there is no threat, because the operation in question would be rejected by the operating system anyway.

Consider this scenario: you have a UNIX program running as root via set-user-id. The program uses access to check file permissions of another user, and then runs the file as root, but only if the permission check has been successful. Let's say the program is called securerun, and you run it as follows:

securerun myfile

An attacker can make a program that exploits this security hole to run, using this algorithm:

  • Write a file xyz of which the user has executing permissions
  • Start two threads, A and B
  • Thread A waits a few milliseconds, and executes cp norunning xyz to replace xyz with a file that the attacker wants to run, but has no run permissions to do so
  • Thread B calls securerun xyz

If the attacker gets lucky by getting his timing right, your securerun would check the execute permissions on the old xyz, but it would run the new xyz, a copy of norunning that the hacker wasn't supposed to run. Since there is a short time window between the check and the execution, the attacker is bound to get lucky at some point, if he tries his strategy many times in a loop.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

Typical erroneous code:

  • Use access to check whether to read file on user's behalf, in a program running with elevated privileges
  • Short gap here
  • Open file

During the "short gap", the user might be able to manipulate the file system, for example:

ln -f secret_file.txt non_secret_file.txt

Then open will open the secret file for reading, even though it would have failed the access check had the link been in place at the time the check was done.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699