diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc index 68c17d534cd..c98c21d07cc 100644 --- a/lib/Support/Unix/PathV2.inc +++ b/lib/Support/Unix/PathV2.inc @@ -236,6 +236,22 @@ error_code remove(const Twine &path, bool &existed) { SmallString<128> path_storage; StringRef p = path.toNullTerminatedStringRef(path_storage); + struct stat buf; + if (stat(p.begin(), &buf) != 0) { + if (errno != errc::no_such_file_or_directory) + return error_code(errno, system_category()); + existed = false; + return error_code::success(); + } + + // Note: this check catches strange situations. In all cases, LLVM should + // only be involved in the creation and deletion of regular files. This + // check ensures that what we're trying to erase is a regular file. It + // effectively prevents LLVM from erasing things like /dev/null, any block + // special file, or other things that aren't "regular" files. + if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) + return make_error_code(errc::operation_not_permitted); + if (::remove(p.begin()) == -1) { if (errno != errc::no_such_file_or_directory) return error_code(errno, system_category());