mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +00:00
zdtm: Tests for xids and caps
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@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
parent
16c58dbd11
commit
d40e50d7c9
@ -25,6 +25,8 @@ $ZP/streaming/pipe_shared00
|
|||||||
$ZP/transition/file_read
|
$ZP/transition/file_read
|
||||||
$ZP/transition/fork
|
$ZP/transition/fork
|
||||||
$ZP/static/zombie00
|
$ZP/static/zombie00
|
||||||
|
$ZP/static/pid00
|
||||||
|
$ZP/static/caps00
|
||||||
$ZP/static/cmdlinenv00
|
$ZP/static/cmdlinenv00
|
||||||
$ZP/static/socket_listen"
|
$ZP/static/socket_listen"
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ TST_NOFILE = \
|
|||||||
busyloop00 \
|
busyloop00 \
|
||||||
sleeping00 \
|
sleeping00 \
|
||||||
pid00 \
|
pid00 \
|
||||||
|
caps00 \
|
||||||
wait00 \
|
wait00 \
|
||||||
zombie00 \
|
zombie00 \
|
||||||
fpu00 \
|
fpu00 \
|
||||||
|
125
test/zdtm/live/static/caps00.c
Normal file
125
test/zdtm/live/static/caps00.c
Normal file
@ -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@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;
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.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_doc = "Check that p?pid and e?[ug]id didn't change";
|
||||||
const char *test_author = "Pavel Emelianov <xemul@parallels.com>";
|
const char *test_author = "Pavel Emelianov <xemul@parallels.com>";
|
||||||
|
|
||||||
|
int setfsuid(uid_t fsuid);
|
||||||
|
int setfsgid(uid_t fsgid);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
pid_t pid, ppid;
|
int pid, s_p[2], f_p[2], r_p[3];
|
||||||
uid_t uid, euid;
|
const __uid_t w_ruid = 1, w_euid = 2, w_suid = 3, w_fsuid = w_euid;
|
||||||
gid_t gid, egid;
|
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);
|
test_init(argc, argv);
|
||||||
|
|
||||||
#define SET_XID(id) id = get##id()
|
pipe(s_p);
|
||||||
SET_XID(pid);
|
pipe(f_p);
|
||||||
ppid = 1; /* SET_XID(ppid); daemonization confuses it */
|
pipe(r_p);
|
||||||
SET_XID(uid);
|
|
||||||
SET_XID(euid);
|
pid = fork();
|
||||||
SET_XID(gid);
|
if (pid == 0) {
|
||||||
SET_XID(egid);
|
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_daemon();
|
||||||
test_waitsig();
|
test_waitsig();
|
||||||
|
|
||||||
#define CHECK(id) do { \
|
close(f_p[1]);
|
||||||
if (id != get##id()) { \
|
|
||||||
fail("%s != get%s()\n", #id, #id); \
|
|
||||||
goto out; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
CHECK(pid);
|
read(r_p[0], &res, 1);
|
||||||
CHECK(ppid);
|
if (res == '0')
|
||||||
CHECK(uid);
|
pass();
|
||||||
CHECK(euid);
|
else
|
||||||
CHECK(gid);
|
fail("Fail: %c", res);
|
||||||
CHECK(egid);
|
|
||||||
|
|
||||||
pass();
|
|
||||||
out:
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user