Commit d40e50d7 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 16c58dbd
...@@ -25,6 +25,8 @@ $ZP/streaming/pipe_shared00 ...@@ -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 = \ ...@@ -7,6 +7,7 @@ TST_NOFILE = \
busyloop00 \ busyloop00 \
sleeping00 \ sleeping00 \
pid00 \ pid00 \
caps00 \
wait00 \ wait00 \
zombie00 \ zombie00 \
fpu00 \ fpu00 \
......
#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;
}
#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 @@ ...@@ -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);
SET_XID(gid);
SET_XID(egid);
test_daemon(); pid = fork();
test_waitsig(); 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 */
#define CHECK(id) do { \ close(s_p[1]);
if (id != get##id()) { \
fail("%s != get%s()\n", #id, #id); \ read(f_p[0], &res, 1);
goto out; \ close(f_p[0]);
#define CHECK_ID(__t, __w, __e) do { \
if (__t##id != w_##__t##__w##id) { \
res = __e; \
goto bad; \
} \ } \
} while (0) } 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');
CHECK(pid); res = '0';
CHECK(ppid); bad:
CHECK(uid); write(r_p[1], &res, 1);
CHECK(euid); close(r_p[1]);
CHECK(gid); _exit(0);
CHECK(egid); }
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(); pass();
out: else
fail("Fail: %c", res);
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment