Fix some more issues

- ARM Neon headers are now exported in libc/isystem/

- stat() and access() now do a better job reporting which files are
  executable which ones aren't. They do this by reading the first two
  bytes in a file to see if it's `MZ` or `#!`.
This commit is contained in:
Justine Tunney 2023-09-21 11:41:42 -07:00
parent 22cf6e11eb
commit 4f5d5a6813
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
17 changed files with 144 additions and 49 deletions

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -24,7 +25,11 @@
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/mem/mem.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/securityimpersonationlevel.h"
#include "libc/nt/enum/securityinformation.h"
#include "libc/nt/errors.h"
@ -50,18 +55,19 @@
* @see libc/sysv/consts.sh
*/
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
int rc, e;
void *freeme;
int rc;
bool32 result;
uint32_t flagmask;
struct NtSecurityDescriptor *s;
struct NtGenericMapping mapping;
struct NtPrivilegeSet privileges;
int64_t hToken, hImpersonatedToken;
uint32_t secsize, granted, privsize;
int64_t hToken, hImpersonatedToken, hFile;
intptr_t buffer[1024 / sizeof(intptr_t)];
freeme = 0;
if (flags & X_OK) flags |= R_OK;
granted = 0;
result = false;
flagmask = flags;
s = (void *)buffer;
secsize = sizeof(buffer);
privsize = sizeof(privileges);
@ -70,9 +76,8 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
mapping.GenericWrite = kNtFileGenericWrite;
mapping.GenericExecute = kNtFileGenericExecute;
mapping.GenericAll = kNtFileAllAccess;
MapGenericMask(&flags, &mapping);
MapGenericMask(&flagmask, &mapping);
hImpersonatedToken = hToken = -1;
TryAgain:
if (GetFileSecurity(pathname,
kNtOwnerSecurityInformation |
kNtGroupSecurityInformation |
@ -84,13 +89,29 @@ TryAgain:
&hToken)) {
if (DuplicateToken(hToken, kNtSecurityImpersonation,
&hImpersonatedToken)) {
if (flags == kNtGenericExecute) { // X_OK
flags |= kNtGenericRead; // R_OK
}
if (AccessCheck(s, hImpersonatedToken, flags, &mapping, &privileges,
if (AccessCheck(s, hImpersonatedToken, flagmask, &mapping, &privileges,
&privsize, &granted, &result)) {
if (result || flags == F_OK) {
rc = 0;
if (flags & X_OK) {
if ((hFile = CreateFile(
pathname, kNtFileGenericRead,
kNtFileShareRead | kNtFileShareWrite |
kNtFileShareDelete,
0, kNtOpenExisting,
kNtFileAttributeNormal | kNtFileFlagBackupSemantics,
0)) != -1) {
if (IsWindowsExecutable(hFile)) {
rc = 0;
} else {
rc = eacces();
}
CloseHandle(hFile);
} else {
rc = __winerr();
}
} else {
rc = 0;
}
} else {
NTTRACE("ntaccesscheck finale failed: result=%d flags=%x", result,
flags);
@ -112,25 +133,15 @@ TryAgain:
strerror(errno));
}
} else {
e = GetLastError();
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
if (!freeme && _weaken(malloc) && (freeme = _weaken(malloc)(secsize))) {
s = freeme;
goto TryAgain;
} else {
rc = enomem();
NTTRACE("%s(%#hs) failed: %s", "GetFileSecurity", pathname,
strerror(errno));
}
} else {
errno = e;
NTTRACE("%s(%#hs) failed: %s", "GetFileSecurity", pathname,
strerror(errno));
rc = -1;
}
rc = __winerr();
NTTRACE("%s(%#hs) failed: %s", "GetFileSecurity", pathname,
strerror(errno));
}
if (hImpersonatedToken != -1) {
CloseHandle(hImpersonatedToken);
}
if (hToken != -1) {
CloseHandle(hToken);
}
if (freeme && _weaken(free)) _weaken(free)(freeme);
if (hImpersonatedToken != -1) CloseHandle(hImpersonatedToken);
if (hToken != -1) CloseHandle(hToken);
return rc;
}