Skip to content

Commit

Permalink
bpf:pfc: Add optimization option to use a binary tree
Browse files Browse the repository at this point in the history
This patch adds a filter attribute, SCMP_FLTATR_CTL_OPTIMIZE,
to specify the optimization level of the seccomp filter:
	0 - currently unused
	1 - rules weighted by priority and complexity (default)
	2 - binary tree sorted by syscall number

Several in-house customers have identified that their large
seccomp filters are slowing down their applications.  Their
filters largely consist of simple allow/deny logic for many
syscalls (306 in one case) and for the most part don't utilize
argument filtering.

I modified gen_bpf.c and gen_pfc.c to utilize a cBPF binary tree
if the user has requested optimize level 2.  I then timed
calling getppid() in a loop using one of my customer's seccomp
filters.  I ran this loop one million times and recorded the min,
max, and mean times (in TSC ticks) to call getppid().  (I didn't
disable interrupts, so the max time was often large.)  I chose
to report the minimum time because I feel it best represents the
actual time to traverse the syscall.

Test Case                      minimum TSC ticks to make syscall
----------------------------------------------------------------
seccomp disabled                                             138
getppid() at the front of 306-syscall seccomp filter         256
getppid() in middle of 306-syscall seccomp filter            516
getppid() at the end of the 306-syscall filter              1942
getppid() in a binary tree                                   312

As shown in the table above, a binary tree can signficantly improve
syscall performance in the average and worst case scenario for these
customers.

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
  • Loading branch information
drakenclimber committed Feb 24, 2020
1 parent fc8a69c commit c9df088
Show file tree
Hide file tree
Showing 7 changed files with 459 additions and 45 deletions.
5 changes: 5 additions & 0 deletions include/seccomp.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ enum scmp_filter_attr {
SCMP_FLTATR_API_TSKIP = 5, /**< allow rules with a -1 syscall */
SCMP_FLTATR_CTL_LOG = 6, /**< log not-allowed actions */
SCMP_FLTATR_CTL_SSB = 7, /**< disable SSB mitigation */
SCMP_FLTATR_CTL_OPTIMIZE = 8, /**< filter optimization level: (DEFAULT = 1)
* 0 - currently unused
* 1 - rules weighted by priority and complexity
* 2 - binary tree sorted by syscall number
*/
_SCMP_FLTATR_MAX,
};

Expand Down
17 changes: 17 additions & 0 deletions src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ static void _db_reset(struct db_filter *db)
}
db->syscalls = NULL;
}
db->syscall_cnt = 0;

/* free any rules */
if (db->rules != NULL) {
Expand Down Expand Up @@ -1069,6 +1070,7 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action)
col->attr.api_tskip = 0;
col->attr.log_enable = 0;
col->attr.spec_allow = 0;
col->attr.optimize = 1;

/* set the state */
col->state = _DB_STA_VALID;
Expand Down Expand Up @@ -1311,6 +1313,9 @@ int db_col_attr_get(const struct db_filter_col *col,
case SCMP_FLTATR_CTL_SSB:
*value = col->attr.spec_allow;
break;
case SCMP_FLTATR_CTL_OPTIMIZE:
*value = col->attr.optimize;
break;
default:
rc = -EEXIST;
break;
Expand Down Expand Up @@ -1386,6 +1391,17 @@ int db_col_attr_set(struct db_filter_col *col,
rc = -EOPNOTSUPP;
}
break;
case SCMP_FLTATR_CTL_OPTIMIZE:
switch (value) {
case 1:
case 2:
col->attr.optimize = value;
break;
default:
rc = -EOPNOTSUPP;
break;
}
break;
default:
rc = -EEXIST;
break;
Expand Down Expand Up @@ -2052,6 +2068,7 @@ int db_rule_add(struct db_filter *db, const struct db_api_rule_list *rule)
s_new->next = db->syscalls;
db->syscalls = s_new;
}
db->syscall_cnt++;
return 0;
} else if (s_iter->chains == NULL) {
if (rm_flag || !s_iter->valid) {
Expand Down
3 changes: 3 additions & 0 deletions src/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ struct db_filter_attr {
uint32_t log_enable;
/* SPEC_ALLOW related attributes */
uint32_t spec_allow;
/* SCMP_FLTATR_CTL_OPTIMIZE related attributes */
uint32_t optimize;
};

struct db_filter {
Expand All @@ -126,6 +128,7 @@ struct db_filter {

/* syscall filters, kept as a sorted single-linked list */
struct db_sys_list *syscalls;
unsigned int syscall_cnt;

/* list of rules used to build the filters, kept in order */
struct db_api_rule_list *rules;
Expand Down
Loading

0 comments on commit c9df088

Please sign in to comment.