Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions kernel/patch/common/supercall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -418,7 +430,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;
}
Expand Down