update: susfs to 4a2aeafed0387550cd7e22bbd2566bcf2df58e8c
This commit updates susfs in the kernel to the latest currently available by the time of this commit.
This commit is contained in:
parent
c81ada184a
commit
e69c25d4b2
6 changed files with 54 additions and 75 deletions
20
fs/inode.c
20
fs/inode.c
|
@ -24,10 +24,6 @@
|
||||||
#include <trace/events/writeback.h>
|
#include <trace/events/writeback.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
|
||||||
extern bool susfs_is_current_ksu_domain(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inode locking rules:
|
* Inode locking rules:
|
||||||
*
|
*
|
||||||
|
@ -1829,11 +1825,6 @@ int generic_update_time(struct inode *inode, struct timespec64 *time, int flags)
|
||||||
int iflags = I_DIRTY_TIME;
|
int iflags = I_DIRTY_TIME;
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
|
||||||
if (susfs_is_current_ksu_domain()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (flags & S_ATIME)
|
if (flags & S_ATIME)
|
||||||
inode->i_atime = *time;
|
inode->i_atime = *time;
|
||||||
if (flags & S_VERSION)
|
if (flags & S_VERSION)
|
||||||
|
@ -1859,11 +1850,6 @@ EXPORT_SYMBOL(generic_update_time);
|
||||||
*/
|
*/
|
||||||
int inode_update_time(struct inode *inode, struct timespec64 *time, int flags)
|
int inode_update_time(struct inode *inode, struct timespec64 *time, int flags)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
|
||||||
if (susfs_is_current_ksu_domain()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (inode->i_op->update_time)
|
if (inode->i_op->update_time)
|
||||||
return inode->i_op->update_time(inode, time, flags);
|
return inode->i_op->update_time(inode, time, flags);
|
||||||
return generic_update_time(inode, time, flags);
|
return generic_update_time(inode, time, flags);
|
||||||
|
@ -1920,12 +1906,6 @@ void touch_atime(const struct path *path)
|
||||||
struct inode *inode = d_inode(path->dentry);
|
struct inode *inode = d_inode(path->dentry);
|
||||||
struct timespec64 now;
|
struct timespec64 now;
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
|
||||||
if (susfs_is_current_ksu_domain()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!atime_needs_update(path, inode))
|
if (!atime_needs_update(path, inode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,6 @@
|
||||||
#include <linux/susfs_def.h>
|
#include <linux/susfs_def.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_KSU_SUSFS_SUS_PATH) || defined(CONFIG_KSU_SUSFS_OPEN_REDIRECT)
|
|
||||||
#include <linux/susfs_def.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_FSCRYPT_SDP
|
#ifdef CONFIG_FSCRYPT_SDP
|
||||||
#include <linux/fscrypto_sdp_name.h>
|
#include <linux/fscrypto_sdp_name.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,18 +45,25 @@
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
extern bool susfs_is_current_ksu_domain(void);
|
extern bool susfs_is_current_ksu_domain(void);
|
||||||
extern bool susfs_is_current_zygote_domain(void);
|
extern bool susfs_is_current_zygote_domain(void);
|
||||||
#define CL_SUSFS_COPY_MNT_NS 0x1000000
|
|
||||||
#define DEFAULT_SUS_MNT_GROUP_ID 1000
|
static DEFINE_IDA(susfs_mnt_id_ida);
|
||||||
|
static DEFINE_IDA(susfs_mnt_group_ida);
|
||||||
|
|
||||||
|
#define CL_ZYGOTE_COPY_MNT_NS BIT(24) /* used by copy_mnt_ns() */
|
||||||
|
#define CL_COPY_MNT_NS BIT(25) /* used by copy_mnt_ns() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||||
|
extern void susfs_auto_add_sus_ksu_default_mount(const char __user *to_pathname);
|
||||||
|
bool susfs_is_auto_add_sus_ksu_default_mount_enabled = true;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||||
extern int susfs_auto_add_sus_bind_mount(const char *pathname, struct path *path_target);
|
extern int susfs_auto_add_sus_bind_mount(const char *pathname, struct path *path_target);
|
||||||
|
bool susfs_is_auto_add_sus_bind_mount_enabled = true;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||||
extern void susfs_auto_add_try_umount_for_bind_mount(struct path *path);
|
extern void susfs_auto_add_try_umount_for_bind_mount(struct path *path);
|
||||||
#endif
|
bool susfs_is_auto_add_try_umount_for_bind_mount_enabled = true;
|
||||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
|
||||||
extern void susfs_auto_add_sus_ksu_default_mount(const char __user *to_pathname);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Maximum number of mounts in a mount namespace */
|
/* Maximum number of mounts in a mount namespace */
|
||||||
|
@ -215,24 +222,28 @@ static int mnt_alloc_id(struct mount *mnt)
|
||||||
static void mnt_free_id(struct mount *mnt)
|
static void mnt_free_id(struct mount *mnt)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
// If mnt->mnt.susfs_orig_mnt_id is not zero, it means mnt->mnt_id is spoofed,
|
// We should first check the 'mnt->mnt.susfs_mnt_id_backup', see if it is DEFAULT_SUS_MNT_ID_FOR_KSU_PROC_UNSHARE
|
||||||
|
// if so, these mnt_id were not assigned by mnt_alloc_id() so we don't need to free it.
|
||||||
|
if (unlikely(mnt->mnt.susfs_mnt_id_backup == DEFAULT_SUS_MNT_ID_FOR_KSU_PROC_UNSHARE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Now we can check if its mnt_id is sus
|
||||||
|
if (unlikely(mnt->mnt_id >= DEFAULT_SUS_MNT_ID)) {
|
||||||
|
ida_free(&susfs_mnt_id_ida, mnt->mnt_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Lastly if 'mnt->mnt.susfs_mnt_id_backup' is not 0, then it contains a backup origin mnt_id
|
||||||
|
// so we free it in the original way
|
||||||
|
if (likely(mnt->mnt.susfs_mnt_id_backup)) {
|
||||||
|
// If mnt->mnt.susfs_mnt_id_backup is not zero, it means mnt->mnt_id is spoofed,
|
||||||
// so here we return the original mnt_id for being freed.
|
// so here we return the original mnt_id for being freed.
|
||||||
if (unlikely(mnt->mnt.susfs_orig_mnt_id)) {
|
ida_free(&mnt_id_ida, mnt->mnt.susfs_mnt_id_backup);
|
||||||
ida_free(&mnt_id_ida, mnt->mnt.susfs_orig_mnt_id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ida_free(&mnt_id_ida, mnt->mnt_id);
|
ida_free(&mnt_id_ida, mnt->mnt_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
|
||||||
static void susfs_mnt_alloc_group_id(struct mount *mnt)
|
|
||||||
{
|
|
||||||
// Just assign the same default sus mount_group_id to mnt->mnt_group_id
|
|
||||||
mnt->mnt_group_id = DEFAULT_SUS_MNT_GROUP_ID;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a new peer group ID
|
* Allocate a new peer group ID
|
||||||
*/
|
*/
|
||||||
|
@ -265,9 +276,10 @@ bypass_orig_flow:
|
||||||
void mnt_release_group_id(struct mount *mnt)
|
void mnt_release_group_id(struct mount *mnt)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
// If mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID, it means 'mnt' is sus mount,
|
// If mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID, it means 'mnt' is also sus mount,
|
||||||
// here we don't need to free the mnt_group_id and just simply return and do nothing.
|
// then we free the mnt->mnt_group_id from susfs_mnt_group_ida
|
||||||
if (unlikely(mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID)) {
|
if (mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID) {
|
||||||
|
ida_free(&susfs_mnt_group_ida, mnt->mnt_group_id);
|
||||||
mnt->mnt_group_id = 0;
|
mnt->mnt_group_id = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1372,7 +1384,8 @@ bypass_orig_flow:
|
||||||
mnt->mnt_parent = mnt;
|
mnt->mnt_parent = mnt;
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
if (susfs_is_current_zygote_domain() && !(flag & CL_SUSFS_COPY_MNT_NS)) {
|
// If caller process is zygote and not doing unshare, so we just reorder the mnt_id
|
||||||
|
if (likely(is_current_zygote_domain) && !(flag & CL_ZYGOTE_COPY_MNT_NS)) {
|
||||||
mnt->mnt.susfs_orig_mnt_id = mnt->mnt_id;
|
mnt->mnt.susfs_orig_mnt_id = mnt->mnt_id;
|
||||||
mnt->mnt_id = current->susfs_last_fake_mnt_id++;
|
mnt->mnt_id = current->susfs_last_fake_mnt_id++;
|
||||||
}
|
}
|
||||||
|
@ -2481,17 +2494,6 @@ static int invent_group_ids(struct mount *mnt, bool recurse)
|
||||||
{
|
{
|
||||||
struct mount *p;
|
struct mount *p;
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
|
||||||
if (susfs_is_current_ksu_domain()) {
|
|
||||||
for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
|
|
||||||
if (!p->mnt_group_id && !IS_MNT_SHARED(p)) {
|
|
||||||
susfs_mnt_alloc_group_id(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
|
for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
|
||||||
if (!p->mnt_group_id && !IS_MNT_SHARED(p)) {
|
if (!p->mnt_group_id && !IS_MNT_SHARED(p)) {
|
||||||
int err = mnt_alloc_group_id(p);
|
int err = mnt_alloc_group_id(p);
|
||||||
|
@ -3946,9 +3948,11 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
||||||
copy_flags |= CL_SHARED_TO_SLAVE;
|
copy_flags |= CL_SHARED_TO_SLAVE;
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
|
// Always let clone_mnt() in copy_tree() know it is from copy_mnt_ns()
|
||||||
|
copy_flags |= CL_COPY_MNT_NS;
|
||||||
if (is_zygote_pid) {
|
if (is_zygote_pid) {
|
||||||
// Let clone_mnt() in copy_tree() know we only interested in function called by copy_mnt_ns()
|
// Let clone_mnt() in copy_tree() know copy_mnt_ns() is run by zygote process
|
||||||
copy_flags |= CL_SUSFS_COPY_MNT_NS;
|
copy_flags |= CL_ZYGOTE_COPY_MNT_NS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_KDP_NS
|
#ifdef CONFIG_KDP_NS
|
||||||
|
@ -4014,7 +4018,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
// current->susfs_last_fake_mnt_id -> to record last valid fake mnt_id to zygote pid
|
// current->susfs_last_fake_mnt_id -> to record last valid fake mnt_id to zygote pid
|
||||||
// q->mnt.susfs_orig_mnt_id -> original mnt_id
|
// q->mnt.susfs_mnt_id_backup -> original mnt_id
|
||||||
// q->mnt_id -> will be modified to the fake mnt_id
|
// q->mnt_id -> will be modified to the fake mnt_id
|
||||||
|
|
||||||
// Here We are only interested in processes of which original mnt namespace belongs to zygote
|
// Here We are only interested in processes of which original mnt namespace belongs to zygote
|
||||||
|
@ -4025,7 +4029,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
||||||
if (unlikely(q->mnt.mnt_root->d_inode->i_state & INODE_STATE_SUS_MOUNT)) {
|
if (unlikely(q->mnt.mnt_root->d_inode->i_state & INODE_STATE_SUS_MOUNT)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
q->mnt.susfs_orig_mnt_id = q->mnt_id;
|
q->mnt.susfs_mnt_id_backup = q->mnt_id;
|
||||||
q->mnt_id = last_entry_mnt_id++;
|
q->mnt_id = last_entry_mnt_id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4106,13 +4110,6 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
|
||||||
goto out_data;
|
goto out_data;
|
||||||
|
|
||||||
ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
|
ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
|
||||||
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT) && defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT)
|
|
||||||
// Just for the compatibility of Magic Mount KernelSU
|
|
||||||
if (!ret && susfs_is_current_ksu_domain()) {
|
|
||||||
susfs_auto_add_sus_ksu_default_mount(dir_name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT) && defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT)
|
#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT) && defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT)
|
||||||
// Just for the compatibility of Magic Mount KernelSU
|
// Just for the compatibility of Magic Mount KernelSU
|
||||||
if (!ret && susfs_is_auto_add_sus_ksu_default_mount_enabled && susfs_is_current_ksu_domain()) {
|
if (!ret && susfs_is_auto_add_sus_ksu_default_mount_enabled && susfs_is_current_ksu_domain()) {
|
||||||
|
@ -4325,7 +4322,8 @@ out_to:
|
||||||
out_from:
|
out_from:
|
||||||
path_put(&from_path);
|
path_put(&from_path);
|
||||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||||
if (!ret && susfs_is_current_ksu_domain()) {
|
// For Legacy KSU mount scheme
|
||||||
|
if (!ret && susfs_is_auto_add_sus_ksu_default_mount_enabled && susfs_is_current_ksu_domain()) {
|
||||||
susfs_auto_add_sus_ksu_default_mount(to_pathname);
|
susfs_auto_add_sus_ksu_default_mount(to_pathname);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
#if defined(CONFIG_KSU_SUSFS_SUS_KSTAT) || defined(CONFIG_KSU_SUSFS_SUS_MOUNT)
|
||||||
#include <linux/susfs_def.h>
|
#include <linux/susfs_def.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ extern void susfs_sus_ino_for_generic_fillattr(unsigned long ino, struct kstat *
|
||||||
void generic_fillattr(struct inode *inode, struct kstat *stat)
|
void generic_fillattr(struct inode *inode, struct kstat *stat)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||||
if (unlikely(inode->i_state & INODE_STATE_SUS_KSTAT)) {
|
if (likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC) &&
|
||||||
|
unlikely(inode->i_state & INODE_STATE_SUS_KSTAT)) {
|
||||||
susfs_sus_ino_for_generic_fillattr(inode->i_ino, stat);
|
susfs_sus_ino_for_generic_fillattr(inode->i_ino, stat);
|
||||||
stat->mode = inode->i_mode;
|
stat->mode = inode->i_mode;
|
||||||
stat->rdev = inode->i_rdev;
|
stat->rdev = inode->i_rdev;
|
||||||
|
@ -205,6 +206,10 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||||
unsigned lookup_flags = 0;
|
unsigned lookup_flags = 0;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||||
|
struct mount *mnt;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||||
if (susfs_is_sus_su_hooks_enabled) {
|
if (susfs_is_sus_su_hooks_enabled) {
|
||||||
ksu_handle_stat(&dfd, &filename, &flags);
|
ksu_handle_stat(&dfd, &filename, &flags);
|
||||||
|
|
|
@ -77,8 +77,8 @@ struct vfsmount {
|
||||||
ANDROID_KABI_RESERVE(1);
|
ANDROID_KABI_RESERVE(1);
|
||||||
ANDROID_KABI_RESERVE(2);
|
ANDROID_KABI_RESERVE(2);
|
||||||
ANDROID_KABI_RESERVE(3);
|
ANDROID_KABI_RESERVE(3);
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS
|
||||||
ANDROID_KABI_USE(4, u64 susfs_orig_mnt_id);
|
ANDROID_KABI_USE(4, u64 susfs_mnt_id_backup);
|
||||||
#else
|
#else
|
||||||
ANDROID_KABI_RESERVE(4);
|
ANDROID_KABI_RESERVE(4);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1398,12 +1398,12 @@ struct task_struct {
|
||||||
ANDROID_KABI_RESERVE(4);
|
ANDROID_KABI_RESERVE(4);
|
||||||
ANDROID_KABI_RESERVE(5);
|
ANDROID_KABI_RESERVE(5);
|
||||||
ANDROID_KABI_RESERVE(6);
|
ANDROID_KABI_RESERVE(6);
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
#ifdef CONFIG_KSU_SUSFS
|
||||||
ANDROID_KABI_USE(7, u64 susfs_task_state);
|
ANDROID_KABI_USE(7, u64 susfs_task_state);
|
||||||
#else
|
#else
|
||||||
ANDROID_KABI_RESERVE(7);
|
ANDROID_KABI_RESERVE(7);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
#ifdef CONFIG_KSU_SUSFS
|
||||||
ANDROID_KABI_USE(8, u64 susfs_last_fake_mnt_id);
|
ANDROID_KABI_USE(8, u64 susfs_last_fake_mnt_id);
|
||||||
#else
|
#else
|
||||||
ANDROID_KABI_RESERVE(8);
|
ANDROID_KABI_RESERVE(8);
|
||||||
|
|
Loading…
Reference in a new issue