From f5a2741ec2cfb9b670cae6a74d06e84693a3ee2c Mon Sep 17 00:00:00 2001 From: Mingjie Shen Date: Wed, 28 Jun 2023 23:08:20 -0400 Subject: [PATCH] libc/lib_remove: fix TOCTOU race condition Separately checking the state of a file before operating on it may allow an attacker to modify the file between the two operations. Reference: CWE-367 https://github.com/bminor/glibc/blob/4290aed05135ae4c0272006442d147f2155e70d7/sysdeps/posix/remove.c#L29-L41 Signed-off-by: Mingjie Shen --- libs/libc/stdio/lib_remove.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/libs/libc/stdio/lib_remove.c b/libs/libc/stdio/lib_remove.c index 7798d6cbfc5..66bfb7d8c14 100644 --- a/libs/libc/stdio/lib_remove.c +++ b/libs/libc/stdio/lib_remove.c @@ -51,25 +51,18 @@ int remove(FAR const char *path) { - struct stat buf; - int ret; + /* First try to unlink since this is + * more frequently the necessary action. + */ - /* Check the kind of object pointed by path */ - - ret = stat(path, &buf); - if (ret != 0) + if (unlink(path) != 0 /* If it is indeed a directory... */ + && (errno != EPERM /* ...try to remove it. */ + || rmdir(path) != 0)) { - return ret; + /* Cannot remove the object for whatever reason. */ + + return -1; } - /* Act according to the kind of object */ - - if (S_ISDIR(buf.st_mode)) - { - return rmdir(path); - } - else - { - return unlink(path); - } + return 0; }