Sticktron / g0blin

a work-in-progress jailbreak for iOS 10.3.x (A7-A9)
241 stars 89 forks source link

execve is still sandboxed #87

Open rweichler opened 6 years ago

rweichler commented 6 years ago

The problem tweak I'm using is EQE. Here's the error when I try to launch the app:

Jan 13 00:37:42 Alis-iPhone kernel(Sandbox)[0] <Notice>: SandboxViolation: luajit(371) deny(1) process-exec* /private/var/tweak/com.r333d.eqe/bin/EQE.exe
Jan 13 00:37:42 Alis-iPhone kernel(Sandbox)[0] <Notice>: Sandbox: hook..execve() killing EQE.exe pid 371[UID: 501]: (err=1) process-exec denied while updating label

The CFBundleExecutable in Info.plist is EQE.lua.

The contents of EQE.lua:

#!/var/tweak/com.r333d.eqe/bin/luajit

--[[
The abysmal state of stashing on iOS 10 forces
me to do it like this. Else the app will take up
a few MB on the system partition, which is unacceptable,
since there is only 60MB of space on some iOS 10 devices

Also, I'm not using bash (like most other apps do it)
because it isn't compiled for arm64. So it'd give you that
"The developer hasn't optimized this app for arm64" popup

The only reason why I'm using luajit (instead of a
custom compiled version of bash) is because it's
already bundled with EQE... so why not

All of this code would be the equivalent of this in bash:
exec /Applications/EQE.app/EQE $@
]]

local ffi = require 'ffi'
ffi.cdef[[
int execv(const char *path, char *const argv[]);
]]

arg[0] = '/Applications/EQE.app/EQE'
local argv = ffi.new('char *[?]', #arg + 2)
for i=0,#arg do
    local v = arg[i]
    argv[i] = ffi.new('char[?]', #v + 1, v)
end
argv[#arg + 1] = nil

return ffi.C.execv(arg[0], argv)

And /Applications/EQE.app/EQE is a symlink to /var/tweak/com.r333d.eqe/bin/EQE.exe

af6 commented 6 years ago

i dont know if app executables can be symlinks

rweichler commented 6 years ago

They can, that's how stashing works

Sticktron commented 6 years ago

@rweichler You are correct. It will be addressed in RC2.

Sticktron commented 6 years ago

@rweichler I have tested out EQE with RC2 (didn't test it on RC1) and as far as I can tell it works.

rweichler commented 6 years ago

@Sticktron it's still not working. im getting lots of user reports it doesn't work, and it still crashes on launch. i cannot effectively test this anymore because dropbear was removed and OpenSSH doesn't seem to work

JohnCoates commented 6 years ago

I'm developing an app that has the same issue, and I'm using execv for the same reason as @rweichler. My app fails to install on HFS volumes because the partition /Applications/ is so small. So I put the app in /var/mobile/Library and drop an executable that uses execv in /Applications/.

I've been advised that a suitable solution is that for G0blin to have a postinst executable that detects APFS, and then removes the loader .app installed into /Applications, and moves the .app that installs into /var/mobile/Library over to /Applications/

I'm also having the postrm script clean up the files copied into /Applications/

Is this a good solution, or are there any potential problems I'm not seeing?

rweichler commented 6 years ago

@JohnCoates Oh, wow! Thanks for that info, I had no idea iOS 10.3 used APFS. I thought it was an iOS 11 thing... This makes everything so much easier.

Yeah, what you describe is essentially I was planning on doing for iOS 11 (and now, that I have that info, for jailbreaks with iOS >= 10.3).

This is basically what I have:

And the only thing I'll add in my postinst script is essentially this: mv /var/tweak/com.r333d.eqe/bin/EQE.exe /Applications/EQE.app/EQE.lua. No postrm script.

Generally speaking doing filesystem stuff in postinst/postrm scripts is frowned upon but I don't think we have any other choice. I don't think dpkg was designed with this kind of stuff in mind so we just gotta roll with it, I guess...

rweichler commented 6 years ago

It appears that doing this is the best way of detecting APFS in a postinst script:

if mount | grep -q apfs; then
    # do your stuff
fi
Sticktron commented 6 years ago

Re-opening the issue.

Sorry guys there is definitely a shortcoming in my kernel patching. I think your ideas for a workaround are fine. That way you aren't held back by me. I don't know when I will figure this out.

One note about the test above: not all the filesystems are APFS so it might be better to check / specifically...

if stat -f -c %T / | grep -q apfs; then
    # root is mounted as APFS
fi

or even to perhaps check for disk capacity or free space on / instead, and make the decision to not use /Applications be based on storage capability instead of precise format.