[CRIU] [PATCH 5/5] zdtm: Tests for xids and caps

Pavel Emelyanov xemul at openvz.org
Fri Jan 27 12:45:13 EST 2012


Rather simple and straightforward and atomic tests should be.
The only problem is that after changing any from the subj the
subsequent opens for .out/.pid files fail so test actually
forks in the beginning. That said -- we need some API in the
lib/ for such forkers.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>

---
-------------- next part --------------
 test/zdtm.sh                   |    2 +
 test/zdtm/live/static/Makefile |    1 +
 test/zdtm/live/static/caps00.c |  125 ++++++++++++++++++++++++++++++++++++++++
 test/zdtm/live/static/pid00.c  |  100 +++++++++++++++++++++++--------
 4 files changed, 202 insertions(+), 26 deletions(-)
 create mode 100644 test/zdtm/live/static/caps00.c

diff --git a/test/zdtm.sh b/test/zdtm.sh
index ffc8504..100faf9 100644
--- a/test/zdtm.sh
+++ b/test/zdtm.sh
@@ -25,6 +25,8 @@ $ZP/streaming/pipe_shared00
 $ZP/transition/file_read
 $ZP/transition/fork
 $ZP/static/zombie00
+$ZP/static/pid00
+$ZP/static/caps00
 $ZP/static/cmdlinenv00
 $ZP/static/socket_listen"
 
diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
index 1e76a54..58a7032 100644
--- a/test/zdtm/live/static/Makefile
+++ b/test/zdtm/live/static/Makefile
@@ -7,6 +7,7 @@ TST_NOFILE	=				\
 		busyloop00			\
 		sleeping00			\
 		pid00				\
+		caps00				\
 		wait00				\
 		zombie00			\
 		fpu00				\
diff --git a/test/zdtm/live/static/caps00.c b/test/zdtm/live/static/caps00.c
new file mode 100644
index 0000000..1383217
--- /dev/null
+++ b/test/zdtm/live/static/caps00.c
@@ -0,0 +1,125 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc	= "Check that aps are preserved";
+const char *test_author	= "Pavel Emelianov <xemul at parallels.com>";
+
+struct cap_hdr {
+	unsigned int version;
+	int pid;
+};
+
+struct cap_data {
+	unsigned int	eff;
+	unsigned int	prm;
+	unsigned int	inh;
+};
+
+#define _LINUX_CAPABILITY_VERSION_3     0x20080522
+#define _LINUX_CAPABILITY_U32S_3        2
+#define CAP_CHOWN            0
+#define CAP_DAC_OVERRIDE     1
+
+int capget(struct cap_hdr *hdrp, struct cap_data *datap);
+int capset(struct cap_hdr *hdrp, const struct cap_data *datap);
+
+int main(int argc, char **argv)
+{
+	int pid, s_p[2], f_p[2], r_p[3];
+	char res = 'x';
+
+	test_init(argc, argv);
+
+	pipe(s_p);
+	pipe(f_p);
+	pipe(r_p);
+
+	pid = fork();
+	if (pid == 0) {
+		struct cap_hdr hdr;
+		struct cap_data data[_LINUX_CAPABILITY_U32S_3];
+		struct cap_data data_2[_LINUX_CAPABILITY_U32S_3];
+
+		close(s_p[0]);
+		close(f_p[1]);
+		close(r_p[0]);
+
+		hdr.version = _LINUX_CAPABILITY_VERSION_3;
+		hdr.pid = 0;
+
+		capget(&hdr, data);
+
+		hdr.version = _LINUX_CAPABILITY_VERSION_3;
+		hdr.pid = 0;
+
+		data[0].eff &= ~((1 << CAP_CHOWN) | (1 << CAP_DAC_OVERRIDE));
+		data[0].prm &= ~(1 << CAP_DAC_OVERRIDE);
+
+		capset(&hdr, data);
+
+		close(s_p[1]);
+
+		read(f_p[0], &res, 1);
+		close(f_p[0]);
+
+		hdr.version = _LINUX_CAPABILITY_VERSION_3;
+		hdr.pid = 0;
+
+		capget(&hdr, data_2);
+
+		if (data[0].eff != data_2[0].eff) {
+			res = '1';
+			goto bad;
+		}
+		if (data[1].eff != data_2[1].eff) {
+			res = '2';
+			goto bad;
+		}
+		if (data[0].prm != data_2[0].prm) {
+			res = '3';
+			goto bad;
+		}
+		if (data[1].prm != data_2[1].prm) {
+			res = '4';
+			goto bad;
+		}
+		if (data[0].inh != data_2[0].inh) {
+			res = '3';
+			goto bad;
+		}
+		if (data[1].inh != data_2[1].inh) {
+			res = '4';
+			goto bad;
+		}
+
+		res = '0';
+bad:
+		write(r_p[1], &res, 1);
+		close(r_p[1]);
+		_exit(0);
+	}
+
+	close(f_p[0]);
+	close(s_p[1]);
+	close(r_p[1]);
+
+	read(s_p[0], &res, 1);
+	close(s_p[0]);
+
+	test_daemon();
+	test_waitsig();
+
+	close(f_p[1]);
+
+	read(r_p[0], &res, 1);
+	if (res == '0')
+		pass();
+	else
+		fail("Fail: %c", res);
+
+	return 0;
+}
diff --git a/test/zdtm/live/static/pid00.c b/test/zdtm/live/static/pid00.c
index 030aeda..0b03ef5 100644
--- a/test/zdtm/live/static/pid00.c
+++ b/test/zdtm/live/static/pid00.c
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE
 #include <errno.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -7,40 +8,87 @@
 const char *test_doc	= "Check that p?pid and e?[ug]id didn't change";
 const char *test_author	= "Pavel Emelianov <xemul at parallels.com>";
 
