xref: /openbmc/linux/include/net/scm.h (revision 877ce7c1b3afd69a9b1caeb1b9964c992641f52a)
11da177e4SLinus Torvalds #ifndef __LINUX_NET_SCM_H
21da177e4SLinus Torvalds #define __LINUX_NET_SCM_H
31da177e4SLinus Torvalds 
41da177e4SLinus Torvalds #include <linux/limits.h>
51da177e4SLinus Torvalds #include <linux/net.h>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds /* Well, we should have at least one descriptor open
81da177e4SLinus Torvalds  * to accept passed FDs 8)
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds #define SCM_MAX_FD	(OPEN_MAX-1)
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds struct scm_fp_list
131da177e4SLinus Torvalds {
141da177e4SLinus Torvalds 	int		count;
151da177e4SLinus Torvalds 	struct file	*fp[SCM_MAX_FD];
161da177e4SLinus Torvalds };
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds struct scm_cookie
191da177e4SLinus Torvalds {
201da177e4SLinus Torvalds 	struct ucred		creds;		/* Skb credentials	*/
211da177e4SLinus Torvalds 	struct scm_fp_list	*fp;		/* Passed files		*/
22*877ce7c1SCatherine Zhang #ifdef CONFIG_SECURITY_NETWORK
23*877ce7c1SCatherine Zhang 	char			*secdata;	/* Security context	*/
24*877ce7c1SCatherine Zhang 	u32			seclen;		/* Security length	*/
25*877ce7c1SCatherine Zhang #endif
261da177e4SLinus Torvalds 	unsigned long		seq;		/* Connection seqno	*/
271da177e4SLinus Torvalds };
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
301da177e4SLinus Torvalds extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
311da177e4SLinus Torvalds extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
321da177e4SLinus Torvalds extern void __scm_destroy(struct scm_cookie *scm);
331da177e4SLinus Torvalds extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds static __inline__ void scm_destroy(struct scm_cookie *scm)
361da177e4SLinus Torvalds {
371da177e4SLinus Torvalds 	if (scm && scm->fp)
381da177e4SLinus Torvalds 		__scm_destroy(scm);
391da177e4SLinus Torvalds }
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
421da177e4SLinus Torvalds 			       struct scm_cookie *scm)
431da177e4SLinus Torvalds {
441d541dddSBenjamin LaHaise 	struct task_struct *p = current;
451d541dddSBenjamin LaHaise 	scm->creds.uid = p->uid;
461d541dddSBenjamin LaHaise 	scm->creds.gid = p->gid;
471d541dddSBenjamin LaHaise 	scm->creds.pid = p->tgid;
481d541dddSBenjamin LaHaise 	scm->fp = NULL;
491d541dddSBenjamin LaHaise 	scm->seq = 0;
501da177e4SLinus Torvalds 	if (msg->msg_controllen <= 0)
511da177e4SLinus Torvalds 		return 0;
521da177e4SLinus Torvalds 	return __scm_send(sock, msg, scm);
531da177e4SLinus Torvalds }
541da177e4SLinus Torvalds 
55*877ce7c1SCatherine Zhang #ifdef CONFIG_SECURITY_NETWORK
56*877ce7c1SCatherine Zhang static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
57*877ce7c1SCatherine Zhang {
58*877ce7c1SCatherine Zhang 	if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL)
59*877ce7c1SCatherine Zhang 		put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata);
60*877ce7c1SCatherine Zhang }
61*877ce7c1SCatherine Zhang #else
62*877ce7c1SCatherine Zhang static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
63*877ce7c1SCatherine Zhang { }
64*877ce7c1SCatherine Zhang #endif /* CONFIG_SECURITY_NETWORK */
65*877ce7c1SCatherine Zhang 
661da177e4SLinus Torvalds static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
671da177e4SLinus Torvalds 				struct scm_cookie *scm, int flags)
681da177e4SLinus Torvalds {
691da177e4SLinus Torvalds 	if (!msg->msg_control)
701da177e4SLinus Torvalds 	{
711da177e4SLinus Torvalds 		if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
721da177e4SLinus Torvalds 			msg->msg_flags |= MSG_CTRUNC;
731da177e4SLinus Torvalds 		scm_destroy(scm);
741da177e4SLinus Torvalds 		return;
751da177e4SLinus Torvalds 	}
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 	if (test_bit(SOCK_PASSCRED, &sock->flags))
781da177e4SLinus Torvalds 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
791da177e4SLinus Torvalds 
80*877ce7c1SCatherine Zhang 	scm_passec(sock, msg, scm);
81*877ce7c1SCatherine Zhang 
821da177e4SLinus Torvalds 	if (!scm->fp)
831da177e4SLinus Torvalds 		return;
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds 	scm_detach_fds(msg, scm);
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds #endif /* __LINUX_NET_SCM_H */
901da177e4SLinus Torvalds 
91