Fix renameat(2) for CAPABILITIES kernels.
When renameat(2) is used with: - absolute path for to; - tofd not set to AT_FDCWD; - the target exists kern_renameat() requires CAP_UNLINK capability on tofd, but corresponding namei ni_filecap is not initialized at all because the lookup is absolute. As result, the check was done against empty filecap and syscall fails erronously. Fix it by creating a return flags namei member and reporting if the lookup was absolute, then do not touch to.ni_filecaps at all. PR: 222258 Reviewed by: jilles, ngie Sponsored by: The FreeBSD Foundation MFC after: 1 week X-MFC-note: KBI breakage Differential revision: https://reviews.freebsd.org/D19096
This commit is contained in:
parent
ca4620a431
commit
fe9ffad6ed
@ -410,6 +410,7 @@ namei(struct nameidata *ndp)
|
||||
dp = NULL;
|
||||
cnp->cn_nameptr = cnp->cn_pnbuf;
|
||||
if (cnp->cn_pnbuf[0] == '/') {
|
||||
ndp->ni_resflags |= NIRES_ABS;
|
||||
error = namei_handle_root(ndp, &dp);
|
||||
} else {
|
||||
if (ndp->ni_startdir != NULL) {
|
||||
@ -1302,6 +1303,7 @@ NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg,
|
||||
ndp->ni_dirp = namep;
|
||||
ndp->ni_dirfd = dirfd;
|
||||
ndp->ni_startdir = startdir;
|
||||
ndp->ni_resflags = 0;
|
||||
filecaps_init(&ndp->ni_filecaps);
|
||||
ndp->ni_cnd.cn_thread = td;
|
||||
if (rightsp != NULL)
|
||||
|
@ -3544,10 +3544,10 @@ again:
|
||||
goto out;
|
||||
}
|
||||
#ifdef CAPABILITIES
|
||||
if (newfd != AT_FDCWD) {
|
||||
if (newfd != AT_FDCWD && (tond.ni_resflags & NIRES_ABS) == 0) {
|
||||
/*
|
||||
* If the target already exists we require CAP_UNLINKAT
|
||||
* from 'newfd'.
|
||||
* from 'newfd', when newfd was used for the lookup.
|
||||
*/
|
||||
error = cap_check(&tond.ni_filecaps.fc_rights,
|
||||
&cap_unlinkat_rights);
|
||||
|
@ -87,6 +87,10 @@ struct nameidata {
|
||||
*/
|
||||
struct vnode *ni_vp; /* vnode of result */
|
||||
struct vnode *ni_dvp; /* vnode of intermediate directory */
|
||||
/*
|
||||
* Results: flags returned from namei
|
||||
*/
|
||||
u_int ni_resflags;
|
||||
/*
|
||||
* Shared between namei and lookup/commit routines.
|
||||
*/
|
||||
@ -159,6 +163,11 @@ struct nameidata {
|
||||
#define NOCAPCHECK 0x20000000 /* do not perform capability checks */
|
||||
#define PARAMASK 0x3ffffe00 /* mask of parameter descriptors */
|
||||
|
||||
/*
|
||||
* Namei results flags
|
||||
*/
|
||||
#define NIRES_ABS 0x00000001 /* Path was absolute */
|
||||
|
||||
/*
|
||||
* Flags in ni_lcf, valid for the duration of the namei call.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user