tools/testing/selftests/net/af_unix/scm_pidfd.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/af_unix/scm_pidfd.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/af_unix/scm_pidfd.c
Extension
.c
Size
11729 bytes
Lines
557
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cmsg_data {
	struct ucred *ucred;
	int *pidfd;
};

static int parse_cmsg(struct msghdr *msg, struct cmsg_data *res)
{
	struct cmsghdr *cmsg;

	if (msg->msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
		log_err("recvmsg: truncated");
		return 1;
	}

	for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
		if (cmsg->cmsg_level == SOL_SOCKET &&
		    cmsg->cmsg_type == SCM_PIDFD) {
			if (cmsg->cmsg_len < sizeof(*res->pidfd)) {
				log_err("CMSG parse: SCM_PIDFD wrong len");
				return 1;
			}

			res->pidfd = (void *)CMSG_DATA(cmsg);
		}

		if (cmsg->cmsg_level == SOL_SOCKET &&
		    cmsg->cmsg_type == SCM_CREDENTIALS) {
			if (cmsg->cmsg_len < sizeof(*res->ucred)) {
				log_err("CMSG parse: SCM_CREDENTIALS wrong len");
				return 1;
			}

			res->ucred = (void *)CMSG_DATA(cmsg);
		}
	}

	if (!res->pidfd) {
		log_err("CMSG parse: SCM_PIDFD not found");
		return 1;
	}

	if (!res->ucred) {
		log_err("CMSG parse: SCM_CREDENTIALS not found");
		return 1;
	}

	return 0;
}

static int cmsg_check(int fd)
{
	struct msghdr msg = { 0 };
	struct cmsg_data res;
	struct iovec iov;
	int data = 0;
	char control[CMSG_SPACE(sizeof(struct ucred)) +
		     CMSG_SPACE(sizeof(int))] = { 0 };
	pid_t parent_pid;
	int err;

	iov.iov_base = &data;
	iov.iov_len = sizeof(data);

	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = control;
	msg.msg_controllen = sizeof(control);

	err = recvmsg(fd, &msg, 0);
	if (err < 0) {
		log_err("recvmsg");
		return 1;
	}

	if (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
		log_err("recvmsg: truncated");
		return 1;
	}

	/* send(pfd, "x", sizeof(char), 0) */
	if (data != 'x') {
		log_err("recvmsg: data corruption");
		return 1;
	}

	if (parse_cmsg(&msg, &res)) {
		log_err("CMSG parse: parse_cmsg() failed");
		return 1;
	}

Annotation

Implementation Notes