app-probe.dhover×122all
#!/usr/bin/env dub
/+ dub.sdl:
    name "android-research-app-probe"
    platforms "linux"
    dflags "-betterC"
    targetPath "build"
+/
/**
 * libc-only probe suitable for a Bionic Android executable (-betterC).
 * Run from the real terminal UI, not adb shell or run-as.
 * Evidence: ../index.md#app-domain-probe.
 * Namespace changes occur only in forked children; no mounts are made.
 */
module 
(module) app_probe

libc-only probe suitable for a Bionic Android executable (-betterC). Run from the real terminal UI, not adb shell or run-as.

Evidence

../index.md#app-domain-probe. Namespace changes occur only in forked children; no mounts are made.

app_probe
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdio

D header file for C99 <stdio.h>

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h

Source

core/stdc/stdio.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
stdio
:
(alias) app_probe.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
,
(alias) app_probe.fflush = int core.stdc.stdio.fflush(shared(core.stdc.stdio._IO_FILE)* stream) nothrow @nogc @trusted
fflush
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.errno

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/errno.h.html, errno.h

Source

core/stdc/errno.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
errno
:
(alias) app_probe.errno = int core.stdc.errno.__errno_location() nothrow @nogc ref @trusted
errno
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.unistd

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 8, IEEE Std 1003.1, 2024 Edition
unistd
:
(alias) app_probe.getuid = uint core.sys.posix.unistd.getuid() nothrow @nogc @trusted
getuid
,
(alias) app_probe.getgid = uint core.sys.posix.unistd.getgid() nothrow @nogc @trusted
getgid
,
(alias) app_probe.fork = int core.sys.posix.unistd.fork() nothrow @nogc @trusted
fork
,
(alias) app_probe.read = long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogc
read
,
(alias) app_probe.close = int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
,
(alias) app_probe._exit = noreturn core.sys.posix.unistd._exit(int) nothrow @nogc @trusted
_exit
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.fcntl

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
fcntl
: open,
(alias constant) app_probe.O_RDONLY = int core.sys.posix.fcntl.O_RDONLY = 0
O_RDONLY
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.wait

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
wait
:
(alias) app_probe.waitpid = int core.sys.posix.sys.wait.waitpid(int, int*, int) nothrow @nogc
waitpid
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.socket

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
socket
:
(alias) app_probe.socket = int core.sys.posix.sys.socket.socket(int, int, int) nothrow @nogc @safe
socket
,
(alias enum value) app_probe.SOCK_STREAM = core.sys.posix.sys.socket.SOCK_STREAM = 1
SOCK_STREAM
;
extern(C) int
int app_probe.unshare(int flags) nothrow @nogc
unshare
(int
(parameter) int flags
flags
) @nogc nothrow;
void
void app_probe.showFile(const(char)* path) nothrow @nogc
showFile
(const(char)*
(parameter) const(char)* path
path
) @nogc nothrow
{ char[4096]
(local variable) char[4096] buffer
buffer
;
const
(local variable) const(int) fd
fd
= open(
int core.sys.posix.fcntl.open64(scope const(char*), int, ...) nothrow @nogc
path
,
(constant) int core.sys.posix.fcntl.O_RDONLY = 0
O_RDONLY
);
if (
(local variable) const(int) fd
fd
< 0)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("%s: errno=%d\n",
(parameter) const(char)* path
path
,
int core.stdc.errno.__errno_location() nothrow @nogc ref @trusted
errno
);
return; }
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("%s:\n",
(parameter) const(char)* path
path
);
while (true) { const
(local variable) const(long) size
size
=
long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogc
read
(
(local variable) const(int) fd
fd
,
(local variable) char[4096] buffer
buffer
.
(constant) char* char[4096].ptr = &buffer
ptr
,
(local variable) char[4096] buffer
buffer
.
(constant) ulong char[4096].length = 4096LU
length
- 1);
if (
(local variable) const(long) size
size
<= 0)
break;
(local variable) char[4096] buffer
buffer
[
(local variable) const(long) size
size
] = 0;
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("%s",
(local variable) char[4096] buffer
buffer
.
(constant) char* char[4096].ptr = &buffer
ptr
);
}
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("\n");
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) const(int) fd
fd
);
} int
int app_probe.namespaceAttempt(int flags, const(char)* name) nothrow @nogc
namespaceAttempt
(int
(parameter) int flags
flags
, const(char)*
(parameter) const(char)* name
name
) @nogc nothrow
{
int core.stdc.stdio.fflush(shared(core.stdc.stdio._IO_FILE)* stream) nothrow @nogc @trusted
fflush
(null);
const
(local variable) const(int) child
child
=
int core.sys.posix.unistd.fork() nothrow @nogc @trusted
fork
();
if (
(local variable) const(int) child
child
< 0)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("fork: errno=%d\n",
int core.stdc.errno.__errno_location() nothrow @nogc ref @trusted
errno
);
return 1; } if (
(local variable) const(int) child
child
== 0)
{ const
(local variable) const(int) result
result
=
int app_probe.unshare(int flags) nothrow @nogc
unshare
(
(parameter) int flags
flags
);
const
(local variable) const(int) error
error
=
int core.stdc.errno.__errno_location() nothrow @nogc ref @trusted
errno
;
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("unshare(%s): result=%d errno=%d\n",
(parameter) const(char)* name
name
,
(local variable) const(int) result
result
,
(local variable) const(int) result
result
< 0 ?
(local variable) const(int) error
error
: 0);
int core.stdc.stdio.fflush(shared(core.stdc.stdio._IO_FILE)* stream) nothrow @nogc @trusted
fflush
(null);
noreturn core.sys.posix.unistd._exit(int) nothrow @nogc @trusted
_exit
(0);
} int
(local variable) int status
status
;
return
int core.sys.posix.sys.wait.waitpid(int, int*, int) nothrow @nogc
waitpid
(
(local variable) const(int) child
child
, &
(local variable) int status
status
, 0) !=
(local variable) const(int) child
child
||
(local variable) int status
status
!= 0;
} extern(C) int
int app_probe.main() nothrow @nogc
main
() @nogc nothrow
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("uid=%u gid=%u\n",
uint core.sys.posix.unistd.getuid() nothrow @nogc @trusted
getuid
(),
uint core.sys.posix.unistd.getgid() nothrow @nogc @trusted
getgid
());
void app_probe.showFile(const(char)* path) nothrow @nogc
showFile
("/proc/self/attr/current");
void app_probe.showFile(const(char)* path) nothrow @nogc
showFile
("/proc/self/status");
int
(local variable) int failure
failure
=
int app_probe.namespaceAttempt(int flags, const(char)* name) nothrow @nogc
namespaceAttempt
(0x10000000, "CLONE_NEWUSER");
(local variable) int failure
failure
|=
int app_probe.namespaceAttempt(int flags, const(char)* name) nothrow @nogc
namespaceAttempt
(0x00020000, "CLONE_NEWNS");
(local variable) int failure
failure
|=
int app_probe.namespaceAttempt(int flags, const(char)* name) nothrow @nogc
namespaceAttempt
(0x10000000 | 0x00020000, "CLONE_NEWUSER|CLONE_NEWNS");
const
(local variable) const(int) fd
fd
=
int core.sys.posix.sys.socket.socket(int, int, int) nothrow @nogc @safe
socket
(40,
(enum value) core.sys.posix.sys.socket.SOCK_STREAM = 1
SOCK_STREAM
, 0); // Linux AF_VSOCK.
const
(local variable) const(int) error
error
=
int core.stdc.errno.__errno_location() nothrow @nogc ref @trusted
errno
;
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("socket(AF_VSOCK): fd=%d errno=%d\n",
(local variable) const(int) fd
fd
,
(local variable) const(int) fd
fd
< 0 ?
(local variable) const(int) error
error
: 0);
if (
(local variable) const(int) fd
fd
>= 0)
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) const(int) fd
fd
);
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("Capability absence/rejection is a result, not a probe failure.\n");
return
(local variable) int failure
failure
;
}