We will need to call putname() before do_renameat2() returning -EINVAL to avoid memory leaks. Fixes: 3c5499fa56f5 ("fs: make do_renameat2() take struct filename") Signed-off-by: Qian Cai <cai@xxxxxxxxxx> --- fs/namei.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 27f5a4e025fd..9dc5e1b139c9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4362,11 +4362,11 @@ int do_renameat2(int olddfd, struct filename *oldname, int newdfd, int error; if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) - return -EINVAL; + goto out; if ((flags & (RENAME_NOREPLACE | RENAME_WHITEOUT)) && (flags & RENAME_EXCHANGE)) - return -EINVAL; + goto out; if (flags & RENAME_EXCHANGE) target_flags = 0; @@ -4486,6 +4486,14 @@ int do_renameat2(int olddfd, struct filename *oldname, int newdfd, } exit: return error; +out: + if (!IS_ERR(oldname)) + putname(oldname); + + if (!IS_ERR(newname)) + putname(newname); + + return -EINVAL; } SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname, -- 2.28.0