mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add name length checks to renameat(2).
In Linux, the callers of fs/namei.c:do_renameat2() do this check by calling fs/namei.c:getname(). This is important of consistency with Linux. Also, without this we can see panics in overlayfs rename if new file's name is too long. Because upperlayer RenameAt operation would succeed but SetXattr operation will fail leading to an inconsistent state. PiperOrigin-RevId: 464173793
This commit is contained in:
@@ -1486,6 +1486,9 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
return linuxerr.EBUSY
|
||||
}
|
||||
if len(newName) > MaxFilenameLen {
|
||||
return linuxerr.ENAMETOOLONG
|
||||
}
|
||||
mnt := rp.Mount()
|
||||
if mnt != oldParentVD.Mount() {
|
||||
return linuxerr.EXDEV
|
||||
|
||||
@@ -707,6 +707,9 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
return linuxerr.EBUSY
|
||||
}
|
||||
if len(newName) > linux.NAME_MAX {
|
||||
return linuxerr.ENAMETOOLONG
|
||||
}
|
||||
|
||||
err = checkCreateLocked(ctx, rp.Credentials(), newName, dstDir)
|
||||
switch {
|
||||
|
||||
@@ -1081,6 +1081,9 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
return linuxerr.EBUSY
|
||||
}
|
||||
// Do not check for newName length, since different filesystem
|
||||
// implementations impose different name limits. upperfs.RenameAt() will fail
|
||||
// appropriately if it has to.
|
||||
mnt := rp.Mount()
|
||||
if mnt != oldParentVD.Mount() {
|
||||
return linuxerr.EXDEV
|
||||
|
||||
@@ -532,6 +532,9 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
return linuxerr.EBUSY
|
||||
}
|
||||
if len(newName) > fs.maxFilenameLen {
|
||||
return linuxerr.ENAMETOOLONG
|
||||
}
|
||||
mnt := rp.Mount()
|
||||
if mnt != oldParentVD.Mount() {
|
||||
return linuxerr.EXDEV
|
||||
|
||||
@@ -494,6 +494,10 @@ func (vfs *VirtualFilesystem) RenameAt(ctx context.Context, creds *auth.Credenti
|
||||
oldParentVD.DecRef(ctx)
|
||||
return linuxerr.EBUSY
|
||||
}
|
||||
if len(oldName) > linux.NAME_MAX {
|
||||
oldParentVD.DecRef(ctx)
|
||||
return linuxerr.ENAMETOOLONG
|
||||
}
|
||||
|
||||
if !newpop.Path.Begin.Ok() {
|
||||
oldParentVD.DecRef(ctx)
|
||||
|
||||
@@ -88,6 +88,16 @@ TEST(RenameTest, FileToSameDirectory) {
|
||||
EXPECT_THAT(Exists(newpath), IsPosixErrorOkAndHolds(true));
|
||||
}
|
||||
|
||||
TEST(RenameTest, FileNameTooLong) {
|
||||
auto old_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
auto new_base = NextTempBasename();
|
||||
int padding = (NAME_MAX + 1) - new_base.size();
|
||||
new_base.append(padding, 'x');
|
||||
auto new_path = JoinPath(Dirname(old_file.path()), new_base);
|
||||
ASSERT_THAT(rename(old_file.path().c_str(), new_path.c_str()),
|
||||
SyscallFailsWithErrno(ENAMETOOLONG));
|
||||
}
|
||||
|
||||
TEST(RenameTest, RenameAfterWritableFDAndChmod) {
|
||||
// Restore will require re-opening the writable FD which will fail.
|
||||
const DisableSave ds;
|
||||
|
||||
Reference in New Issue
Block a user