mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
zdtm: add ucreds test for unix stream sockets
Signed-off-by: Cyrill Gorcunov <gorcunov@virtuozzo.com> Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> (cherry picked from commit ce7e4398f851d5fd2cd191134a6a7830b1f7fb94) Signed-off-by: Ahmed Elaidy <elaidya225@gmail.com> Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
This commit is contained in:
parent
dd11b13aab
commit
0dcfa267e2
2 changed files with 187 additions and 0 deletions
|
|
@ -343,6 +343,7 @@ TST_FILE = \
|
|||
deleted_unix_sock \
|
||||
sk-unix-rel \
|
||||
sk-unix-rel-seqpacket \
|
||||
sk-unix-ucred \
|
||||
deleted_dev \
|
||||
unlink_fstat00 \
|
||||
unlink_fstat01 \
|
||||
|
|
|
|||
186
test/zdtm/static/sk-unix-ucred.c
Normal file
186
test/zdtm/static/sk-unix-ucred.c
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
|
||||
const char *test_doc = "Test unix stream sockets with ucreds in queue\n";
|
||||
const char *test_author = "Cyrill Gorcunov <gorcunov@openvz.org";
|
||||
|
||||
char *filename;
|
||||
TEST_OPTION(filename, string, "socket file name", 1);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
unsigned int addrlen;
|
||||
int sock[2], accepted;
|
||||
|
||||
int ret, data;
|
||||
char path[PATH_MAX];
|
||||
char *cwd;
|
||||
|
||||
struct ucred *ucredp, ucred, *ucp;
|
||||
struct msghdr msgh;
|
||||
struct iovec iov;
|
||||
ssize_t nr;
|
||||
|
||||
union {
|
||||
struct cmsghdr cmh;
|
||||
char control[CMSG_SPACE(sizeof(struct ucred))];
|
||||
} control_un;
|
||||
struct cmsghdr *cmhp;
|
||||
socklen_t len;
|
||||
|
||||
test_init(argc, argv);
|
||||
|
||||
cwd = get_current_dir_name();
|
||||
if (!cwd) {
|
||||
pr_perror("getcwd");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s", cwd, filename);
|
||||
unlink(path);
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, filename, sizeof(addr.sun_path) - 1);
|
||||
addrlen = sizeof(addr.sun_family) + strlen(filename);
|
||||
|
||||
sock[0] = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
sock[1] = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock[0] < 0 || sock[1] < 0) {
|
||||
pr_perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setsockopt(sock[0], SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0 ||
|
||||
setsockopt(sock[1], SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0) {
|
||||
pr_perror("setsockopt SO_REUSEADDR");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setsockopt(sock[0], SOL_SOCKET, SO_PASSCRED, &(int){ 1 }, sizeof(int)) < 0 ||
|
||||
setsockopt(sock[1], SOL_SOCKET, SO_PASSCRED, &(int){ 1 }, sizeof(int)) < 0) {
|
||||
pr_perror("setsockopt SO_PASSCRED");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = bind(sock[0], (struct sockaddr *)&addr, addrlen);
|
||||
if (ret) {
|
||||
pr_perror("bind");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = listen(sock[0], 16);
|
||||
if (ret) {
|
||||
pr_perror("bind");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (connect(sock[1], (struct sockaddr *)&addr, addrlen)) {
|
||||
pr_perror("connect");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
accepted = accept(sock[0], NULL, NULL);
|
||||
if (accepted < 0) {
|
||||
pr_perror("accept");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
||||
control_un.cmh.cmsg_level = SOL_SOCKET;
|
||||
control_un.cmh.cmsg_type = SCM_CREDENTIALS;
|
||||
|
||||
msgh.msg_control = control_un.control;
|
||||
msgh.msg_controllen = sizeof(control_un.control);
|
||||
|
||||
msgh.msg_iov = &iov;
|
||||
msgh.msg_iovlen = 1;
|
||||
iov.iov_base = &data;
|
||||
iov.iov_len = sizeof(data);
|
||||
|
||||
msgh.msg_name = NULL;
|
||||
msgh.msg_namelen = 0;
|
||||
|
||||
cmhp = CMSG_FIRSTHDR(&msgh);
|
||||
cmhp->cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
||||
cmhp->cmsg_level = SOL_SOCKET;
|
||||
cmhp->cmsg_type = SCM_CREDENTIALS;
|
||||
ucp = (struct ucred *)CMSG_DATA(cmhp);
|
||||
ucp->pid = getpid();
|
||||
ucp->uid = getuid();
|
||||
ucp->gid = getgid();
|
||||
|
||||
if (sendmsg(sock[1], &msgh, 0) < 0) {
|
||||
pr_perror("send");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
||||
control_un.cmh.cmsg_level = SOL_SOCKET;
|
||||
control_un.cmh.cmsg_type = SCM_CREDENTIALS;
|
||||
|
||||
msgh.msg_control = control_un.control;
|
||||
msgh.msg_controllen = sizeof(control_un.control);
|
||||
|
||||
msgh.msg_iov = &iov;
|
||||
msgh.msg_iovlen = 1;
|
||||
iov.iov_base = &data;
|
||||
iov.iov_len = sizeof(data);
|
||||
|
||||
msgh.msg_name = NULL;
|
||||
msgh.msg_namelen = 0;
|
||||
|
||||
nr = recvmsg(accepted, &msgh, 0);
|
||||
if (nr < 0) {
|
||||
fail("recvmsg");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cmhp = CMSG_FIRSTHDR(&msgh);
|
||||
if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
|
||||
fail("bad cmsg header / message length");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (cmhp->cmsg_level != SOL_SOCKET) {
|
||||
fail("cmsg_level != SOL_SOCKET");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (cmhp->cmsg_type != SCM_CREDENTIALS) {
|
||||
pr_err("cmsg_type != SCM_CREDENTIALS\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ucredp = (struct ucred *)CMSG_DATA(cmhp);
|
||||
test_msg("Received credentials pid=%ld, uid=%ld, gid=%ld\n",
|
||||
(long) ucredp->pid, (long) ucredp->uid, (long) ucredp->gid);
|
||||
|
||||
len = sizeof(struct ucred);
|
||||
if (getsockopt(sock[0], SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
|
||||
fail("getsockopt");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test_msg("Credentials from SO_PEERCRED: pid=%ld, euid=%ld, egid=%ld\n",
|
||||
(long) ucred.pid, (long) ucred.uid, (long) ucred.gid);
|
||||
|
||||
pass();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue