From 4328a3ff580f7842c3341f7ff2bef2cf452b0aa6 Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Wed, 1 Apr 2026 01:54:39 -0300 Subject: [PATCH 1/2] add support to 32-bit supercall This commit allows 32-bit processes to take advantage of the supercall by calling the 32-bit truncate, without issues due to integer size difference. --- kernel/patch/common/supercall.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/patch/common/supercall.c b/kernel/patch/common/supercall.c index 21e46509..6acfa758 100644 --- a/kernel/patch/common/supercall.c +++ b/kernel/patch/common/supercall.c @@ -418,7 +418,13 @@ int supercall_install() hook_err_t err = hook_syscalln(__NR_supercall, 6, before, 0, 0); if (err) { - log_boot("install supercall hook error: %d\n", err); + log_boot("install supercall 64-bit hook error: %d\n", err); + rc = err; + goto out; + } + err = hook_compat_syscalln(92, 6, before, 0, 0); // __NR_truncate == __NR_supercall for 32-bit + if (err) { + log_boot("install supercall 32-bit hook error: %d\n", err); rc = err; goto out; } From 17a555c66738c1b4d152c2b315b93af25c81d0ff Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Fri, 1 May 2026 13:48:41 -0300 Subject: [PATCH 2/2] add support for reading/writing kstorage from 32-bit process This commit adds support for 32-bit processes in userspace to be able to write to kstorage with KernelPatch by using structures instead of relying on 64-bit integers which can't be passed to kernel space from userspace, since they're emulated. --- kernel/patch/common/supercall.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/kernel/patch/common/supercall.c b/kernel/patch/common/supercall.c index 6acfa758..3a81d1b0 100644 --- a/kernel/patch/common/supercall.c +++ b/kernel/patch/common/supercall.c @@ -247,14 +247,28 @@ static long call_su_set_allow_sctx(char *__user usctx) return set_all_allow_sctx(buf); } -static long call_kstorage_read(int gid, long did, void *out_data, int offset, int dlen) -{ - return read_kstorage(gid, did, out_data, offset, dlen, true); +struct data_item { + void *data; + int dlen; + int offset; +}; + +static long call_kstorage_read(int gid, long did, struct data_item *out_data_item) +{ + struct data_item *item = memdup_user(out_data_item, sizeof(*item)); + if (!item || IS_ERR(item)) return PTR_ERR(item); + long rc = read_kstorage(gid, did, item->data, item->offset, item->dlen, true); + kvfree(item); + return rc; } -static long call_kstorage_write(int gid, long did, void *data, int offset, int dlen) +static long call_kstorage_write(int gid, long did, struct data_item *in_data_item) { - return write_kstorage(gid, did, data, offset, dlen, true); + struct data_item *item = memdup_user(in_data_item, sizeof(*item)); + if (!item || IS_ERR(item)) return PTR_ERR(item); + long rc = write_kstorage(gid, did, item->data, item->offset, item->dlen, true); + kvfree(item); + return rc; } static long call_list_kstorage_ids(int gid, long *ids, int ids_len) @@ -311,12 +325,10 @@ static long supercall(int is_key_auth, long cmd, long arg1, long arg2, long arg3 return call_su_get_allow_sctx((char *__user)arg1, (int)arg2); case SUPERCALL_SU_SET_ALLOW_SCTX: return call_su_set_allow_sctx((char *__user)arg1); - case SUPERCALL_KSTORAGE_READ: - return call_kstorage_read((int)arg1, (long)arg2, (void *)arg3, (int)((long)arg4 >> 32), (long)arg4 << 32 >> 32); + return call_kstorage_read((int)arg1, (long)arg2, (struct data_item *)arg3); case SUPERCALL_KSTORAGE_WRITE: - return call_kstorage_write((int)arg1, (long)arg2, (void *)arg3, (int)((long)arg4 >> 32), - (long)arg4 << 32 >> 32); + return call_kstorage_write((int)arg1, (long)arg2, (struct data_item *)arg3); case SUPERCALL_KSTORAGE_LIST_IDS: return call_list_kstorage_ids((int)arg1, (long *)arg2, (int)arg3); case SUPERCALL_KSTORAGE_REMOVE: