8000 RFE: Add support for maximum supported kernel version by drakenclimber · Pull Request #457 · seccomp/libseccomp · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

RFE: Add support for maximum supported kernel version #457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
12 changes: 12 additions & 0 deletions doc/man/man3/seccomp_attr_set.3
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ A flag to specify if libseccomp should request wait killable semantics when
possible. Defaults to off
.RI ( value
== 0).
.TP
.B SCMP_FLTATR_ACT_ENOSYS
Action to take when an unknown (too new) syscall is invoked. Used in
conjunction with SCMP_FLTATR_CTL_KVER. Defaults to SCMP_ACT_ERRNO(38)
(ENOSYS). If desired behavior differs from the default, then this attribute
must be set prior to setting SCMP_FLTATR_CTL_KVERMAX.
.TP
.B SCMP_FLTATR_CTL_KVERMAX
Maximum kernel version understood by the user application. Syscalls from
newer kernel versions will return with the action in SCMP_FLTATR_ACT_ENOSYS.
Once SCMP_FLTATR_CTL_KVERMAX is set, no more rules can be added to the
filter. Attempting to add more rules will result in -EINVAL.
.\" //////////////////////////////////////////////////////////////////////////
.SH RETURN VALUE
.\" //////////////////////////////////////////////////////////////////////////
Expand Down
95 changes: 95 additions & 0 deletions include/seccomp.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ enum scmp_filter_attr {
*/
SCMP_FLTATR_API_SYSRAWRC = 9, /**< return the system return codes */
SCMP_FLTATR_CTL_WAITKILL = 10, /**< request wait killable semantics */
SCMP_FLTATR_ACT_ENOSYS = 11, /**< action to take when an unknown
* (newer than this filter) syscall is
* invoked. Must be used in conjunction
* with SCMP_FLTATR_CTL_KVER
*/
SCMP_FLTATR_CTL_KVERMAX = 12, /**< maximum kernel version understood
* by the user application. syscalls
* from newer kernel versions will
* return with the action in
* SCMP_FLTATR_ACT_UNKNOWN
< 8000 /td> */
_SCMP_FLTATR_MAX,
};

Expand All @@ -97,6 +108,90 @@ enum scmp_compare {
_SCMP_CMP_MAX,
};

/**
* Kernel versions
*/
enum scmp_kver {
__SCMP_KV_NULL = 0,
SCMP_KV_UNDEF = 1,
SCMP_KV_3_0 = 2,
SCMP_KV_3_1 = 3,
SCMP_KV_3_2 = 4,
SCMP_KV_3_3 = 5,
SCMP_KV_3_4 = 6,
SCMP_KV_3_5 = 7,
SCMP_KV_3_6 = 8,
SCMP_KV_3_7 = 9,
SCMP_KV_3_8 = 10,
SCMP_KV_3_9 = 11,
SCMP_KV_3_10 = 12,
SCMP_KV_3_11 = 13,
SCMP_KV_3_12 = 14,
SCMP_KV_3_13 = 15,
SCMP_KV_3_14 = 16,
SCMP_KV_3_15 = 17,
SCMP_KV_3_16 = 18,
SCMP_KV_3_17 = 19,
SCMP_KV_3_18 = 20,
SCMP_KV_3_19 = 21,
SCMP_KV_4_0 = 22,
SCMP_KV_4_1 = 23,
SCMP_KV_4_2 = 24,
SCMP_KV_4_3 = 25,
SCMP_KV_4_4 = 26,
SCMP_KV_4_5 = 27,
SCMP_KV_4_6 = 28,
SCMP_KV_4_7 = 29,
SCMP_KV_4_8 = 30,
SCMP_KV_4_9 = 31,
SCMP_KV_4_10 = 32,
SCMP_KV_4_11 = 33,
SCMP_KV_4_12 = 34,
SCMP_KV_4_13 = 35,
SCMP_KV_4_14 = 36,
SCMP_KV_4_15 = 37,
SCMP_KV_4_16 = 38,
SCMP_KV_4_17 = 39,
SCMP_KV_4_18 = 40,
SCMP_KV_4_19 = 41,
SCMP_KV_4_20 = 42,
SCMP_KV_5_0 = 43,
SCMP_KV_5_1 = 44,
SCMP_KV_5_2 = 45,
SCMP_KV_5_3 = 46,
SCMP_KV_5_4 = 47,
SCMP_KV_5_5 = 48,
SCMP_KV_5_6 = 49,
SCMP_KV_5_7 = 50,
SCMP_KV_5_8 = 51,
SCMP_KV_5_9 = 52,
SCMP_KV_5_10 = 53,
SCMP_KV_5_11 = 54,
SCMP_KV_5_12 = 55,
SCMP_KV_5_13 = 56,
SCMP_KV_5_14 = 57,
SCMP_KV_5_15 = 58,
SCMP_KV_5_16 = 59,
SCMP_KV_5_17 = 60,
SCMP_KV_5_18 = 61,
SCMP_KV_5_19 = 62,
SCMP_KV_6_0 = 63,
SCMP_KV_6_1 = 64,
SCMP_KV_6_2 = 65,
SCMP_KV_6_3 = 66,
SCMP_KV_6_4 = 67,
SCMP_KV_6_5 = 68,
SCMP_KV_6_6 = 69,
SCMP_KV_6_7 = 70,
SCMP_KV_6_8 = 71,
SCMP_KV_6_9 = 72,
SCMP_KV_6_10 = 73,
SCMP_KV_6_11 = 74,
SCMP_KV_6_12 = 75,
SCMP_KV_6_13 = 76,
__SCMP_KV_MAX,
};

