[base] check if path leads to a valid file name

Passing directories to fopen is not a defined behaviour in C/C++.
A new test case added by https://crrev.com/c/3098189 is trying to
import directories which is expected to fail.

Test however is not passing on some platforms including on S390 Linux
as `fopen` is successful, size gets set to 0 and a (non-existent)
empty file gets returned.

This CL uses `stat` to make sure the path is valid and is
not a directory.

Change-Id: Ibcc762b21145d2198cba07953387a31f39f59300
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3102346
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#76389}
This commit is contained in:
Milad Fa 2021-08-18 00:34:51 -04:00 committed by V8 LUCI CQ
parent 365b7f12f0
commit 7255e1f8a9

View File

@ -586,25 +586,29 @@ class PosixMemoryMappedFile final : public OS::MemoryMappedFile {
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name,
FileMode mode) {
const char* fopen_mode = (mode == FileMode::kReadOnly) ? "r" : "r+";
if (FILE* file = fopen(name, fopen_mode)) {
if (fseek(file, 0, SEEK_END) == 0) {
long size = ftell(file); // NOLINT(runtime/int)
if (size == 0) return new PosixMemoryMappedFile(file, nullptr, 0);
if (size > 0) {
int prot = PROT_READ;
int flags = MAP_PRIVATE;
if (mode == FileMode::kReadWrite) {
prot |= PROT_WRITE;
flags = MAP_SHARED;
}
void* const memory =
mmap(OS::GetRandomMmapAddr(), size, prot, flags, fileno(file), 0);
if (memory != MAP_FAILED) {
return new PosixMemoryMappedFile(file, memory, size);
struct stat statbuf;
// Make sure path exists and is not a directory.
if (stat(name, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) {
if (FILE* file = fopen(name, fopen_mode)) {
if (fseek(file, 0, SEEK_END) == 0) {
long size = ftell(file); // NOLINT(runtime/int)
if (size == 0) return new PosixMemoryMappedFile(file, nullptr, 0);
if (size > 0) {
int prot = PROT_READ;
int flags = MAP_PRIVATE;
if (mode == FileMode::kReadWrite) {
prot |= PROT_WRITE;
flags = MAP_SHARED;
}
void* const memory =
mmap(OS::GetRandomMmapAddr(), size, prot, flags, fileno(file), 0);
if (memory != MAP_FAILED) {
return new PosixMemoryMappedFile(file, memory, size);
}
}
}
fclose(file);
}
fclose(file);
}
return nullptr;
}