+int setfsuid(uid_t fsuid);
+int setfsgid(uid_t fsgid);
+
 int main(int argc, char **argv)
 {
-	pid_t pid, ppid;
-	uid_t uid, euid;
-	gid_t gid, egid;
+	int pid, s_p[2], f_p[2], r_p[3];
+	const __uid_t w_ruid = 1, w_euid = 2, w_suid = 3, w_fsuid = w_euid;
+	const __uid_t w_rgid = 5, w_egid = 6, w_sgid = 7, w_fsgid = 8;
+	__uid_t rid, eid, sid, fsid;
+	char res = 'x';
 
 	test_init(argc, argv);
 
-#define SET_XID(id)	id = get##id()
-	SET_XID(pid);
-	ppid = 1;	/* SET_XID(ppid); 	daemonization confuses it */
-	SET_XID(uid);
-	SET_XID(euid);
-	SET_XID(gid);
-	SET_XID(egid);
+	pipe(s_p);
+	pipe(f_p);
+	pipe(r_p);
+
+	pid = fork();
+	if (pid == 0) {
+		close(s_p[0]);
+		close(f_p[1]);
+		close(r_p[0]);
+
+		setresgid(w_rgid, w_egid, w_sgid);
+		setfsgid(w_fsgid);
+		setresuid(w_ruid, w_euid, w_suid);
+		/* fsuid change is impossible after above */
+
+		close(s_p[1]);
+
+		read(f_p[0], &res, 1);
+		close(f_p[0]);
+
+#define CHECK_ID(__t, __w, __e)	do {			\
+		if (__t##id != w_##__t##__w##id) {	\
+			res = __e;			\
+			goto bad;			\
+		}					\
+	} while (0)
+
+		rid = eid = sid = fsid = 0;
+		getresuid(&rid, &eid, &sid);
+		fsid = setfsuid(w_euid);
+		CHECK_ID(r, u, '1');
+		CHECK_ID(e, u, '2');
+		CHECK_ID(s, u, '3');
+		CHECK_ID(s, u, '3');
+		CHECK_ID(fs, u, '4');
+
+		rid = eid = sid = fsid = 0;
+		getresgid(&rid, &eid, &sid);
+		fsid = setfsgid(w_fsgid);
+		CHECK_ID(r, g, '5');
+		CHECK_ID(e, g, '6');
+		CHECK_ID(s, g, '7');
+		CHECK_ID(fs, g, '8');
+
+		res = '0';
+bad:
+		write(r_p[1], &res, 1);
+		close(r_p[1]);
+		_exit(0);
+	}
+
+	close(f_p[0]);
+	close(s_p[1]);
+	close(r_p[1]);
+
+	read(s_p[0], &res, 1);
+	close(s_p[0]);
 
 	test_daemon();
 	test_waitsig();
 
-#define CHECK(id) do {					\
-	if (id != get##id()) {				\
-		fail("%s != get%s()\n", #id, #id);	\
-		goto out;				\
-	}						\
-} while (0)
-
-	CHECK(pid);
-	CHECK(ppid);
-	CHECK(uid);
-	CHECK(euid);
-	CHECK(gid);
-	CHECK(egid);
-
-	pass();
-out:
+	close(f_p[1]);
+
+	read(r_p[0], &res, 1);
+	if (res == '0')
+		pass();
+	else
+		fail("Fail: %c", res);
+
 	return 0;
 }
-- 
1.6.5.2


More information about the CRIU mailing list