/**
* Argument datum
*/
Expand Down
24 changes: 23 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,27 @@ if ENABLE_PYTHON
SUBDIRS += python
endif

GET_MAX_SYSCALL= ./scmp_get_max_syscall_num.py
AM_CFLAGS = \
-DMAX_SYSCALL_NUM_X86=`${GET_MAX_SYSCALL} -a x86` \
-DMAX_SYSCALL_NUM_X86_64=`${GET_MAX_SYSCALL} -a x86_64` \
-DMAX_SYSCALL_NUM_X32=`${GET_MAX_SYSCALL} -a x32` \
-DMAX_SYSCALL_NUM_ARM=`${GET_MAX_SYSCALL} -a arm` \
-DMAX_SYSCALL_NUM_AARCH64=`${GET_MAX_SYSCALL} -a aarch64` \
-DMAX_SYSCALL_NUM_LOONGARCH64=`${GET_MAX_SYSCALL} -a loongarch64` \
-DMAX_SYSCALL_NUM_M68K=`${GET_MAX_SYSCALL} -a m68k` \
-DMAX_SYSCALL_NUM_MIPS=`${GET_MAX_SYSCALL} -a mips` \
-DMAX_SYSCALL_NUM_MIPS64=`${GET_MAX_SYSCALL} -a mips64` \
-DMAX_SYSCALL_NUM_MIPS64N32=`${GET_MAX_SYSCALL} -a mips64n32` \
-DMAX_SYSCALL_NUM_PARISC=`${GET_MAX_SYSCALL} -a parisc` \
-DMAX_SYSCALL_NUM_PARISC64=`${GET_MAX_SYSCALL} -a parisc64` \
-DMAX_SYSCALL_NUM_PPC=`${GET_MAX_SYSCALL} -a ppc` \
-DMAX_SYSCALL_NUM_PPC64=`${GET_MAX_SYSCALL} -a ppc64` \
-DMAX_SYSCALL_NUM_RISCV64=`${GET_MAX_SYSCALL} -a riscv64` \
-DMAX_SYSCALL_NUM_S390=`${GET_MAX_SYSCALL} -a s390` \
-DMAX_SYSCALL_NUM_S390X=`${GET_MAX_SYSCALL} -a s390x` \
-DMAX_SYSCALL_NUM_SH=`${GET_MAX_SYSCALL} -a sh`

