Undecimus: Rebooting userspace puts the jailbreak in a non-functional state

Created on 15 Jan 2019  Â·  12Comments  Â·  Source: pwn20wndstuff/Undecimus

Rebooting user space using launchd's built in feature which can be triggered by running launchctl reboot userspace (unc0ver's launchctl binary lacks the entitlement that is needed to perform this operation, this will be fixed soon, but in the meantime, to perform your testing, you can simply resign /bin/launchctl with these entitlements (which are the entitlements that we are supposed to have) using ldid2 (not ldid because the kernel trust cache only accepts SHA256 signatures on iOS 11 and up) (Should be installed from the Elucubratus repository, the package is called Link Identity Editor) or jtool by Jonathan Levin from http://www.newosxbook.com/tools/jtool.html and inject it back to the trust cache using the trust cache injection tool that comes as default with unc0ver v2.0.0 or up, also available in the Elucubratus repository. These steps will need to be redone every time unc0ver runs since unc0ver will re-extract the its resources if they were modified, and launchctl is a part of its resources) will essentially reboot the entire system but the kernel itself. This means that launchd itself will also be restarted. The jailbreak depends on pwning the userland. The launch daemons that were loaded by the jailbreak will obviously also be unloaded since this is a full reboot of the userspace. Substrate will obviously stop working, so amfid won't be pwned, this means that code signing won't be patched and we will be unable to run fake signed binaries unless they have been injected into AMFI's dynamic trust cache before (This will work because the trust cache is in the kernel, which isn't rebooted), Substrate add-ons will also stop working since Substrate itself won't be running anymore, however, since the kernel itself will stay untouched, the kernel version string will still be patched, this means that the jailbreak will detect that the device was jailbroken although it really isn't anymore (This horribly confuses the users). At this point, we will basically be out of power, and we will need to run the jailbreak again to load Substrate and load launch daemons once again, there's really no other way in. We can't control what happens after this, however, we can change how it happens... I believe this functionality is implemented in launchd, so we should be able to hook launchd to possibly disable this functionality altogether, which will still be better than the current behavior, or we can also hook into launchd to change how it restarts itself, and possibly use DYLD_INSERT_LIBRARIES to inject a library to the new launchd that would execute Substrate again and load jailbreak launch daemons to persist the jailbreak. This seems like a better solution, however, in any case, this should be implemented in Cydia Substrate itself. Substrate already has to hook launchd, and the historical record confirms that Apple has been automatically triggering this feature (userspace reboot) when the device is in the idle mode, and allegedly when it's the night where the user won't be using their device. Historical record confirms this, the users have initially started complaining about this problem with the release of the Pangu Jailbreak Tool for iOS 9.2-9.3.3, although the devices have been suffering from this issue since the initial release of iOS 9.0, majority of the people were unaware because they really had no way to notice that this happened unless they intentionally checked their crash reports (A new "SystemMemoryReset" crash log will appear every time iOS does this on its own, manually trigging it via launchctl won't make this appear, but they essentially perform the same operation) because Pangu Jailbreak Tool for iOS 9.0-9.1 contained an untether and didn't depend on userland patches that needed to be reapplied by an other userland process (This is a weird behavior that I don't know the reasoning behind yet but on certain jailbreak tools, the userspace reboot won't work at all, it will lead to a kernel panic, I don't know if Pangu Jailbreak Tool for iOS 9.0-9.1 was one of those, but even if it was, it would be seamless because of the Untether). However, with the release of Pangu Jailbreak Tool for iOS 9.2-9.3.3, jailbreak tools switched to a different approach ("Semi-Untethered".). And this is when people started really noticing it since there was no one to put the device in a jailbroken state again once launchd was restarted, users had to re-run the jailbreak. I don't know if anyone remembers this, but fixes that weren't actually fixes but dirty mitigations like changing the Jetsam file to max out the memory limit to make sure that the device wouldn't exceed the memory limit and trigger a userspace reboot started coming out (unc0ver's increase memory limit switch essentially does the same thing.). So this isn't really an issue in the system or the jailbreak, but something that a jailbreak should be handling (and currently doesn't). However this shouldn't be confused with kernel crashes, prior to the release of unc0ver with Cydia Substrate, people were suffering from kernel data aborts and other kernel related issues on iOS 11 jailbreaks (Except for the light-weight jailbreaks like Liber* by Jonathan Levin), which were caused by the jailbreaks. This is a different case.
I have additionally picked users who were having this issue on the latest unc0ver and Cydia Substrate and confirmed that this was indeed their issue.

Most helpful comment

No. Substrate will probably be updated to address this soonish.

All 12 comments

So I have been reversing launchd with @sharedRoutine and we may have found something that will simply the complicated issue and allow us to fix it in a much easier way although you may totally hate it ;P

Additional research shows that mmaintenanced manages and triggers these operations

iPhone7 ,ios 11.1.2,My phone restarts two or three times a day, how can I submit the log to you, crashreport does not seem to get the restart log

I have been occasionally reversing launchd for the past days.
It is now clear that it uses the posix_spawn() APIs to re-execute itself.
Now the idea is to create a dynamic library that would:
execute ‘/usr/libexec/substrate’, load launch daemon plists in ‘/Library/LaunchDaemons’ and re-create ‘/var/tmp/slide.txt’ after restoring the kernel slide from kernel’s task_info(DYLD_INFO) (This has been possible since v2.1.1.).

