Make path_open return ELOOP on O_NOFOLLOW|O_DIRECTORY on a symlink.
This commit is contained in:
@@ -1780,8 +1780,9 @@ __wasi_errno_t wasmtime_ssp_path_open(
|
|||||||
|
|
||||||
int nfd = openat(pa.fd, pa.path, noflags, 0666);
|
int nfd = openat(pa.fd, pa.path, noflags, 0666);
|
||||||
if (nfd < 0) {
|
if (nfd < 0) {
|
||||||
|
int openat_errno = errno;
|
||||||
// Linux returns ENXIO instead of EOPNOTSUPP when opening a socket.
|
// Linux returns ENXIO instead of EOPNOTSUPP when opening a socket.
|
||||||
if (errno == ENXIO) {
|
if (openat_errno == ENXIO) {
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int ret =
|
int ret =
|
||||||
fstatat(pa.fd, pa.path, &sb, pa.follow ? 0 : AT_SYMLINK_NOFOLLOW);
|
fstatat(pa.fd, pa.path, &sb, pa.follow ? 0 : AT_SYMLINK_NOFOLLOW);
|
||||||
@@ -1789,12 +1790,22 @@ __wasi_errno_t wasmtime_ssp_path_open(
|
|||||||
return ret == 0 && S_ISSOCK(sb.st_mode) ? __WASI_ENOTSUP
|
return ret == 0 && S_ISSOCK(sb.st_mode) ? __WASI_ENOTSUP
|
||||||
: __WASI_ENXIO;
|
: __WASI_ENXIO;
|
||||||
}
|
}
|
||||||
|
// Linux returns ENOTDIR instead of ELOOP when using O_NOFOLLOW|O_DIRECTORY
|
||||||
|
// on a symlink.
|
||||||
|
if (openat_errno == ENOTDIR && (noflags & (O_NOFOLLOW | O_DIRECTORY)) != 0) {
|
||||||
|
struct stat sb;
|
||||||
|
int ret = fstatat(pa.fd, pa.path, &sb, AT_SYMLINK_NOFOLLOW);
|
||||||
|
if (S_ISLNK(sb.st_mode)) {
|
||||||
|
path_put(&pa);
|
||||||
|
return __WASI_ELOOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
path_put(&pa);
|
path_put(&pa);
|
||||||
// FreeBSD returns EMLINK instead of ELOOP when using O_NOFOLLOW on
|
// FreeBSD returns EMLINK instead of ELOOP when using O_NOFOLLOW on
|
||||||
// a symlink.
|
// a symlink.
|
||||||
if (!pa.follow && errno == EMLINK)
|
if (!pa.follow && openat_errno == EMLINK)
|
||||||
return __WASI_ELOOP;
|
return __WASI_ELOOP;
|
||||||
return convert_errno(errno);
|
return convert_errno(openat_errno);
|
||||||
}
|
}
|
||||||
path_put(&pa);
|
path_put(&pa);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user