Add delay-init quirk for Corsair K70 RGB keyboards
[pandora-kernel.git] / include / net / scm.h
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 user_struct      *user;
20         struct file             *fp[SCM_MAX_FD];
21 };
22
23 struct scm_cookie {
24         struct pid              *pid;           /* Skb credentials */
25         const struct cred       *cred;
26         struct scm_fp_list      *fp;            /* Passed files         */
27         struct ucred            creds;          /* Skb credentials      */
28 #ifdef CONFIG_SECURITY_NETWORK
29         u32                     secid;          /* Passed security ID   */
30 #endif
31 };
32
33 extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
34 extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
35 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
36 extern void __scm_destroy(struct scm_cookie *scm);
37 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
38
39 #ifdef CONFIG_SECURITY_NETWORK
40 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
41 {
42         security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
43 }
44 #else
45 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
46 { }
47 #endif /* CONFIG_SECURITY_NETWORK */
48
49 static __inline__ void scm_set_cred(struct scm_cookie *scm,
50                                     struct pid *pid, const struct cred *cred)
51 {
52         scm->pid  = get_pid(pid);
53         scm->cred = cred ? get_cred(cred) : NULL;
54         cred_real_to_ucred(pid, cred, &scm->creds);
55 }
56
57 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
58 {
59         put_pid(scm->pid);
60         scm->pid  = NULL;
61
62         if (scm->cred)
63                 put_cred(scm->cred);
64         scm->cred = NULL;
65 }
66
67 static __inline__ void scm_destroy(struct scm_cookie *scm)
68 {
69         scm_destroy_cred(scm);
70         if (scm && scm->fp)
71                 __scm_destroy(scm);
72 }
73
74 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
75                                struct scm_cookie *scm, bool forcecreds)
76 {
77         memset(scm, 0, sizeof(*scm));
78         if (forcecreds)
79                 scm_set_cred(scm, task_tgid(current), current_cred());
80         unix_get_peersec_dgram(sock, scm);
81         if (msg->msg_controllen <= 0)
82                 return 0;
83         return __scm_send(sock, msg, scm);
84 }
85
86 #ifdef CONFIG_SECURITY_NETWORK
87 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
88 {
89         char *secdata;
90         u32 seclen;
91         int err;
92
93         if (test_bit(SOCK_PASSSEC, &sock->flags)) {
94                 err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
95
96                 if (!err) {
97                         put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
98                         security_release_secctx(secdata, seclen);
99                 }
100         }
101 }
102 #else
103 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
104 { }
105 #endif /* CONFIG_SECURITY_NETWORK */
106
107 static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
108                                 struct scm_cookie *scm, int flags)
109 {
110         if (!msg->msg_control) {
111                 if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
112                         msg->msg_flags |= MSG_CTRUNC;
113                 scm_destroy(scm);
114                 return;
115         }
116
117         if (test_bit(SOCK_PASSCRED, &sock->flags))
118                 put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
119
120         scm_destroy_cred(scm);
121
122         scm_passec(sock, msg, scm);
123
124         if (!scm->fp)
125                 return;
126         
127         scm_detach_fds(msg, scm);
128 }
129
130
131 #endif /* __LINUX_NET_SCM_H */
132