Line data Source code
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 253
14 :
15 : struct scm_fp_list {
16 : struct list_head list;
17 : short count;
18 : short max;
19 : struct file *fp[SCM_MAX_FD];
20 : };
21 1 :
22 : struct scm_cookie {
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 : };
29 :
30 : extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
31 : extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
32 : extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
33 : extern void __scm_destroy(struct scm_cookie *scm);
34 : extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
35 :
36 : #ifdef CONFIG_SECURITY_NETWORK
37 : static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
38 : {
39 : security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
40 : }
41 : #else
42 : static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
43 : { }
44 0 : #endif /* CONFIG_SECURITY_NETWORK */
45 :
46 : static __inline__ void scm_destroy(struct scm_cookie *scm)
47 : {
48 0 : if (scm && scm->fp)
49 0 : __scm_destroy(scm);
50 0 : }
51 :
52 : static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
53 : struct scm_cookie *scm)
54 0 : {
55 0 : struct task_struct *p = current;
56 0 : scm->creds.uid = current_uid();
57 0 : scm->creds.gid = current_gid();
58 0 : scm->creds.pid = task_tgid_vnr(p);
59 0 : scm->fp = NULL;
60 0 : unix_get_peersec_dgram(sock, scm);
61 0 : if (msg->msg_controllen <= 0)
62 0 : return 0;
63 0 : return __scm_send(sock, msg, scm);
64 : }
65 :
66 : #ifdef CONFIG_SECURITY_NETWORK
67 : static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
68 : {
69 : char *secdata;
70 : u32 seclen;
71 : int err;
72 :
73 : if (test_bit(SOCK_PASSSEC, &sock->flags)) {
74 : err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
75 :
76 : if (!err) {
77 : put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
78 : security_release_secctx(secdata, seclen);
79 : }
80 : }
81 : }
82 : #else
83 : static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
84 : { }
85 0 : #endif /* CONFIG_SECURITY_NETWORK */
86 :
87 : static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
88 : struct scm_cookie *scm, int flags)
89 : {
90 0 : if (!msg->msg_control) {
91 0 : if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
92 0 : msg->msg_flags |= MSG_CTRUNC;
93 0 : scm_destroy(scm);
94 0 : return;
95 : }
96 :
97 0 : if (test_bit(SOCK_PASSCRED, &sock->flags))
98 0 : put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
99 :
100 0 : scm_passec(sock, msg, scm);
101 :
102 0 : if (!scm->fp)
103 0 : return;
104 :
105 0 : scm_detach_fds(msg, scm);
106 0 : }
107 1 :
108 :
109 : #endif /* __LINUX_NET_SCM_H */
110 :
|