Skip to content

Commit c32c6de

Browse files
committed
zdtm: add sk-unix-cred test for SCM_CREDENTIALS checkpoint/restore
Test that SCM_CREDENTIALS ancillary messages queued in a unix socket are correctly saved and restored by CRIU. Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com>
1 parent 78dd8e2 commit c32c6de

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

test/zdtm/static/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ TST_DIR = \
469469
sk-unix-mntns \
470470
sk-unix01 \
471471
sk-unix01-seqpacket \
472+
sk-unix-cred \
472473
sk-unix-dgram-ghost \
473474
unsupported_children_collision \
474475
shared_slave_mount_children \

test/zdtm/static/sk-unix-cred.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <errno.h>
5+
#include <unistd.h>
6+
#include <sys/types.h>
7+
#include <sys/socket.h>
8+
#include <sys/un.h>
9+
#include "zdtmtst.h"
10+
11+
const char *test_doc = "Test SCM_CREDENTIALS checkpoint/restore in unix socket queue\n";
12+
const char *test_author = "Ahmed Elaidy <elaidya225@gmail.com>";
13+
char *dirname;
14+
TEST_OPTION(dirname, string, "directory name", 1);
15+
int main(int argc, char *argv[])
16+
{
17+
int sk[2];
18+
struct msghdr msg = {};
19+
struct iovec iov;
20+
char buf[64];
21+
char cmsg_buf[CMSG_SPACE(sizeof(struct ucred))];
22+
struct cmsghdr *cmsg;
23+
struct ucred *cred;
24+
struct ucred send_cred;
25+
int opt = 1;
26+
27+
test_init(argc, argv);
28+
29+
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sk) < 0)
30+
return pr_perror("socketpair");
31+
32+
if (setsockopt(sk[1], SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)) < 0)
33+
return pr_perror("setsockopt SO_PASSCRED");
34+
35+
/* Send a message with SCM_CREDENTIALS */
36+
send_cred.pid = getpid();
37+
send_cred.uid = getuid();
38+
send_cred.gid = getgid();
39+
40+
iov.iov_base = buf;
41+
iov.iov_len = sizeof(buf);
42+
43+
memset(cmsg_buf, 0, sizeof(cmsg_buf));
44+
msg.msg_iov = &iov;
45+
msg.msg_iovlen = 1;
46+
msg.msg_control = cmsg_buf;
47+
msg.msg_controllen = sizeof(cmsg_buf);
48+
49+
cmsg = CMSG_FIRSTHDR(&msg);
50+
cmsg->cmsg_level = SOL_SOCKET;
51+
cmsg->cmsg_type = SCM_CREDENTIALS;
52+
cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
53+
memcpy(CMSG_DATA(cmsg), &send_cred, sizeof(struct ucred));
54+
55+
strcpy(buf, "hello");
56+
if (sendmsg(sk[0], &msg, 0) < 0)
57+
return pr_perror("sendmsg");
58+
59+
test_daemon();
60+
test_waitsig();
61+
62+
/* Receive and verify credentials after restore */
63+
memset(buf, 0, sizeof(buf));
64+
memset(cmsg_buf, 0, sizeof(cmsg_buf));
65+
msg.msg_control = cmsg_buf;
66+
msg.msg_controllen = sizeof(cmsg_buf);
67+
iov.iov_base = buf;
68+
iov.iov_len = sizeof(buf);
69+
70+
if (recvmsg(sk[1], &msg, 0) < 0)
71+
return pr_perror("recvmsg");
72+
73+
cmsg = CMSG_FIRSTHDR(&msg);
74+
if (!cmsg) {
75+
fail("no cmsg after restore");
76+
return 1;
77+
}
78+
79+
if (cmsg->cmsg_type != SCM_CREDENTIALS) {
80+
fail("wrong cmsg type after restore");
81+
return 1;
82+
}
83+
84+
cred = (struct ucred *)CMSG_DATA(cmsg);
85+
86+
if (cred->uid != send_cred.uid || cred->gid != send_cred.gid) {
87+
fail("credentials mismatch after restore: "
88+
"uid %d/%d gid %d/%d",
89+
cred->uid, send_cred.uid,
90+
cred->gid, send_cred.gid);
91+
return 1;
92+
}
93+
94+
close(sk[0]);
95+
close(sk[1]);
96+
97+
pass();
98+
return 0;
99+
}

0 commit comments

Comments
 (0)