1

Apache has options FollowSymLinks and SymLinksIfOwnerMatch. However, they "should not be considered a security restriction, since symlink testing is subject to race conditions that make it circumventable." Compare this with Samba:

Samba has an option called wide links :

Note: Turning this parameter on when UNIX extensions are enabled will allow UNIX clients to create symbolic links on the share that can point to files or directories outside restricted path exported by the share definition. This can cause access to areas outside of the share. Due to this problem, this parameter will be automatically disabled (with a message in the log file) if the unix extensions option is on.

See the parameter allow insecure wide links if you wish to change this coupling between the two parameters.

Can the Samba option be bypassed via a race condition?

If not, how is Samba able to prevent the race condition? E.g. what sequence of operations can be used to prevent the race condition?

2

It certainly was vulnerable. See CVE-2017-2619.

The patch for this bug includes a new function, called open_dir_safely(). It uses chdir() to enter the directory that contains the file to be opened.

I guess this means you can use getcwd(), to check you are still inside the Samba shared directory. At least that could work quite nicely on Linux, because it has an efficient system call for getcwd(). I have not confirmed exactly what Samba does after chdir().

This is not great if your process has multiple threads, because chdir() affects the whole process :-). Linux-specific programs could instead use open() with the O_PATH flag, and then use readlink() on the open file descriptor under /proc/self/fd/.

The above can provide assurance about the directory that contains the file. To ensure the file name is not resolved as a link when you pass it to open(), you can use the O_NOFOLLOW flag. If it is a symlink, open() will return ELOOP. Then you may readlink() the file and resolve the symlink yourself. This would involve repeating the procedure from the start :-).

If you have to repeat the procedure "too many" times, then you can return failure (ELOOP again). (And the same if you have to retry too many times because someone is playing silly beggars and repeatedly changing the file between open(... O_NOFOLLOW) and readlink()).

On a non-Linux OS, you might not have a very efficient getcwd(). If you have O_PATH, then you can avoid getcwd() by iterating through every segment of the path, using O_PATH + O_NOFOLLOW and manually resolving links.

In future, this problem might be addressed by some specific flag like AT_PATH_BENEATH or O_BENEATH.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.