diff options
author | Seebs <seebs@seebs.net> | 2019-08-02 12:29:04 -0500 |
---|---|---|
committer | Seebs <seebs@seebs.net> | 2019-08-02 12:29:04 -0500 |
commit | 060058bb29f70b244e685b3c704eb0641b736f73 (patch) | |
tree | 76f5761ad3729960e6d89b493fd39eb8c7e6649a | |
parent | 097ca3e245200c4a4333964af59a106c42ff3bca (diff) | |
download | pseudo-master.tar.gz pseudo-master.tar.bz2 pseudo-master.zip |
use *correct* flags for open/openat, also apply them for related statHEADross/mastermaster
When statting a file that we may or may not be opening with O_NOFOLLOW,
we should use lstat (or AT_SYMLINK_NOFOLLOW) to try to get information
about the right file.
Also when we want to check whether a bit is set, we should use & rather
than |. I am an experienced programmer and know the difference between
those.
-rw-r--r-- | ChangeLog.txt | 4 | ||||
-rw-r--r-- | ports/linux/guts/openat.c | 26 | ||||
-rw-r--r-- | ports/linux/wrapfuncs.in | 12 |
3 files changed, 30 insertions, 12 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 329b262..f681596 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +2019-08-02: + * (seebs) Pass flags & O_NOFOLLOW, also use that to influence + stat types. Note. &. Not |. + 2019-08-01: * (seebs) Pass flags|O_NOFOLLOW on when resolving paths with openat. diff --git a/ports/linux/guts/openat.c b/ports/linux/guts/openat.c index 673ea6e..656ac2b 100644 --- a/ports/linux/guts/openat.c +++ b/ports/linux/guts/openat.c @@ -55,9 +55,13 @@ if (flags & O_CREAT) { save_errno = errno; #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS - rc = real___xstat64(_STAT_VER, path, &buf); + if (flags & O_NOFOLLOW) { + rc = real___lxstat64(_STAT_VER, path, &buf); + } else { + rc = real___xstat64(_STAT_VER, path, &buf); + } #else - rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0); + rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); #endif existed = (rc != -1); if (!existed) @@ -72,9 +76,13 @@ if (!(flags & O_NONBLOCK) && ((flags & (O_WRONLY | O_RDONLY | O_RDWR)) != O_RDWR)) { save_errno = errno; #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS - rc = real___xstat64(_STAT_VER, path, &buf); + if (flags & O_NOFOLLOW) { + rc = real___lxstat64(_STAT_VER, path, &buf); + } else { + rc = real___xstat64(_STAT_VER, path, &buf); + } #else - rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0); + rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); #endif if (rc != -1 && S_ISFIFO(buf.st_mode)) { overly_magic_nonblocking = 1; @@ -126,11 +134,17 @@ } #endif #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS - stat_rc = real___xstat64(_STAT_VER, path, &buf); + if (flags & O_NOFOLLOW) { + stat_rc = real___lxstat64(_STAT_VER, path, &buf); + } else { + stat_rc = real___xstat64(_STAT_VER, path, &buf); + } #else - stat_rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0); + stat_rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); #endif + pseudo_debug(PDBGF_FILE, "openat(path %s), flags %o, stat rc %d, stat mode %o\n", + path, flags, stat_rc, buf.st_mode); if (stat_rc != -1) { buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode); if (!existed) { diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in index 4cdbc9c..c5ea7c3 100644 --- a/ports/linux/wrapfuncs.in +++ b/ports/linux/wrapfuncs.in @@ -1,12 +1,12 @@ -int open(const char *path, int flags, ...{mode_t mode}); /* flags=flags|O_NOFOLLOW */ +int open(const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ char *get_current_dir_name(void); int __xstat(int ver, const char *path, struct stat *buf); int __lxstat(int ver, const char *path, struct stat *buf); /* flags=AT_SYMLINK_NOFOLLOW */ int __fxstat(int ver, int fd, struct stat *buf); int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */ int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags); -int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags|O_NOFOLLOW */ -int __openat_2(int dirfd, const char *path, int flags); /* flags=flags|O_NOFOLLOW */ +int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ +int __openat_2(int dirfd, const char *path, int flags); /* flags=flags&O_NOFOLLOW */ int mknod(const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknod */ int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknodat */ int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */ @@ -15,9 +15,9 @@ int fcntl(int fd, int cmd, ...{struct flock *lock}); # just so we know the inums of symlinks char *canonicalize_file_name(const char *filename); int eaccess(const char *path, int mode); -int open64(const char *path, int flags, ...{mode_t mode}); /* flags=flags|O_NOFOLLOW */ -int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags|O_NOFOLLOW */ -int __openat64_2(int dirfd, const char *path, int flags); /* flags=flags|O_NOFOLLOW */ +int open64(const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ +int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ +int __openat64_2(int dirfd, const char *path, int flags); /* flags=flags&O_NOFOLLOW */ int creat64(const char *path, mode_t mode); int stat(const char *path, struct stat *buf); /* real_func=pseudo_stat */ int lstat(const char *path, struct stat *buf); /* real_func=pseudo_lstat, flags=AT_SYMLINK_NOFOLLOW */ |