SOURCES_ALL = \
api.c system.h system.c helper.h helper.c \
gen_pfc.h gen_pfc.c gen_bpf.h gen_bpf.c \
Expand Down Expand Up @@ -49,7 +70,8 @@ SOURCES_ALL = \

EXTRA_DIST = \
arch-syscall-validate arch-syscall-check \
arch-gperf-generate syscalls.csv syscalls.perf.template
arch-gperf-generate syscalls.csv syscalls.perf.template \
scmp_get_max_syscall_num.py

TESTS = arch-syscall-check

Expand Down
16 changes: 14 additions & 2 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,14 @@ API int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src)
if (db_col_valid(col_dst) || db_col_valid(col_src))
return _rc_filter(-EINVAL);

/* NOTE: only the default action, NNP, and TSYNC settings must match */
/* NOTE: only the default action, NNP, TSYNC, and kernel version
* settings must match */
if ((col_dst->attr.act_default != col_src->attr.act_default) ||
(col_dst->attr.nnp_enable != col_src->attr.nnp_enable) ||
(col_dst->attr.tsync_enable != col_src->attr.tsync_enable))
(col_dst->attr.tsync_enable != col_src->attr.tsync_enable) ||
(col_dst->attr.act_enosys != col_src->attr.act_enosys) ||
(col_dst->attr.kvermax != col_src->attr.kvermax))

return _rc_filter(-EINVAL);

return _rc_filter(db_col_merge(col_dst, col_src));
Expand Down Expand Up @@ -590,6 +594,14 @@ API int seccomp_rule_add_array(scmp_filter_ctx ctx,
if (action == col->attr.act_default)
return _rc_filter(-EACCES);

if (col->attr.kvermax != SCMP_KV_UNDEF)
/* Currently libseccomp does not support overwriting rules
* that have already been added to the filter. The maximum
* supported kernel version feature adds a rule for each
* syscall. Thus we can't support adding any more syscalls
* after that value is set */
return _rc_filter(-EINVAL);

return _rc_filter(db_col_rule_add(col, 0, action,
syscall, arg_cnt, arg_arra F438 y));
}
Expand Down
43 changes: 43 additions & 0 deletions src/arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,46 @@ int arch_filter_rule_add(struct db_filter *db,
free(rule_dup);
return rc;
}

int arch_add_kver_rule(struct db_filter *db, struct db_api_rule_list *rule,
enum scmp_kver supported_kver)
{
struct db_sys_list *s_iter;
enum scmp_kver syscall_added_ver;
const char *syscall_name;
int rc = 0;

db_list_foreach(s_iter, db->syscalls) {
if (rule->syscall == s_iter->num)
/* Do not overwrite existing rules */
return 0;
}

syscall_name = (db->arch->syscall_resolve_num_raw)(rule->syscall);
if (syscall_name == NULL)
/* This syscall number is invalid in this architecture */
return 0;

syscall_added_ver = (db->arch->syscall_num_kver)(rule->syscall);
if (syscall_added_ver > supported_kver)
/* This syscall is newer than the kernel version supported by
* the application. Don't add it to the rule, and therefore
* it will be subject to the attr->act_unknown action */
return 0;

rc = arch_syscall_translate(db->arch, &rule->syscall);
if (rc < 0)
return 0;

if (db->arch->rule_add == NULL) {
/* syscalls < -1 require a db->arch->rule_add() function */
if (rule->syscall < -1 && rule->strict)
return 0;

rc = db_rule_add(db, rule);
} else {
rc = (db->arch->rule_add)(db, rule);
}

return rc;
}
2 changes: 2 additions & 0 deletions src/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,6 @@ int arch_syscall_rewrite(const struct arch_def *arch, int *syscall);
int arch_filter_rule_add(struct db_filter *db,
const struct db_api_rule_list *rule);

int arch_add_kver_rule(struct db_filter *db, struct db_api_rule_list *rule,
enum scmp_kver supported_kver);
#endif
Loading
Loading
0