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