Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #1341 from patrickbkr/fix-root-file-executable
Browse files Browse the repository at this point in the history
Fix MVM_file_isexecutable() when being root
  • Loading branch information
jnthn committed Sep 22, 2020
2 parents 21992e6 + 96d32a1 commit 738024f
Showing 1 changed file with 54 additions and 31 deletions.
85 changes: 54 additions & 31 deletions src/io/fileops.c
Expand Up @@ -13,6 +13,19 @@
#define DEFAULT_MODE _S_IWRITE /* work around sucky libuv defaults */
#endif

static MVMint64 file_info_with_error(MVMThreadContext *tc, uv_stat_t* stat, MVMString *filename, MVMint32 use_lstat) {
char * const a = MVM_string_utf8_c8_encode_C_string(tc, filename);
uv_fs_t req;

MVMint64 res = use_lstat
? uv_fs_lstat(NULL, &req, a, NULL)
: uv_fs_stat(NULL, &req, a, NULL);
*stat = req.statbuf;

MVM_free(a);
return res;
}

static uv_stat_t file_info(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat) {
char * const a = MVM_string_utf8_c8_encode_C_string(tc, filename);
uv_fs_t req;
Expand Down Expand Up @@ -202,48 +215,47 @@ MVMint64 MVM_file_exists(MVMThreadContext *tc, MVMString *f, MVMint32 use_lstat)
#ifdef _WIN32
#define FILE_IS(name, rwx) \
MVMint64 MVM_file_is ## name (MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat) { \
if (!MVM_file_exists(tc, filename, use_lstat)) \
uv_stat_t statbuf; \
if (file_info_with_error(tc, &statbuf, filename, use_lstat) < 0) { \
return 0; \
} \
else { \
uv_stat_t statbuf = file_info(tc, filename, use_lstat); \
MVMint64 r = (statbuf.st_mode & S_I ## rwx ); \
return r ? 1 : 0; \
} \
}
FILE_IS(readable, READ)
FILE_IS(writable, WRITE)
MVMint64 MVM_file_isexecutable(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat) {
if (!MVM_file_exists(tc, filename, use_lstat))
MVMint64 r = 0;
uv_stat_t statbuf;
if (file_info_with_error(tc, &statbuf, filename, use_lstat) < 0)
return 0;
else if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
return 1;
else {
MVMint64 r = 0;
uv_stat_t statbuf = file_info(tc, filename, use_lstat);
if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
return 1;
else {
/* true if fileext is in PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC */
MVMString *dot = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, ".");
MVMROOT(tc, dot, {
MVMint64 n = MVM_string_index_from_end(tc, filename, dot, 0);
if (n >= 0) {
MVMString *fileext = MVM_string_substring(tc, filename, n, -1);
char *ext = MVM_string_utf8_c8_encode_C_string(tc, fileext);
char *pext = getenv("PATHEXT");
int plen = strlen(pext);
int i;
for (i = 0; i < plen; i++) {
if (0 == stricmp(ext, pext++)) {
r = 1;
break;
}
/* true if fileext is in PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC */
MVMString *dot = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, ".");
MVMROOT(tc, dot, {
MVMint64 n = MVM_string_index_from_end(tc, filename, dot, 0);
if (n >= 0) {
MVMString *fileext = MVM_string_substring(tc, filename, n, -1);
char *ext = MVM_string_utf8_c8_encode_C_string(tc, fileext);
char *pext = getenv("PATHEXT");
int plen = strlen(pext);
int i;
for (i = 0; i < plen; i++) {
if (0 == stricmp(ext, pext++)) {
r = 1;
break;
}
MVM_free(ext);
MVM_free(pext);
}
});
}
return r;
MVM_free(ext);
MVM_free(pext);
}
});
}
return r;
}
#else

Expand Down Expand Up @@ -277,10 +289,10 @@ static int are_we_group_member(MVMThreadContext *tc, gid_t group) {
}
#define FILE_IS(name, rwx) \
MVMint64 MVM_file_is ## name (MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat) { \
if (!MVM_file_exists(tc, filename, use_lstat)) \
uv_stat_t statbuf; \
if (file_info_with_error(tc, &statbuf, filename, use_lstat) < 0) \
return 0; \
else { \
uv_stat_t statbuf = file_info(tc, filename, use_lstat); \
MVMint64 r = (statbuf.st_mode & S_I ## rwx ## OTH) \
|| (statbuf.st_uid == geteuid() && (statbuf.st_mode & S_I ## rwx ## USR)) \
|| (geteuid() == 0) \
Expand All @@ -290,7 +302,18 @@ static int are_we_group_member(MVMThreadContext *tc, gid_t group) {
}
FILE_IS(readable, R)
FILE_IS(writable, W)
FILE_IS(executable, X)
MVMint64 MVM_file_isexecutable(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat) {
uv_stat_t statbuf;
if (file_info_with_error(tc, &statbuf, filename, use_lstat) < 0)
return 0;
else {
MVMint64 r = (statbuf.st_mode & S_IXOTH)
|| (statbuf.st_uid == geteuid() && (statbuf.st_mode & S_IXUSR))
|| (are_we_group_member(tc, statbuf.st_gid) && (statbuf.st_mode & S_IXGRP))
|| (geteuid() == 0 && (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)));
return r ? 1 : 0;
}
}
#endif

/* Get a MoarVM file handle representing one of the standard streams */
Expand Down

0 comments on commit 738024f

Please sign in to comment.