1 #ifndef __LINUX_NET_SCM_H 2 #define __LINUX_NET_SCM_H 3 4 #include <linux/limits.h> 5 #include <linux/net.h> 6 #include <linux/security.h> 7 #include <linux/pid.h> 8 #include <linux/nsproxy.h> 9 10 /* Well, we should have at least one descriptor open 11 * to accept passed FDs 8) 12 */ 13 #define SCM_MAX_FD 255 14 15 struct scm_fp_list 16 { 17 int count; 18 struct file *fp[SCM_MAX_FD]; 19 }; 20 21 struct scm_cookie 22 { 23 struct ucred creds; /* Skb credentials */ 24 struct scm_fp_list *fp; /* Passed files */ 25 #ifdef CONFIG_SECURITY_NETWORK 26 u32 secid; /* Passed security ID */ 27 #endif 28 unsigned long seq; /* Connection seqno */ 29 }; 30 31 extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); 32 extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm); 33 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); 34 extern void __scm_destroy(struct scm_cookie *scm); 35 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); 36 37 #ifdef CONFIG_SECURITY_NETWORK 38 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) 39 { 40 security_socket_getpeersec_dgram(sock, NULL, &scm->secid); 41 } 42 #else 43 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) 44 { } 45 #endif /* CONFIG_SECURITY_NETWORK */ 46 47 static __inline__ void scm_destroy(struct scm_cookie *scm) 48 { 49 if (scm && scm->fp) 50 __scm_destroy(scm); 51 } 52 53 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, 54 struct scm_cookie *scm) 55 { 56 struct task_struct *p = current; 57 scm->creds.uid = p->uid; 58 scm->creds.gid = p->gid; 59 scm->creds.pid = task_tgid_vnr(p); 60 scm->fp = NULL; 61 scm->seq = 0; 62 unix_get_peersec_dgram(sock, scm); 63 if (msg->msg_controllen <= 0) 64 return 0; 65 return __scm_send(sock, msg, scm); 66 } 67 68 #ifdef CONFIG_SECURITY_NETWORK 69 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) 70 { 71 char *secdata; 72 u32 seclen; 73 int err; 74 75 if (test_bit(SOCK_PASSSEC, &sock->flags)) { 76 err = security_secid_to_secctx(scm->secid, &secdata, &seclen); 77 78 if (!err) { 79 put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); 80 security_release_secctx(secdata, seclen); 81 } 82 } 83 } 84 #else 85 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) 86 { } 87 #endif /* CONFIG_SECURITY_NETWORK */ 88 89 static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, 90 struct scm_cookie *scm, int flags) 91 { 92 if (!msg->msg_control) 93 { 94 if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) 95 msg->msg_flags |= MSG_CTRUNC; 96 scm_destroy(scm); 97 return; 98 } 99 100 if (test_bit(SOCK_PASSCRED, &sock->flags)) 101 put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); 102 103 scm_passec(sock, msg, scm); 104 105 if (!scm->fp) 106 return; 107 108 scm_detach_fds(msg, scm); 109 } 110 111 112 #endif /* __LINUX_NET_SCM_H */ 113 114