If the target file already exists, check for the CAP_UNLINKAT capabiity right

on the target directory descriptor, but only if this is renameat(2) and real
target directory descriptor is given (not AT_FDCWD). Without this fix regular
rename(2) fails if the target file already exists.

Reported by:	Michael Butler <imb@protected-networks.net>
Reported by:	Larry Rosenman <ler@lerctr.org>
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Pawel Jakub Dawidek 2013-03-02 09:58:47 +00:00
parent fe138cc2af
commit 6d4e99aaef

View File

@ -3556,13 +3556,16 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new,
goto out;
}
#ifdef CAPABILITIES
/*
* If the target already exists we require CAP_UNLINKAT
* from 'newfd'.
*/
error = cap_check(tond.ni_filecaps.fc_rights, CAP_UNLINKAT);
if (error != 0)
goto out;
if (newfd != AT_FDCWD) {
/*
* If the target already exists we require CAP_UNLINKAT
* from 'newfd'.
*/
error = cap_check(tond.ni_filecaps.fc_rights,
CAP_UNLINKAT);
if (error != 0)
goto out;
}
#endif
}
if (fvp == tdvp) {