diff --git a/LibOS/shim/src/sys/shim_access.c b/LibOS/shim/src/sys/shim_access.c index a3fb6251..8df9c06e 100644 --- a/LibOS/shim/src/sys/shim_access.c +++ b/LibOS/shim/src/sys/shim_access.c @@ -18,24 +18,7 @@ #include "shim_thread.h" int shim_do_access(const char* file, mode_t mode) { - if (!file) - return -EINVAL; - - if (test_user_string(file)) - return -EFAULT; - - struct shim_dentry* dent = NULL; - int ret = 0; - - lock(&dcache_lock); - - ret = __path_lookupat(NULL, file, LOOKUP_ACCESS | LOOKUP_FOLLOW, &dent, 0, NULL, false); - if (!ret) - ret = __permission(dent, mode); - - unlock(&dcache_lock); - - return ret; + return shim_do_faccessat(AT_FDCWD, file, mode); } int shim_do_faccessat(int dfd, const char* filename, mode_t mode) { @@ -49,7 +32,7 @@ int shim_do_faccessat(int dfd, const char* filename, mode_t mode) { struct shim_dentry* dent = NULL; int ret = 0; - if ((ret = get_dirfd_dentry(dfd, &dir)) < 0) + if (*filename != '/' && (ret = get_dirfd_dentry(dfd, &dir)) < 0) return ret; lock(&dcache_lock); @@ -63,6 +46,7 @@ int shim_do_faccessat(int dfd, const char* filename, mode_t mode) { out: unlock(&dcache_lock); - put_dentry(dir); + if (dir) + put_dentry(dir); return ret; } diff --git a/LibOS/shim/src/sys/shim_fs.c b/LibOS/shim/src/sys/shim_fs.c index 32e8cf5b..91d78b76 100644 --- a/LibOS/shim/src/sys/shim_fs.c +++ b/LibOS/shim/src/sys/shim_fs.c @@ -26,34 +26,7 @@ /* The kernel would look up the parent directory, and remove the child from the inode. But we are * working with the PAL, so we open the file, truncate and close it. */ int shim_do_unlink(const char* file) { - if (!file) - return -EINVAL; - - if (test_user_string(file)) - return -EFAULT; - - struct shim_dentry* dent = NULL; - int ret = 0; - - if ((ret = path_lookupat(NULL, file, LOOKUP_OPEN, &dent, NULL)) < 0) - return ret; - - if (!dent->parent) - return -EACCES; - - if (dent->state & DENTRY_ISDIRECTORY) - return -EISDIR; - - if (dent->fs && dent->fs->d_ops && dent->fs->d_ops->unlink) { - if ((ret = dent->fs->d_ops->unlink(dent->parent, dent)) < 0) - return ret; - } else { - dent->state |= DENTRY_PERSIST; - } - - dent->state |= DENTRY_NEGATIVE; - put_dentry(dent); - return 0; + return shim_do_unlinkat(AT_FDCWD, file, 0); } int shim_do_unlinkat(int dfd, const char* pathname, int flag) { @@ -70,7 +43,7 @@ int shim_do_unlinkat(int dfd, const char* pathname, int flag) { struct shim_dentry* dent = NULL; int ret = 0; - if ((ret = get_dirfd_dentry(dfd, &dir)) < 0) + if (*pathname != '/' && (ret = get_dirfd_dentry(dfd, &dir)) < 0) return ret; if ((ret = path_lookupat(dir, pathname, LOOKUP_OPEN, &dent, NULL)) < 0) @@ -103,12 +76,13 @@ int shim_do_unlinkat(int dfd, const char* pathname, int flag) { out_dent: put_dentry(dent); out: - put_dentry(dir); + if (dir) + put_dentry(dir); return ret; } int shim_do_mkdir(const char* pathname, int mode) { - return open_namei(NULL, NULL, pathname, O_CREAT | O_EXCL | O_DIRECTORY, mode, NULL); + return shim_do_mkdirat(AT_FDCWD, pathname, mode); } int shim_do_mkdirat(int dfd, const char* pathname, int mode) { @@ -121,12 +95,13 @@ int shim_do_mkdirat(int dfd, const char* pathname, int mode) { struct shim_dentry* dir = NULL; int ret = 0; - if ((ret = get_dirfd_dentry(dfd, &dir)) < 0) + if (*pathname != '/' && (ret = get_dirfd_dentry(dfd, &dir)) < 0) return ret; ret = open_namei(NULL, dir, pathname, O_CREAT | O_EXCL | O_DIRECTORY, mode, NULL); - put_dentry(dir); + if (dir) + put_dentry(dir); return ret; } @@ -177,29 +152,7 @@ mode_t shim_do_umask(mode_t mask) { } int shim_do_chmod(const char* path, mode_t mode) { - struct shim_dentry* dent = NULL; - int ret = 0; - - /* This isn't documented, but that's what Linux does. */ - mode &= 07777; - - if (test_user_string(path)) - return -EFAULT; - - if ((ret = path_lookupat(NULL, path, LOOKUP_OPEN, &dent, NULL)) < 0) - return ret; - - if (dent->fs && dent->fs->d_ops && dent->fs->d_ops->chmod) { - if ((ret = dent->fs->d_ops->chmod(dent, mode)) < 0) - goto out; - } else { - dent->state |= DENTRY_PERSIST; - } - - dent->mode = mode; -out: - put_dentry(dent); - return ret; + return shim_do_fchmodat(AT_FDCWD, path, mode); } int shim_do_fchmodat(int dfd, const char* filename, mode_t mode) { @@ -216,7 +169,7 @@ int shim_do_fchmodat(int dfd, const char* filename, mode_t mode) { struct shim_dentry* dent = NULL; int ret = 0; - if ((ret = get_dirfd_dentry(dfd, &dir)) < 0) + if (*filename != '/' && (ret = get_dirfd_dentry(dfd, &dir)) < 0) return ret; if ((ret = path_lookupat(dir, filename, LOOKUP_OPEN, &dent, NULL)) < 0) @@ -233,7 +186,8 @@ int shim_do_fchmodat(int dfd, const char* filename, mode_t mode) { out_dent: put_dentry(dent); out: - put_dentry(dir); + if (dir) + put_dentry(dir); return ret; } @@ -262,23 +216,7 @@ out: } int shim_do_chown(const char* path, uid_t uid, gid_t gid) { - struct shim_dentry* dent = NULL; - int ret = 0; - __UNUSED(uid); - __UNUSED(gid); - - if (!path) - return -EINVAL; - - if (test_user_string(path)) - return -EFAULT; - - if ((ret = path_lookupat(NULL, path, LOOKUP_OPEN, &dent, NULL)) < 0) - return ret; - - /* XXX: do nothing now */ - put_dentry(dent); - return ret; + return shim_do_fchownat(AT_FDCWD, path, uid, gid, 0); } int shim_do_fchownat(int dfd, const char* filename, uid_t uid, gid_t gid, int flags) { @@ -296,7 +234,7 @@ int shim_do_fchownat(int dfd, const char* filename, uid_t uid, gid_t gid, int fl struct shim_dentry* dent = NULL; int ret = 0; - if ((ret = get_dirfd_dentry(dfd, &dir)) < 0) + if (*filename != '/' && (ret = get_dirfd_dentry(dfd, &dir)) < 0) return ret; if ((ret = path_lookupat(dir, filename, LOOKUP_OPEN, &dent, NULL)) < 0) @@ -305,7 +243,8 @@ int shim_do_fchownat(int dfd, const char* filename, uid_t uid, gid_t gid, int fl /* XXX: do nothing now */ put_dentry(dent); out: - put_dentry(dir); + if (dir) + put_dentry(dir); return ret; } @@ -621,7 +560,7 @@ int shim_do_renameat(int olddirfd, const char* oldpath, int newdirfd, const char return -EFAULT; } - if ((ret = get_dirfd_dentry(olddirfd, &old_dir_dent)) < 0) { + if (*oldpath != '/' && (ret = get_dirfd_dentry(olddirfd, &old_dir_dent)) < 0) { goto out; } @@ -634,7 +573,7 @@ int shim_do_renameat(int olddirfd, const char* oldpath, int newdirfd, const char goto out; } - if ((ret = get_dirfd_dentry(newdirfd, &new_dir_dent)) < 0) { + if (*newpath != '/' && (ret = get_dirfd_dentry(newdirfd, &new_dir_dent)) < 0) { goto out; } diff --git a/LibOS/shim/src/sys/shim_open.c b/LibOS/shim/src/sys/shim_open.c index 770d8874..f018f357 100644 --- a/LibOS/shim/src/sys/shim_open.c +++ b/LibOS/shim/src/sys/shim_open.c @@ -88,30 +88,7 @@ size_t shim_do_write(int fd, const void* buf, size_t count) { } int shim_do_open(const char* file, int flags, mode_t mode) { - if (!file || test_user_string(file)) - return -EFAULT; - - if (!(flags & O_CREAT)) { - /* `mode` should be ignored if O_CREAT is not specified, according to man */ - mode = 0; - } else { - /* This isn't documented, but that's what Linux does. */ - mode &= 07777; - } - - struct shim_handle* hdl = get_new_handle(); - if (!hdl) - return -ENOMEM; - - int ret = 0; - ret = open_namei(hdl, NULL, file, flags, mode, NULL); - if (ret < 0) - goto out; - - ret = set_new_fd_handle(hdl, flags & O_CLOEXEC ? FD_CLOEXEC : 0, NULL); -out: - put_handle(hdl); - return ret; + return shim_do_openat(AT_FDCWD, file, flags, mode); } int shim_do_creat(const char* path, mode_t mode) { @@ -133,7 +110,7 @@ int shim_do_openat(int dfd, const char* filename, int flags, int mode) { struct shim_dentry* dir = NULL; int ret = 0; - if ((ret = get_dirfd_dentry(dfd, &dir)) < 0) + if (*filename != '/' && (ret = get_dirfd_dentry(dfd, &dir)) < 0) return ret; struct shim_handle* hdl = get_new_handle(); @@ -151,7 +128,8 @@ int shim_do_openat(int dfd, const char* filename, int flags, int mode) { out_hdl: put_handle(hdl); out: - put_dentry(dir); + if (dir) + put_dentry(dir); return ret; } diff --git a/LibOS/shim/src/sys/shim_pipe.c b/LibOS/shim/src/sys/shim_pipe.c index 4b081caa..59157540 100644 --- a/LibOS/shim/src/sys/shim_pipe.c +++ b/LibOS/shim/src/sys/shim_pipe.c @@ -274,10 +274,8 @@ int shim_do_mknodat(int dirfd, const char* pathname, mode_t mode, dev_t dev) { struct shim_dentry* dir = NULL; struct shim_dentry* dent = NULL; - ret = get_dirfd_dentry(dirfd, &dir); - if (ret < 0) { + if (*pathname != '/' && (ret = get_dirfd_dentry(dirfd, &dir)) < 0) goto out; - } ret = path_lookupat(dir, pathname, LOOKUP_CREATE, &dent, NULL); if (ret < 0 && ret != -ENOENT) { diff --git a/LibOS/shim/src/sys/shim_stat.c b/LibOS/shim/src/sys/shim_stat.c index 2cb0527e..59e8172a 100644 --- a/LibOS/shim/src/sys/shim_stat.c +++ b/LibOS/shim/src/sys/shim_stat.c @@ -91,6 +91,7 @@ out: } int shim_do_readlinkat(int dirfd, const char* file, char* buf, int bufsize) { + int ret; if (!file || test_user_string(file)) return -EFAULT; @@ -102,10 +103,9 @@ int shim_do_readlinkat(int dirfd, const char* file, char* buf, int bufsize) { struct shim_dentry* dent = NULL; struct shim_dentry* dir = NULL; - int ret = get_dirfd_dentry(dirfd, &dir); - if (ret < 0) { + + if (*file != '/' && (ret = get_dirfd_dentry(dirfd, &dir)) < 0) goto out; - } struct shim_qstr qstr = QSTR_INIT; diff --git a/LibOS/shim/test/ltp/ltp.cfg b/LibOS/shim/test/ltp/ltp.cfg index 4adb860e..d2d962fb 100644 --- a/LibOS/shim/test/ltp/ltp.cfg +++ b/LibOS/shim/test/ltp/ltp.cfg @@ -1942,9 +1942,6 @@ skip = yes [rename13] skip = yes -[rename14] -skip = yes - [renameat01] skip = yes