>> Therefore, while it may be possible to attempt to work around this
>> in Postfix, the only sensible solution is at the OS level.
> 
> Alas, those linking restrictions are still disabled by default on a
> vanilla linux kernel (upstream rejected the patch to enable them), and
> on every non-linux OS.

Indeed, but Linux users can enable the sysctl in question.

> If you absolutely must do a recursive, *automated* ownership change, the
> best defense that I'm aware of is to immediately call fstatat() on the
> fd obtained from openat() at each stage of the recursive traversal. If
> the descriptor has more than one link, reject it as suspicious. There's
> still a tiny window between openat() and fstatat() where the attacker
> can delete his link (so that your fd points to something juicy, but the
> link count is 1), but AFAIK that's as good as it gets.

It is rather difficult to avoid the race, especially when using standard
command-line tools, rather than writing custom code.

> If you need to do a recursive chown that isn't automated -- like for
> example to update $old_mail_owner to $new_mail_owner -- then e.g. GNU
> chown has the "--from" option to prevent $old_mail_owner from
> introducing hard links.

This could still be subject to a race, if not done via fstat() + fchown().
And it is GNU-chown-specific, which makes it somewhat unattractive for
Postfix.

> The best case is when you don't really need to do the recursive chown at
> all. Since we have
> 
>  $queue_directory:d:root:-:755:uc

Unfortunately, the recursion is needed, if a new package or a system
upgrade changes the mail_owner, with already queued mail then having
incorrect ownership.  Hence the use of "set-permissions" in package
upgrade scripts.

Doing this portably from the shell is too painful.  The Linux feature
should be enabled by default, and introduced in other systems.

Even doing this in C, without race conditions, takes some care when the
files in question are not newly created with O_EXCL.  One would have
to check with fstat() that each open file has link count 1 and still
matches the lstat() data of the path used to open it.  Then, if that's
true, one can perhaps safely fchown() the file descriptor.

Directories are generally simpler, except perhaps on MacOS/X systems
where HFS+ has some sort of directory hard-links, which could make
that rather complicated.

-- 
        Viktor.

Reply via email to