[CRIU] [PATCH 3/6] restore: preserve dumpable flag when it is set to 2

Filipe Brandenburger filbranden at google.com
Tue Jun 17 20:33:51 PDT 2014


Commit d5bb7e9748fd started to preserve the dumpable flag across migration by
using prctl to get the value on dump and set it back on restore.

On some situations, the dumpable flag can be set to 2.  This happens when it is
not reset (with prctl) after using setuid() or after using execv() on a binary
that has executable but not read permissions, when the fs.suid_dumpable sysctl
is also set to 2.  However, it is not possible to set it to 2 using prctl,
which would make criu restore fail.

Fix this by checking for the value before passing it to prctl.  In case the
value of the dumpable flag was 2 at the source, check whether it is already 2
at the destination, which is likely to happen if the fs.suid_dumpable sysctl is
also set to 2 where restore is running.  In that case, preserve the value,
otherwise reset it to 0 which is the most secure fallback.

Fixes: d5bb7e9748fda52a8653edd2804a4b15c4e4a1e1

Tested:
- Using dumpable02 zdtm test after setting fs.suid_dumpable to 2.
  # sysctl -w fs.suid_dumpable=2
  # test/zdtm.sh ns/static/dumpable02
  4: DEBUG: before dump: dumpable=2
  4: DEBUG: after restore: dumpable=2
  4: PASS
  Test: zdtm/live/static/dumpable02, Result: PASS

Signed-off-by: Filipe Brandenburger <filbranden at google.com>
---
 pie/restorer.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/pie/restorer.c b/pie/restorer.c
index 9afa480aed4f..c54a491ddfda 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -191,16 +191,41 @@ static int restore_creds(CredsEntry *ce)
 
 static int restore_dumpable_flag(MmEntry *mme)
 {
+	int current_dumpable;
 	int ret;
 
-	if (mme->has_dumpable) {
+	if (!mme->has_dumpable) {
+		pr_warn("Dumpable flag not present in criu dump.\n");
+		return 0;
+	}
+
+	if (mme->dumpable == 0 || mme->dumpable == 1) {
 		ret = sys_prctl(PR_SET_DUMPABLE, mme->dumpable, 0, 0, 0);
 		if (ret) {
 			pr_err("Unable to set PR_SET_DUMPABLE: %d\n", ret);
 			return -1;
 		}
+		return 0;
 	}
 
+	/*
+	 * If dumpable flag is present but it is not 0 or 1, then we can not
+	 * use prctl to set it back.  Try to see if it is already correct
+	 * (which is likely if sysctl fs.suid_dumpable is the same when dump
+	 * and restore are run), in which case there is nothing to do.
+	 * Otherwise, set dumpable to 0 which should be a secure fallback.
+	 */
+	current_dumpable = sys_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+	if (mme->dumpable != current_dumpable) {
+		pr_warn("Dumpable flag [%d] does not match current [%d]. "
+			"Will fallback to setting it to 0 to disable it.\n",
+			mme->dumpable, current_dumpable);
+		ret = sys_prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
+		if (ret) {
+			pr_err("Unable to set PR_SET_DUMPABLE: %d\n", ret);
+			return -1;
+		}
+	}
 	return 0;
 }
 
-- 
1.9.3



More information about the CRIU mailing list