-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid executing ELF files directly #24
base: master
Are you sure you want to change the base?
Conversation
LLVM looks at /proc/self/exe to determine which binary has been called. This does not work with the proposed changes for termux-exec: termux/termux-exec#24 Luckily the fallback to look at argv0 works instead.
LLVM looks at /proc/self/exe to determine which binary has been called. This does not work with the proposed changes for termux-exec: termux/termux-exec#24 Luckily the fallback to look at argv0 works instead.
Without -f/--full, pgrep&pkill matches searches by default only on the binary name, which will not work with the changes proposed in termux/termux-exec#24, as there the binary will always be /system/bin/linker64.
Without -f/--full, pgrep&pkill matches searches by default only on the binary name, which will not work with the changes proposed in termux/termux-exec#24, as there the binary will always be /system/bin/linker64.
2a852ec
to
6baed3d
Compare
Very interesting solution. But yeah, it likely won't be acceptable by play store policies, but could be tried. Although not sure if android could add further selinux restrictions to prevent this. Btw are you sure in testing, you uninstalled all termux apps, rebooted, and reinstalled, since otherwise The executable being |
termux-exec.c
Outdated
|
||
#ifndef TERMUX_BASE_DIR | ||
# define TERMUX_BASE_DIR "/data/data/com.termux/files" | ||
#define TERMUX_BASE_DIR "/data/data/com.termux/files" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use hardcoded com.termux
values here and elsewhere, it affects termux forks. To get prefix, first check TERMUX__PREFIX
env variable, then PREFIX
, otherwise default to package build time path @TERMUX_BASE_DIR@
. In future, multiple rootfs support may also be added and $PREFIX
has been deprecated in favour of TERMUX__PREFIX
(note double dash as scope), as it conflicts with other packages like npm
, etc. Haven't pushed change to termux-app yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - I'll update!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to look at TERMUX__PREFIX
now, with a TERMUX_BASE_DIR
value given at compilation time as fallback.
I think PREFIX
is too dangerous to use, as you say it can totally break when reused for other purposes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. But do not use literal com.termux
value. The whole path @TERMUX_BASE_DIR@
should be replaced during build time in the source by value set in properties.sh
. Possibly tests should use this too.
For inspiration, check termux-tools design by grimler.
https://github.com/termux/termux-tools/blob/master/configure.ac
https://github.com/termux/termux-tools/blob/master/Makefile.am
Also do not limit prefix length to 48
, package names can be much longer. For example /data/user/10/net.dinglisch.android.taskerm/files
will fail with length 49
. Even /data/data
paths can be longer. Package name alone on playstore can be of length 50
. Probably just check if it starts with /
since technically packages can be compiled for any prefix, even /data/local/tmp
for adb
or /mnt
paths for external sd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good idea not to use $PREFIX
, will have to push TERMUX__PREFIX
export to termux-app as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But do not use literal com.termux value
With the current version (I made changes and squashed commits): We start by using the TERMUX__PREFIX
env variable now. If that does not exist, we fall back to TERMUX_BASE_DIR
.
TERMUX_BASE_DIR
is given at compilation time, as in make TERMUX_BASE_DIR=/a/path/to/package/prefix
(the
It's not really hardcoded any longer, but supplied at compile time (the existing package already supplies that at build time: https://github.com/termux/termux-packages/blob/master/packages/termux-exec/build.sh#L10).
Remaining usage of com.termux
are ok I think:
- In
Makefile
, as a default value ifmake
is executed without any argument - In
termux-exec.c
, but only inside#ifdef UNIT_TEST
, so only used for testing. We also test with other prefixes as well in the tests. - In
test-program.c
, which is just a utility test program that can be run manually, not part of the package
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your thorough review and feedback @agnostic-apollo !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will check code in detail later, outside, but if app is installed on adoptable external sd, then its app data parent directory prefix will be /mnt/expand/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/user/0
, which alone has length 55
, so 100
is not going to be enough, especially if multiple sub dirs under package name.
You are very welcome. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so 100 is not going to be enough
Thanks again! So what about 200
, that should be enough for everyone perhaps :)? That allows a path such as /mnt/expand/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/user/0/yyyyyyyyyy-yyyyyyyyyy/yyyyyyyyyy-yyyyyyyyyyyyyyyyyyyy/yyyyyyyyyyyyyyyyyyyy/yyyyyyyyyyyyyyyyyyyy-yyyyyy yyyy/xxxxx-xxxxx/yyyyy-yyyyy/zzzzzz-zzzzz/
.
The reason I don't want an arbitrary big length is that it would be good to have a reasonable tight limit - this code is going to be injected in a lot of places, so not taking up more stack or heap space than necessary would be great, to decrease risks of interfering with the surrounding problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lolz technically the only valid length is PATH_MAX
(4096
bytes), but that would be for the full path, not just the prefix. That is also what libraries including mine use as the standard for passing to sys calls. You could reduce it if necessary, but couple of hundred bytes won't matter, but at least log a warning if value is ignored.
As Play Store accepts apps that run binaries by |
This comment was marked as off-topic.
This comment was marked as off-topic.
I think it may be more likely that they don't know proot is being used, otherwise if someone took interest, proot and this clearly does violate the policy.
|
Thanks, I noticed the behaviour you described as well, was really confusing first! But now I can confirm that I am indeed testing with effective targetSdk of 34! I'll share a branch of termux-app for testing shortly. |
I think we should focus on the technical issue here, and leave Google Play policy out of the discussion, since I think that's a separate one. This change is hopefully good on its own, for bumping targetSdk also for distribution outside of Google Play. |
Welcome. Android also sometimes assigns latest target sdk
Fair enough. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
That solution may be problematic. Linker on old Android version does not allow to do this. But I am not sure when it starts. |
Looks like it was introduced in https://android.googlesource.com/platform/bionic/+/8f639a40966c630c64166d2657da3ee641303194, which was first included in Android 8. |
Only supporting android >= 8 (or even a version or two higher) for an app re-introduced to google play seems reasonable to me |
Android 10+ solution is not needed to be used on older versions. It can be enabled on-demand, possibly with letting user to opt-out from this solution. Don't forget that:
Though I found one problem with this solution: users will no longer be able to run static binaries. When I attempt to run static binary, I get error |
Yeah, makes sense what you say, a user can unset But I am fine with dropping the patch too. |
Why remove the patch: termux/termux-exec#24 These changes in termux-exec would cause apt to send invalid installation prefix in user agent. This patch is not actual for now and can be removed anyway. *** Background why the patch was added earlier: Its only purpose to generate HTTP user agent string specific for environment. This lets us to distinguish on server side whether user download packages using official Termux app or derivative checking the installation prefix path and disallow downloads made by non-Termux projects to reduce egress traffic when needed.
Why remove the patch: termux/termux-exec#24 These changes in termux-exec would cause apt to send invalid installation prefix in user agent. This patch is not actual for now and can be removed anyway. *** Background why the patch was added earlier: Its only purpose to generate HTTP user agent string specific for environment. This lets us to distinguish on server side whether user download packages using official Termux app or derivative checking the installation prefix path and disallow downloads made by non-Termux projects to reduce egress traffic when needed.
Why remove the patch: termux/termux-exec#24 These changes in termux-exec would cause apt to send invalid installation prefix in user agent. This patch is not actual for now and can be removed anyway. *** Background why the patch was added earlier: Its only purpose to generate HTTP user agent string specific for environment. This lets us to distinguish on server side whether user download packages using official Termux app or derivative checking the installation prefix path and disallow downloads made by non-Termux projects to reduce egress traffic when needed.
Why remove the patch: termux/termux-exec#24 These changes in termux-exec would cause apt to send invalid installation prefix in user agent. This patch is not actual for now and can be removed anyway. *** Background why the patch was added earlier: Its only purpose to generate HTTP user agent string specific for environment. This lets us to distinguish on server side whether user download packages using official Termux app or derivative checking the installation prefix path and disallow downloads made by non-Termux projects to reduce egress traffic when needed.
Why remove the patch: termux/termux-exec#24 These changes in termux-exec would cause apt to send invalid installation prefix in user agent. This patch is not actual for now and can be removed anyway. *** Background why the patch was added earlier: Its only purpose to generate HTTP user agent string specific for environment. This lets us to distinguish on server side whether user download packages using official Termux app or derivative checking the installation prefix path and disallow downloads made by non-Termux projects to reduce egress traffic when needed.
I want to test this on x86-64 and arm |
|
Intead of checking /proc/self/exe. This allows adb to be used with termux-exec changes in termux/termux-exec#24.
Why remove the patch: termux/termux-exec#24 These changes in termux-exec would cause apt to send invalid installation prefix in user agent. This patch is not actual for now and can be removed anyway. *** Background why the patch was added earlier: Its only purpose to generate HTTP user agent string specific for environment. This lets us to distinguish on server side whether user download packages using official Termux app or derivative checking the installation prefix path and disallow downloads made by non-Termux projects to reduce egress traffic when needed.
|
|
It seems like overwriting the content of |
This can cause anomalous results for programs which expect that |
so that `virusAnalysisTests()` outputs the offset+hash of `argv[0]`. Note that just the _Google Store_ version of _Termux_ output the wrong offset+hash (due to _Google_'s rules: termux/termux-exec#24). In the future (if more is done with our path than output example offsets+hashes), it is possible that this fix will have more value. If other programs use `classSysGetOwnPath()` on _Termux_, this can improve those. ?`cxx/ClassSys.cxx`: ?`classSysGetOwnPath()`: the fix was to use `readlink` to return true path. ?`cxx/ClassSys.hxx`: ?`classSysGetOwnPath()`, ?`classSysFopenOwnPath()`: comments improved. ?`cxx/VirusAnalysis.cxx`: typo fixes. Closes issue #26 (Improve: cxx/ClassSys.cxx:classSysGetOwnPath(): for _Termux_, use `procfs` to return our true path.) Is followup to: d50262f (+`classSysGetOwnPath()`, +`classSysFopenOwnPath()`), 5f0ffd8 (?`virusAnalysisTests()`: if Linux, use procfs: this should close https://github.com/SwuduSusuwu/SubStack/security/code-scanning/1277). ?`posts/VirusAnalysis.md`: Include all this. Remove accidental duplicate comments at end of file.
so that `virusAnalysisTests()` outputs the offset+hash of `argv[0]`. Note that just the _Google Store_ version of _Termux_ output the wrong offset+hash (due to _Google_'s rules: termux/termux-exec#24). In the future (if more is done with our path than output example offsets+hashes), it is possible that this fix will have more value. If other programs use `classSysGetOwnPath()` on _Termux_, this can improve those. ?`cxx/ClassSys.cxx`: ?`classSysGetOwnPath()`: the fix was to use `readlink` to return true path. ?`cxx/ClassSys.hxx`: ?`classSysGetOwnPath()`, ?`classSysFopenOwnPath()`: comments improved. ?`cxx/VirusAnalysis.cxx`: typo fixes. Closes issue #26 (Improve: cxx/ClassSys.cxx:classSysGetOwnPath(): for _Termux_, use `procfs` to return our true path.) Is followup to: d50262f (+`classSysGetOwnPath()`, +`classSysFopenOwnPath()`), 5f0ffd8 (?`virusAnalysisTests()`: if Linux, use procfs: this should close https://github.com/SwuduSusuwu/SubStack/security/code-scanning/1277). ?`posts/VirusAnalysis.md`: Include all this. Remove accidental duplicate comments at end of file.
This is change to work around the Android 10
R^W
violation (execution of binary files are not allowed).See the README for more information.
Helping with testing
Help to test this would be great! For context and more information, see
Problem 1
andSolution 1
in the updated README.NOTE: May totally break your system and need a reinstallation (or require a manual repair in a failsafe session - see below).
Steps (on aarch64 - let me know if you want to test on some other arch):
pkg up
cp $PREFIX/lib/libtermux-exec.so $PREFIX/lib/libtermux-exec.so.bak
termux-exec
containing this code:curl -o ~/te-997.deb https://fornwall.me/te-997.deb && apt install --reinstall ~/te-997.deb
After this, new terminal sessions will be using the updated
termux-exec
version. A way to check this is by runningls -l /proc/self/exe
- it should show a symlink pointing to a path ending inbin/linker64
, since the linker is what is being executed.Try things out (run scripts, compile programs, etc) and report if something does not work as a comment in this issue!
This should only affect behaviour on Android 10+ devices, but if you have an old Android version you are welcome to test that as well - that nothing has changed there.
Helping with testing: Debugging tools
export TERMUX_EXEC_DEBUG=1
to get verbose logging to stderrexport TERMUX_EXEC_OPTOUT=1
to opt out from termux-exec - it will not do any modification toexecve
callsHelping with testing: Known issues
zig
does not work (linker errors withhas unexpected e_type: 2
)Helping with testing: To restore
If things are not completely broken,
apt install --reinstall termux-exec=1:1.0
will install the stable version oftermux-exec
.If the installation is completely broken, so you can't even start a shell:
NEW SESSION
button, and clickFAILSAFE
in the dialog that shows up.cd $PREFIX/lib && cp libtermux-exec.so.bak libtermux-exec.so
apt install --reinstall termux-exec=1:1.0
Updates
te-997.deb
,apt show termux-exec
should show version9:9.7
):TERMUX_SELF_EXE
, the absolute path to the executed file, which can be used as a/proc/self/exec
replacement.