[CRIU] [PATCH 1/2] cr-check: use two features to verify userfaultfd availability

Mike Rapoport rppt at linux.vnet.ibm.com
Tue Aug 8 10:05:56 MSK 2017


For the older kernels the implementation of userfaultfd would not include
non-cooperative mode. In such case it is still possible to use uffd and
enable lazy-pages, but if the restored process will change its virtual
memory layout during restore, we'll get memory corruption.

After this change 'criu check --feature uffd' will report success if the kernel
supports userfaultfd at all and 'criu check --feature uffd-noncoop' will
report success if the kernel supports non-cooperative userfaultfd.

Suggested-by: Pavel Emelyanov <xemul at virtuozzo.com>
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/cr-check.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/criu/cr-check.c b/criu/cr-check.c
index cf200d3..061fd3e 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1048,11 +1048,6 @@ static int check_compat_cr(void)
 
 static int check_uffd(void)
 {
-	unsigned long features = UFFD_FEATURE_EVENT_FORK |
-		UFFD_FEATURE_EVENT_REMAP |
-		UFFD_FEATURE_EVENT_UNMAP |
-		UFFD_FEATURE_EVENT_REMOVE;
-
 	if (kerndat_uffd())
 		return -1;
 
@@ -1061,8 +1056,21 @@ static int check_uffd(void)
 		return -1;
 	}
 
+	return 0;
+}
+
+static int check_uffd_noncoop(void)
+{
+	unsigned long features = UFFD_FEATURE_EVENT_FORK |
+		UFFD_FEATURE_EVENT_REMAP |
+		UFFD_FEATURE_EVENT_UNMAP |
+		UFFD_FEATURE_EVENT_REMOVE;
+
+	if (check_uffd())
+		return -1;
+
 	if ((kdat.uffd_features & features) != features) {
-		pr_err("Userfaultfd missing essential features\n");
+		pr_err("Non-cooperative UFFD is not supported\n");
 		return -1;
 	}
 
@@ -1250,6 +1258,7 @@ int cr_check(void)
 		ret |= check_autofs();
 		ret |= check_compat_cr();
 		ret |= check_uffd();
+		ret |= check_uffd_noncoop();
 	}
 
 	print_on_level(DEFAULT_LOGLEVEL, "%s\n", ret ? CHECK_MAYBE : CHECK_GOOD);
@@ -1317,7 +1326,8 @@ static struct feature_list feature_list[] = {
 	{ "autofs", check_autofs },
 	{ "tcp_half_closed", check_tcp_halt_closed },
 	{ "compat_cr", check_compat_cr },
-	{ "lazy_pages", check_uffd },
+	{ "uffd", check_uffd },
+	{ "uffd-noncoop", check_uffd_noncoop },
 	{ "sk_ns", check_sk_netns },
 	{ "nsid", check_nsid },
 	{ "link_nsid", check_link_nsid},
-- 
2.7.4



More information about the CRIU mailing list