diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index 3d8655a5c..151af21ec 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -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 \ diff --git a/test/zdtm/static/sk-unix-ucred.c b/test/zdtm/static/sk-unix-ucred.c new file mode 100644 index 000000000..8cb1cb7f6 --- /dev/null +++ b/test/zdtm/static/sk-unix-ucred.c @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zdtmtst.h" + +const char *test_doc = "Test unix stream sockets with ucreds in queue\n"; +const char *test_author = "Cyrill Gorcunov 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; +}