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