@@ -23,7 +23,8 @@ static int next_filter_id = 0;
static struct seccomp_info **filters = NULL;
static struct seccomp_info *find_inherited(struct pstree_item *parent,
- struct sock_filter *filter, int len)
+ struct sock_filter *filter,
+ int len, struct seccomp_metadata *meta)
{
struct seccomp_info *info;
@@ -35,6 +36,12 @@ static struct seccomp_info *find_inherited(struct pstree_item *parent,
if (len != info->filter.filter.len)
continue;
+ if (!!meta ^ !!info->filter.has_flags)
+ continue;
+ if (info->filter.has_flags && meta) {
+ if (info->filter.flags != meta->flags)
+ continue;
+ }
if (!memcmp(filter, info->filter.filter.data, len))
return info;
}
@@ -44,6 +51,7 @@ static struct seccomp_info *find_inherited(struct pstree_item *parent,
static int collect_filter_for_pstree(struct pstree_item *item)
{
+ struct seccomp_metadata meta_buf, *meta = &meta_buf;
struct seccomp_info *infos = NULL, *cursor;
int info_count, i, ret = -1;
struct sock_filter buf[BPF_MAXINSNS];
@@ -72,7 +80,20 @@ static int collect_filter_for_pstree(struct pstree_item *item)
}
}
- inherited = find_inherited(item->parent, buf, len);
+ if (!meta)
+ meta = &meta_buf;
+
+ if (ptrace(PTRACE_SECCOMP_GET_METADATA, item->pid->real, i, meta) < 0) {
+ if (errno == EIO) {
+ meta = NULL;
+ } else {
+ pr_perror("couldn't fetch seccomp metadata: pid %d pos %d",
+ item->pid->real, i);
+ goto out;
+ }
+ }
+
+ inherited = find_inherited(item->parent, buf, len, meta);
if (inherited) {
bool found = false;
@@ -96,6 +117,11 @@ static int collect_filter_for_pstree(struct pstree_item *item)
goto out;
seccomp_filter__init(&info->filter);
+ if (meta) {
+ info->filter.has_flags = true;
+ info->filter.flags = meta->flags;
+ }
+
info->filter.filter.len = len * sizeof(struct sock_filter);
info->filter.filter.data = xmalloc(info->filter.filter.len);
if (!info->filter.filter.data) {
@@ -3,6 +3,7 @@ syntax = "proto2";
message seccomp_filter {
required bytes filter = 1;
optional uint32 prev = 2;
+ optional uint32 flags = 3;
}
message seccomp_entry {