[4/7] seccomp: Fetch seccomp flags if kernel provides

Submitted by Cyrill Gorcunov on April 6, 2018, 7:17 p.m.

Details

Message ID 20180406191708.11325-5-gorcunov@gmail.com
State Accepted
Series "seccomp, v2: Add support for per-thread c/r"
Commit 64073bdee5ec5b2d4a1231c9b17a76aa736b5ba1
Headers show

Commit Message

Cyrill Gorcunov April 6, 2018, 7:17 p.m.
Note that there is no real usage of this flag on restore,
we simply save it in image and will make a real use
later.

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
---
 criu/seccomp.c       | 39 +++++++++++++++++++++++++++++++++++++--
 images/seccomp.proto |  1 +
 2 files changed, 38 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/seccomp.c b/criu/seccomp.c
index 673812b4d2d1..c8cd35f9ae46 100644
--- a/criu/seccomp.c
+++ b/criu/seccomp.c
@@ -26,7 +26,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;
 
@@ -38,6 +39,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;
 	}
@@ -47,6 +54,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];
@@ -75,7 +83,29 @@  static int collect_filter_for_pstree(struct pstree_item *item)
 			}
 		}
 
-		inherited = find_inherited(item->parent, buf, len);
+		if (!meta)
+			meta = &meta_buf;
+
+		meta->flags = 0;
+		meta->filter_off = i;
+
+		if (ptrace(PTRACE_SECCOMP_GET_METADATA, item->pid->real, sizeof(meta), meta) < 0) {
+			if (errno == EIO) {
+				/*
+				 * No PTRACE_SECCOMP_GET_METADATA support in
+				 * kernel detected, thus simply ignore. Moving
+				 * it into kerndat is preferred but not
+				 * required.
+				 */
+				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;
 
@@ -99,6 +129,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) {
diff --git a/images/seccomp.proto b/images/seccomp.proto
index 565a7cdd4915..177e5fd4a50a 100644
--- a/images/seccomp.proto
+++ b/images/seccomp.proto
@@ -3,6 +3,7 @@  syntax = "proto2";
 message seccomp_filter {
 	required bytes		filter			= 1;
 	optional uint32		prev			= 2;
+	optional uint32		flags			= 3;
 }
 
 message seccomp_entry {