diff --git a/lib/finchfs.c b/lib/finchfs.c index 02d12df..43ac048 100644 --- a/lib/finchfs.c +++ b/lib/finchfs.c @@ -299,6 +299,9 @@ finchfs_create_chunk_size(const char *path, int32_t flags, mode_t mode, log_debug("finchfs_create_chunk_size() called path=%s chunk_size=%zu", path, chunk_size); char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } int ret; int fd; struct finch_file *file; @@ -352,7 +355,13 @@ int finchfs_open(const char *path, int32_t flags) { log_debug("finchfs_open() called path=%s", path); - char *p = canonical_path(path); + char *p = NULL; + if (path != NULL) { + p = canonical_path(path); + if (p == NULL) { + return -1; + } + } int ret; int fd; struct finch_file *file; @@ -377,6 +386,9 @@ finchfs_open(const char *path, int32_t flags) file->access = flags & 0b11; file->pos = 0; fs_stat_t st; + if (path == NULL) { + return (fd); + } if (flags & __O_DIRECTORY) { ret = fs_rpc_inode_open_dir(NULL, p, file->eid, &st, 1 << 4); if (ret) { @@ -430,7 +442,8 @@ finchfs_close(int fd) return (-1); } int ret = 0; - if (!S_ISDIR(fd_table[fd].file->mode)) { + if (fd_table[fd].file->path != NULL && + !S_ISDIR(fd_table[fd].file->mode)) { ret = fs_rpc_inode_close( fd_table[fd].file->path, fd_table[fd].file->eid[0], fd_table[fd].file->access, fd_table[fd].file->size); @@ -470,6 +483,9 @@ finchfs_pwrite(int fd, const void *buf, size_t size, off_t offset) if (size == 0) { return (0); } + if (fd_table[fd].file->path == NULL) { + return (size); + } log_debug("finchfs_pwrite() called ino=%zu size=%zu offset=%ld", fd_table[fd].file->i_ino, size, offset); chunk_size = fd_table[fd].file->chunk_size; @@ -557,6 +573,9 @@ finchfs_pread(int fd, void *buf, size_t size, off_t offset) errno = EINVAL; return (-1); } + if (fd_table[fd].file->path == NULL) { + return (0); + } if (fd_table[fd].file->access == O_WRONLY) { errno = EPERM; return (-1); @@ -623,7 +642,7 @@ finchfs_read(int fd, void *buf, size_t size) { log_debug("finchfs_read() called fd=%d size=%zu", fd, size); ssize_t ret; - if (fd < 0 || fd >= fd_table_size || fd_table[fd].file->path == NULL) { + if (fd < 0 || fd >= fd_table_size || fd_table[fd].file == NULL) { errno = EBADF; return (-1); } @@ -668,6 +687,9 @@ finchfs_fsync(int fd) errno = EBADF; return (-1); } + if (fd_table[fd].file->path == NULL) { + return (0); + } int ret; ret = fs_rpc_inode_fsync(fd_table[fd].file->i_ino, fd_table[fd].file->eid[0], @@ -681,6 +703,9 @@ finchfs_unlink(const char *path) log_debug("finchfs_unlink() called path=%s", path); int ret; char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } ret = fs_rpc_inode_unlink(NULL, p); free(p); return (ret); @@ -692,6 +717,9 @@ finchfs_mkdir(const char *path, mode_t mode) log_debug("finchfs_mkdir() called path=%s", path); int ret; char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } mode |= S_IFDIR; ret = fs_rpc_mkdir(NULL, p, mode); free(p); @@ -704,6 +732,9 @@ finchfs_rmdir(const char *path) log_debug("finchfs_rmdir() called path=%s", path); int ret; char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } ret = fs_rpc_inode_unlink_all(NULL, p); free(p); return (ret); @@ -714,6 +745,9 @@ finchfs_stat(const char *path, struct stat *st) { log_debug("finchfs_stat() called path=%s", path); char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } fs_stat_t fst; int ret; ret = fs_rpc_inode_stat(NULL, p, &fst, 0); @@ -743,6 +777,10 @@ finchfs_fstat(int fd, struct stat *st) errno = EBADF; return (-1); } + if (fd_table[fd].file->path == NULL) { + errno = EIO; + return (-1); + } st->st_mode = fd_table[fd].file->mode; st->st_uid = getuid(); st->st_gid = getgid(); @@ -763,6 +801,9 @@ finchfs_readdir(const char *path, void *buf, log_debug("finchfs_readdir() called path=%s", path); int ret; char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } ret = fs_rpc_readdir(p, buf, filler); free(p); return (ret); @@ -776,6 +817,9 @@ finchfs_rename(const char *oldpath, const char *newpath) int ret; char *oldp = canonical_path(oldpath); char *newp = canonical_path(newpath); + if (oldp == NULL || newp == NULL) { + return (-1); + } fs_stat_t st; ret = fs_rpc_inode_stat(NULL, oldp, &st, 0); if (ret) { @@ -804,6 +848,9 @@ finchfs_find(const char *path, const char *query, log_debug("finchfs_find() called path=%s query=%s", path, query); int ret; char *p = canonical_path(path); + if (p == NULL) { + return (-1); + } ret = fs_rpc_find(p, query, param, buf, filler); free(p); return (ret); @@ -836,6 +883,9 @@ finchfs_createat_chunk_size(int dirfd, const char *pathname, int flags, eid = fd_table[dirfd].file->eid; } char *p = canonical_path(pathname); + if (p == NULL) { + return (-1); + } int ret; int fd; struct finch_file *file; @@ -898,6 +948,9 @@ finchfs_openat(int dirfd, const char *pathname, int flags) eid = fd_table[dirfd].file->eid; } char *p = canonical_path(pathname); + if (p == NULL) { + return (-1); + } int ret; int fd; struct finch_file *file; @@ -981,6 +1034,9 @@ finchfs_fstatat(int dirfd, const char *pathname, struct stat *st, int flags) eid = fd_table[dirfd].file->eid; } char *p = canonical_path(pathname); + if (p == NULL) { + return (-1); + } fs_stat_t fst; int ret; ret = fs_rpc_inode_stat(eid, p, &fst, 0); @@ -1018,6 +1074,9 @@ finchfs_mkdirat(int dirfd, const char *pathname, mode_t mode) } int ret; char *p = canonical_path(pathname); + if (p == NULL) { + return (-1); + } mode |= S_IFDIR; ret = fs_rpc_mkdir(eid, p, mode); free(p); @@ -1041,6 +1100,9 @@ finchfs_unlinkat(int dirfd, const char *pathname, int flags) } int ret; char *p = canonical_path(pathname); + if (p == NULL) { + return (-1); + } if (flags & AT_REMOVEDIR) { ret = fs_rpc_inode_unlink_all(eid, p); } else { @@ -1080,6 +1142,9 @@ finchfs_renameat(int olddirfd, const char *oldpath, int newdirfd, int ret; char *oldp = canonical_path(oldpath); char *newp = canonical_path(newpath); + if (oldp == NULL || newp == NULL) { + return (-1); + } fs_stat_t st; ret = fs_rpc_inode_stat(oldeid, oldp, &st, 0); if (ret) { @@ -1108,6 +1173,10 @@ finchfs_getdents(int fd, void *dirp, size_t count) errno = EBADF; return (-1); } + if (fd_table[fd].file->path == NULL) { + errno = ENOTDIR; + return (-1); + } if (!S_ISDIR(fd_table[fd].file->mode)) { errno = ENOTDIR; return (-1); diff --git a/lib/path.c b/lib/path.c index 477122a..af54558 100644 --- a/lib/path.c +++ b/lib/path.c @@ -46,6 +46,11 @@ canonical_path(const char *path) const char *p = path; char *pp; + if (path == NULL) { + errno = EINVAL; + return (NULL); + } + p = skip_slash(p); while (*p) { if (depth >= MAX_DEPTH) { diff --git a/tests/finchfs_test.cc b/tests/finchfs_test.cc index 92c6b4f..65f681e 100644 --- a/tests/finchfs_test.cc +++ b/tests/finchfs_test.cc @@ -1080,6 +1080,19 @@ TEST(FinchfsTest, Dup2) EXPECT_EQ(finchfs_term(), 0); } +TEST(FinchfsTest, DEV_NULL) +{ + EXPECT_EQ(finchfs_init(NULL), 0); + int fd; + fd = finchfs_open(NULL, O_RDWR); + EXPECT_EQ(fd, 0); + char buf[1024]; + EXPECT_EQ(finchfs_write(fd, buf, 1024), 1024); + EXPECT_EQ(finchfs_read(fd, buf, 1024), 0); + EXPECT_EQ(finchfs_close(fd), 0); + EXPECT_EQ(finchfs_term(), 0); +} + static int path_to_target_hash(const char *path, int div) {