Some checks failed
Android CI Build / check (push) Has been cancelled
Android CI Build / package-apks (push) Has been cancelled
Docs Deploy / build (push) Has been cancelled
Module Market Check / Validate modules/ (push) Has been cancelled
Module Market Publish / Generate submissions.json (push) Has been cancelled
Docs Deploy / deploy (push) Has been cancelled
- Package rename com.webtoapp -> br.com.drukstech.codeapp - Product rename WebToApp/web-to-app -> DruksCode/drukscode - Design system Wta* -> Dkc* - applicationId br.com.drukstech.codeapp (.play for gplay flavor) - rootProject.name DruksCode - Fresh git history (upstream kept as remote for sync)
72 lines
2.0 KiB
Diff
72 lines
2.0 KiB
Diff
Android targetSdk>=29 SELinux W^X denies exec-mapping app_data files, which
|
|
kills every on-device runtime that keeps its ELF libraries in app storage.
|
|
Bridge such fds into an executable memfd (the same permission class ART JIT
|
|
relies on) before mapping. The probe keeps unrestricted environments
|
|
(generated APKs stay at targetSdk 28) on the zero-overhead direct path.
|
|
--- a/ldso/dynlink.c
|
|
+++ b/ldso/dynlink.c
|
|
@@ -684,7 +684,11 @@
|
|
}
|
|
}
|
|
|
|
-static void *map_library(int fd, struct dso *dso)
|
|
+#ifndef MFD_EXEC
|
|
+#define MFD_EXEC 0x0010U
|
|
+#endif
|
|
+
|
|
+static void *map_library_inner(int fd, struct dso *dso)
|
|
{
|
|
Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
|
|
void *allocated_buf=0;
|
|
@@ -868,8 +872,50 @@
|
|
if (map!=MAP_FAILED) unmap_library(dso);
|
|
free(allocated_buf);
|
|
return 0;
|
|
+}
|
|
+
|
|
+/* W^X bridge: if the fd cannot be exec-mapped, copy it into an executable
|
|
+ * memfd and map from there. Returns fd unchanged when mapping is allowed
|
|
+ * or the bridge is unavailable. */
|
|
+static int wta_exec_bridge(int fd)
|
|
+{
|
|
+ void *t = mmap(0, PAGE_SIZE, PROT_READ|PROT_EXEC, MAP_PRIVATE, fd, 0);
|
|
+ if (t != MAP_FAILED) {
|
|
+ munmap(t, PAGE_SIZE);
|
|
+ return fd;
|
|
+ }
|
|
+ int m = memfd_create("wta-lib", MFD_CLOEXEC | MFD_EXEC);
|
|
+ if (m < 0 && errno == EINVAL)
|
|
+ m = memfd_create("wta-lib", MFD_CLOEXEC);
|
|
+ if (m < 0) return fd;
|
|
+ off_t save = lseek(fd, 0, SEEK_CUR);
|
|
+ lseek(fd, 0, SEEK_SET);
|
|
+ char buf[65536];
|
|
+ ssize_t r;
|
|
+ while ((r = read(fd, buf, sizeof buf)) > 0) {
|
|
+ ssize_t off = 0;
|
|
+ while (off < r) {
|
|
+ ssize_t w = write(m, buf+off, r-off);
|
|
+ if (w < 0) { r = -1; break; }
|
|
+ off += w;
|
|
+ }
|
|
+ if (r < 0) break;
|
|
+ }
|
|
+ lseek(fd, save == (off_t)-1 ? 0 : save, SEEK_SET);
|
|
+ if (r < 0) { close(m); return fd; }
|
|
+ lseek(m, 0, SEEK_SET);
|
|
+ return m;
|
|
}
|
|
|
|
+static void *map_library(int fd, struct dso *dso)
|
|
+{
|
|
+ int bfd = wta_exec_bridge(fd);
|
|
+ if (bfd == fd) return map_library_inner(fd, dso);
|
|
+ void *res = map_library_inner(bfd, dso);
|
|
+ close(bfd);
|
|
+ return res;
|
|
+}
|
|
+
|
|
static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
|
|
{
|
|
size_t l;
|