call it ‘/usr/lib/launchd_persistence.dylib’, inject it to the dynamic kernel trust cache, and hook into launchd to use DYLD_INSERT_LIBRARIES=‘/usr/lib/launchd_persistence.dylib’ when restarting itself

I will attempt to do this in a day or two

Has the new 2.1.3 version fixed this issue?

No. Substrate will probably be updated to address this soonish.

Has there been any progress on the nightly reboots with substrate or news from @Saurik on this? I'm on a 6s 11.2.6 and using 2.1.1 with substitute right now (and it is very stable), as I don't want to install the new substrate because I don't want to go through the hassle of re-jailbreaking every morning.

Still having this issue (3.0 b27). Can usually get around 3 days up time before I wake up to an unjailbroken phone

Rebooting userspace puts the jailbreak in a non-functional state. Current?? 3.7.0 b2?? XS Max ios 12.2

Rebooting user space using launchd's built in feature which can be triggered by running launchctl reboot userspace (unc0ver's launchctl binary lacks the entitlement that is needed to perform this operation, this will be fixed soon, but in the meantime, to perform your testing, you can simply resign /bin/launchctl with these entitlements (which are the entitlements that we are supposed to have) using ldid2 (not ldid because the kernel trust cache only accepts SHA256 signatures on iOS 11 and up) (Should be installed from the Elucubratus repository, the package is called Link Identity Editor) or jtool by Jonathan Levin from http://www.newosxbook.com/tools/jtool.html and inject it back to the trust cache using the trust cache injection tool that comes as default with unc0ver v2.0.0 or up, also available in the Elucubratus repository. These steps will need to be redone every time unc0ver runs since unc0ver will re-extract the its resources if they were modified, and launchctl is a part of its resources) will essentially reboot the entire system but the kernel itself. This means that launchd itself will also be restarted. The jailbreak depends on pwning the userland. The launch daemons that were loaded by the jailbreak will obviously also be unloaded since this is a full reboot of the userspace. Substrate will obviously stop working, so amfid won't be pwned, this means that code signing won't be patched and we will be unable to run fake signed binaries unless they have been injected into AMFI's dynamic trust cache before (This will work because the trust cache is in the kernel, which isn't rebooted), Substrate add-ons will also stop working since Substrate itself won't be running anymore, however, since the kernel itself will stay untouched, the kernel version string will still be patched, this means that the jailbreak will detect that the device was jailbroken although it really isn't anymore (This horribly confuses the users). At this point, we will basically be out of power, and we will need to run the jailbreak again to load Substrate and load launch daemons once again, there's really no other way in. We can't control what happens after this, however, we can change how it happens... I believe this functionality is implemented in launchd, so we should be able to hook launchd to possibly disable this functionality altogether, which will still be better than the current behavior, or we can also hook into launchd to change how it restarts itself, and possibly use DYLD_INSERT_LIBRARIES to inject a library to the new launchd that would execute Substrate again and load jailbreak launch daemons to persist the jailbreak. This seems like a better solution, however, in any case, this should be implemented in Cydia Substrate itself. Substrate already has to hook launchd, and the historical record confirms that Apple has been automatically triggering this feature (userspace reboot) when the device is in the idle mode, and allegedly when it's the night where the user won't be using their device. Historical record confirms this, the users have initially started complaining about this problem with the release of the Pangu Jailbreak Tool for iOS 9.2-9.3.3, although the devices have been suffering from this issue since the initial release of iOS 9.0, majority of the people were unaware because they really had no way to notice that this happened unless they intentionally checked their crash reports (A new "SystemMemoryReset" crash log will appear every time iOS does this on its own, manually trigging it via launchctl won't make this appear, but they essentially perform the same operation) because Pangu Jailbreak Tool for iOS 9.0-9.1 contained an untether and didn't depend on userland patches that needed to be reapplied by an other userland process (This is a weird behavior that I don't know the reasoning behind yet but on certain jailbreak tools, the userspace reboot won't work at all, it will lead to a kernel panic, I don't know if Pangu Jailbreak Tool for iOS 9.0-9.1 was one of those, but even if it was, it would be seamless because of the Untether). However, with the release of Pangu Jailbreak Tool for iOS 9.2-9.3.3, jailbreak tools switched to a different approach ("Semi-Untethered".). And this is when people started really noticing it since there was no one to put the device in a jailbroken state again once launchd was restarted, users had to re-run the jailbreak. I don't know if anyone remembers this, but fixes that weren't actually fixes but dirty mitigations like changing the Jetsam file to max out the memory limit to make sure that the device wouldn't exceed the memory limit and trigger a userspace reboot started coming out (unc0ver's increase memory limit switch essentially does the same thing.). So this isn't really an issue in the system or the jailbreak, but something that a jailbreak should be handling (and currently doesn't). However this shouldn't be confused with kernel crashes, prior to the release of unc0ver with Cydia Substrate, people were suffering from kernel data aborts and other kernel related issues on iOS 11 jailbreaks (Except for the light-weight jailbreaks like Liber* by Jonathan Levin), which were caused by the jailbreaks. This is a different case.
I have additionally picked users who were having this issue on the latest unc0ver and Cydia Substrate and confirmed that this was indeed their issue.

@pwn20wndstuff I assume this can be closed due to it being fully implemented in v4.3.1?

Fixed in v4.3.1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

VeZReVouLiS picture VeZReVouLiS  Â·  3Comments

olibub picture olibub  Â·  3Comments

ghost picture ghost  Â·  3Comments

miguelr4720 picture miguelr4720  Â·  3Comments

bachle22 picture bachle22  Â·  4Comments