Skip to content

Commit

Permalink
be more accurate in reboot3 hook
Browse files Browse the repository at this point in the history
  • Loading branch information
asdfugil committed Jan 20, 2024
1 parent 92ef80d commit 9e6da79
Show file tree
Hide file tree
Showing 15 changed files with 181 additions and 71 deletions.
2 changes: 1 addition & 1 deletion include/libjailbreak/libjailbreak.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum {
JBD_CMD_GET_PINFO_ROOTDEV,
JBD_CMD_DEPLOY_BOOTSTRAP,
JBD_CMD_OBLITERATE_JAILBREAK,
JBD_CMD_REBOOT_USERSPACE,
JBD_CMD_PERFORM_REBOOT3,
JBD_CMD_OVERWRITE_FILE_WITH_CONTENT,
};

Expand Down
1 change: 1 addition & 0 deletions include/payload/payload.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ int obliterate_main(int argc, char* argv[]);
int remove_bogus_var_jb(void);
void overwrite_file(xpc_object_t xrequest, xpc_object_t xreply, struct paleinfo* pinfo);
void reload_launchd_env(void);
void perform_reboot3(xpc_object_t peer, xpc_object_t xreply, xpc_object_t request, struct paleinfo* pinfo_p);

enum {
/* only for sysstatuscheck and prelaunchd stage! */
Expand Down
2 changes: 1 addition & 1 deletion include/systemhook/libiosexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <grp.h>
#include <stdbool.h>

#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC

#define THREE_WAY_CALL(func, ...) ( ie_ ## func && !has_libiosexec ) ? ie_ ## func( __VA_ARGS__ ) : (orig_ ## func ? orig_ ## func( __VA_ARGS__ ) : func( __VA_ARGS__ ))
#define RET_TWC(...) return THREE_WAY_CALL( __VA_ARGS__ )
Expand Down
68 changes: 31 additions & 37 deletions src/payload/jailbreakd/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@
#include <sys/mount.h>
#include <errno.h>

#define ENOENTITLEMENT 144
#define ENOTPLATFORM 154
#define RB2_USERREBOOT (0x2000000000000000llu)
int reboot3(uint64_t how, uint64_t unk);

#define HAVE_DEBUG_JBD

void palera1nd_handler(xpc_object_t peer, xpc_object_t request, struct paleinfo* pinfo_p) {
xpc_object_t xreply = xpc_dictionary_create_reply(request);
xpc_object_t xremote = xpc_dictionary_get_remote_connection(request);
#ifdef HAVE_DEBUG_JBD
char* xrequeststr = xpc_copy_description(request);
pid_t pid = xpc_connection_get_pid(peer);
NSLog(CFSTR("received dictionary from pid %d: %s"), pid, xrequeststr);
free(xrequeststr);
#endif


if (!xremote || !xreply) return;

uint64_t cmd = xpc_dictionary_get_uint64(request, "cmd");
Expand All @@ -44,11 +54,12 @@ void palera1nd_handler(xpc_object_t peer, xpc_object_t request, struct paleinfo*
case JBD_CMD_GET_PINFO_KERNEL_INFO: {
bool entitled = false;
xpc_object_t val = xpc_connection_copy_entitlement_value(peer, KERNELINFO_ENTITLEMENT);
if (xpc_get_type(val) == XPC_TYPE_BOOL) {
if (val && xpc_get_type(val) == XPC_TYPE_BOOL) {
entitled = xpc_bool_get_value(val);
}
if (val) xpc_release(val);
if (!entitled) {
xpc_dictionary_set_int64(xreply, "error", EPERM);
xpc_dictionary_set_int64(xreply, "error", ENOENTITLEMENT);
break;
}
xpc_dictionary_set_uint64(xreply, "kbase", pinfo_p->kbase);
Expand All @@ -62,11 +73,12 @@ void palera1nd_handler(xpc_object_t peer, xpc_object_t request, struct paleinfo*
case JBD_CMD_DEPLOY_BOOTSTRAP: {
bool entitled = false;
xpc_object_t val = xpc_connection_copy_entitlement_value(peer, BOOTSTRAPPER_ENTITLEMENT);
if (xpc_get_type(val) == XPC_TYPE_BOOL) {
if (val && xpc_get_type(val) == XPC_TYPE_BOOL) {
entitled = xpc_bool_get_value(val);
}
if (val) xpc_release(val);
if (!entitled) {
xpc_dictionary_set_int64(xreply, "error", EPERM);
xpc_dictionary_set_int64(xreply, "error", ENOENTITLEMENT);
xpc_dictionary_set_string(xreply, "errorDescription", "This call requires the " BOOTSTRAPPER_ENTITLEMENT ".");
break;
}
Expand All @@ -76,51 +88,31 @@ void palera1nd_handler(xpc_object_t peer, xpc_object_t request, struct paleinfo*
case JBD_CMD_OBLITERATE_JAILBREAK: {
bool entitled = false;
xpc_object_t val = xpc_connection_copy_entitlement_value(peer, OBLITERATOR_ENTITLEMENT);
if (xpc_get_type(val) == XPC_TYPE_BOOL) {
if (val && xpc_get_type(val) == XPC_TYPE_BOOL) {
entitled = xpc_bool_get_value(val);
}
if (val) xpc_release(val);
if (!entitled) {
xpc_dictionary_set_int64(xreply, "error", EPERM);
xpc_dictionary_set_int64(xreply, "error", ENOENTITLEMENT);
xpc_dictionary_set_string(xreply, "errorDescription", "This call requires the " OBLITERATOR_ENTITLEMENT ".");
break;
}
obliterate(request, xreply, pinfo_p);
break;
}
case JBD_CMD_REBOOT_USERSPACE: {
audit_token_t token;
xpc_connection_get_audit_token(peer, &token);
pid_t pid = xpc_connection_get_pid(peer);
if (pid == -1) {
xpc_dictionary_set_int64(xreply, "error", errno);
break;
}
int status;
int ret = csops_audittoken(pid, CS_OPS_STATUS, &status, 4, &token);
if (ret) {
xpc_dictionary_set_int64(xreply, "error", errno);
break;
}
if ((status & CS_PLATFORM_BINARY) == 0) {
xpc_dictionary_set_int64(xreply, "error", ENOTPLATFORM);
break;
}
unmount("/Developer", MNT_FORCE);
ret = reboot3(RB2_USERREBOOT, 0);
if (ret) {
xpc_dictionary_set_int64(xreply, "error", ret);
break;
}
case JBD_CMD_PERFORM_REBOOT3: {
perform_reboot3(peer, xreply, request, pinfo_p);
break;
}
case JBD_CMD_OVERWRITE_FILE_WITH_CONTENT: {
bool entitled = false;
xpc_object_t val = xpc_connection_copy_entitlement_value(peer, BOOTSTRAPPER_ENTITLEMENT);
if (xpc_get_type(val) == XPC_TYPE_BOOL) {
if (val && xpc_get_type(val) == XPC_TYPE_BOOL) {
entitled = xpc_bool_get_value(val);
}
if (val) xpc_release(val);
if (!entitled) {
xpc_dictionary_set_int64(xreply, "error", EPERM);
xpc_dictionary_set_int64(xreply, "error", ENOENTITLEMENT);
xpc_dictionary_set_string(xreply, "errorDescription", "This call requires the " BOOTSTRAPPER_ENTITLEMENT ".");
break;
}
Expand All @@ -130,10 +122,12 @@ void palera1nd_handler(xpc_object_t peer, xpc_object_t request, struct paleinfo*
xpc_dictionary_set_int64(xreply, "error", EINVAL);
break;
}

char* desc = xpc_copy_description(xreply);
// NSLog(CFSTR("sending reply: %s"), desc);
free(desc);

#ifdef HAVE_DEBUG_JBD
char* xreplystr = xpc_copy_description(xreply);
NSLog(CFSTR("sending reply: %s"), xreplystr);
free(xreplystr);
#endif
xpc_connection_send_message(xremote, xreply);
xpc_release(xreply);
}
86 changes: 86 additions & 0 deletions src/payload/jailbreakd/reboot3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <stdio.h>
#include <stdlib.h>
#include <dispatch/dispatch.h>
#include <xpc/xpc.h>
#include <xpc/private.h>
#include <xpc/connection.h>
#include <libjailbreak/libjailbreak.h>
#include <CoreFoundation/CoreFoundation.h>
#include <payload/payload.h>
#include <paleinfo.h>
#include <errno.h>
#include <spawn.h>
#include <pthread.h>
#define TARGET_OS_IPHONE 1
#include <spawn_private.h>
#include <sys/spawn_internal.h>
#include <sys/kern_memorystatus.h>
#include <CoreFoundation/CoreFoundation.h>
#include <removefile.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/codesign.h>
#include <copyfile.h>

#include <sys/stat.h>

#define ENOENTITLEMENT 144
#define ENOTPLATFORM 154
#define RB2_USERREBOOT (0x2000000000000000llu)
#define ITHINK_PURPOSE (0x0100000000000000llu)
int reboot3(uint64_t howto, ...);

void perform_reboot3(xpc_object_t peer, xpc_object_t xreply, xpc_object_t request, struct paleinfo* pinfo_p) {
audit_token_t token;
xpc_connection_get_audit_token(peer, &token);
pid_t pid = xpc_connection_get_pid(peer);
if (pid == -1) {
xpc_dictionary_set_int64(xreply, "error", errno);
return;
}
int status;
int ret = csops_audittoken(pid, CS_OPS_STATUS, &status, 4, &token);
if (ret) {
xpc_dictionary_set_int64(xreply, "error", errno);
return;
}
if ((status & CS_PLATFORM_BINARY) == 0) {
xpc_dictionary_set_int64(xreply, "error", ENOTPLATFORM);
return;
}
xpc_object_t xpc_howto = xpc_dictionary_get_value(request, "howto");
xpc_object_t xpc_purpose = xpc_dictionary_get_value(request, "purpose");
if (!xpc_howto) {
xpc_dictionary_set_int64(xreply, "error", EINVAL);
xpc_dictionary_set_string(xreply, "errorDescription", "howto not supplied");
return;
}
uint64_t howto = xpc_uint64_get_value(xpc_howto);
if (howto & RB2_USERREBOOT) {
bool entitled = false;
xpc_object_t value = xpc_connection_copy_entitlement_value(peer, "com.apple.private.xpc.launchd.userspace-reboot");
if (value && xpc_get_type(value) == XPC_TYPE_BOOL) {
entitled = true;
}
if (value) xpc_release(value);
if (!entitled) {
xpc_dictionary_set_int64(xreply, "error", ENOENTITLEMENT);
return;
}
}
if ((howto & ITHINK_PURPOSE) && !xpc_purpose) {
xpc_dictionary_set_int64(xreply, "error", EINVAL);
xpc_dictionary_set_string(xreply, "errorDescription", "reboot flags included the purpose flag, but no purpose supplied in request");
return;
}

unmount("/Developer", MNT_FORCE);
if (howto & ITHINK_PURPOSE) {
ret = reboot3(howto, (uint32_t)xpc_uint64_get_value(xpc_purpose));
} else ret = reboot3(howto);

if (ret) {
xpc_dictionary_set_int64(xreply, "error", ret);
return;
}
}
2 changes: 1 addition & 1 deletion src/payload/loader/fixup_user_groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <pwd.h>
#include <grp.h>

#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
int fixup_pwgrp_file(char* sysfile, char* jbfile) {
if (access(sysfile, F_OK) != 0) {
fprintf(stderr, "cannot access %s\n", sysfile);
Expand Down
2 changes: 1 addition & 1 deletion src/payload/loader/sysstatuscheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ int sysstatuscheck(uint32_t payload_options, uint64_t pflags) {
} else {
remove_bogus_var_jb();
create_var_jb();
#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
if (access("/var/jb", F_OK) == 0) {
fixup_databases();
}
Expand Down
19 changes: 15 additions & 4 deletions src/payload/p1ctl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,23 @@ int reload_main(int argc, char* argv[]) {
return ret;
}

int reboot_userspace_main(int argc, char* argv[]) {
P1CTL_UPCALL_JBD_WITH_ERR_CHECK(xreply, JBD_CMD_REBOOT_USERSPACE);
#define RB2_USERREBOOT (0x2000000000000000llu)

int retval = print_jailbreakd_reply(xreply);
int reboot_userspace_main(int argc, char* argv[]) {
xpc_object_t xdict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(xdict, "cmd", JBD_CMD_PERFORM_REBOOT3);
xpc_dictionary_set_uint64(xdict, "howto", RB2_USERREBOOT);
xpc_object_t xreply = jailbreak_send_jailbreakd_message_with_reply_sync(xdict);
if (xpc_get_type(xreply) != XPC_TYPE_ERROR) {
print_jailbreakd_reply(xreply);
} else {
char* desc = xpc_copy_description(xreply);
fprintf(stderr, "failed to send jailbreakd message: %s\n", desc);
free(desc);
}
xpc_release(xreply);
return retval;
xpc_release(xdict);
return 0;
}


Expand Down
2 changes: 1 addition & 1 deletion src/payload_dylib/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ xpc_object_t hook_xpc_dictionary_get_value(xpc_object_t dict, const char *key){
xpc_dictionary_set_value(retval, "/System/Library/LaunchDaemons/in.palera.palera1nd.plist", submitJob);
}

#ifdef DEBUG_SHELL
#ifdef HAVE_DEBUG_SHELL
{
xpc_object_t submitJob = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t programArguments = xpc_array_create(NULL, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/payload_dylib/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void load_bootstrapped_jailbreak_env(void)
*pJB_RootPath = strdup(jbPath);
free(old_rootPath);
}
#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
if (!bound_libiosexec) {
init_libiosexec_hook_with_ellekit = dlsym(systemhook_handle, "init_libiosexec_hook_with_ellekit");
if (init_libiosexec_hook_with_ellekit) {
Expand Down
2 changes: 1 addition & 1 deletion src/systemhook/get_libiosexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <dlfcn.h>
#include <substrate.h>

#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
#define BIND_IOSEXEC_SYMBOL(sym) ie_ ## sym = dlsym(libiosexec_handle, "ie_" #sym)

void* libiosexec_handle;
Expand Down
2 changes: 1 addition & 1 deletion src/systemhook/getgrent.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <systemhook/common.h>
#include <dyld-interpose.h>

#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
struct group *
getgrgid_hook(gid_t gid) {
RET_TWC(getgrgid, gid);
Expand Down
2 changes: 1 addition & 1 deletion src/systemhook/getpwent.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <systemhook/common.h>
#include <dyld-interpose.h>

#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
struct passwd *
getpwuid_hook(uid_t uid) {
RET_TWC(getpwuid, uid);
Expand Down
2 changes: 1 addition & 1 deletion src/systemhook/getusershell.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <systemhook/common.h>
#include <dyld-interpose.h>

#ifdef SYSTEMWIDE_IOSEXEC
#ifdef HAVE_SYSTEMWIDE_IOSEXEC
char* getusershell_hook(void) {
RET_TWC(getusershell);
}
Expand Down
Loading

0 comments on commit 9e6da79

Please sign in to comment.