オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Contents of /trunk/1.5.x/ccs-patch/include/linux/tomoyo_socket.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 776 - (show annotations) (download) (as text)
Wed Dec 5 05:29:11 2007 UTC (16 years, 5 months ago) by kumaneko
File MIME type: text/x-chdr
File size: 9362 byte(s)


1 /*
2 * include/linux/tomoyo_socket.h
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2007 NTT DATA CORPORATION
7 *
8 * Version: 1.5.3-pre 2007/12/03
9 *
10 * This file is applicable to both 2.4.30 and 2.6.11 and later.
11 * See README.ccs for ChangeLog.
12 *
13 */
14
15 #ifndef _LINUX_TOMOYO_SOCKET_H
16 #define _LINUX_TOMOYO_SOCKET_H
17
18 /***** TOMOYO Linux start. *****/
19
20 #if defined(CONFIG_TOMOYO)
21
22 #include <net/ip.h>
23 #include <net/ipv6.h>
24 #include <net/udp.h>
25 #include <asm/uaccess.h>
26
27 #include <linux/version.h>
28 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
29 #define sk_family family
30 #define sk_protocol protocol
31 #define sk_type type
32 #define sk_receive_queue receive_queue
33 #endif
34
35 #define MAX_SOCK_ADDR 128 /* net/socket.c */
36
37 static inline int CheckSocketCreatePermission(int family, int type, int protocol)
38 {
39 int error = 0;
40 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
41 if (family == PF_INET || family == PF_INET6) {
42 switch (type) {
43 case SOCK_STREAM:
44 error = CheckCapabilityACL(TOMOYO_INET_STREAM_SOCKET_CREATE);
45 break;
46 case SOCK_DGRAM:
47 error = CheckCapabilityACL(TOMOYO_USE_INET_DGRAM_SOCKET);
48 break;
49 case SOCK_RAW:
50 error = CheckCapabilityACL(TOMOYO_USE_INET_RAW_SOCKET);
51 break;
52 }
53 } else if (family == PF_PACKET) {
54 error = CheckCapabilityACL(TOMOYO_USE_PACKET_SOCKET);
55 } else if (family == PF_ROUTE) {
56 error = CheckCapabilityACL(TOMOYO_USE_ROUTE_SOCKET);
57 }
58 return error;
59 }
60
61 static inline int CheckSocketListenPermission(struct socket *sock)
62 {
63 int error = 0;
64 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
65 if (sock->type == SOCK_STREAM) {
66 switch (sock->sk->sk_family) {
67 case PF_INET:
68 case PF_INET6:
69 error = CheckCapabilityACL(TOMOYO_INET_STREAM_SOCKET_LISTEN);
70 if (!error) {
71 char addr[MAX_SOCK_ADDR];
72 int addr_len;
73 if (sock->ops->getname(sock, (struct sockaddr *) addr, &addr_len, 0) == 0) {
74 switch (((struct sockaddr *) addr)->sa_family) {
75 case AF_INET6:
76 error = CheckNetworkListenACL(1, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, ((struct sockaddr_in6 *) addr)->sin6_port);
77 break;
78 case AF_INET:
79 error = CheckNetworkListenACL(0, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, ((struct sockaddr_in *) addr)->sin_port);
80 break;
81 }
82 } else {
83 error = -EPERM;
84 }
85 }
86 break;
87 }
88 }
89 return error;
90 }
91
92 static inline int CheckSocketConnectPermission(struct socket *sock, struct sockaddr *addr, int addr_len)
93 {
94 int error = 0;
95 const unsigned int type = sock->type;
96 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
97 if (type == SOCK_STREAM || type == SOCK_DGRAM || type == SOCK_RAW) {
98 switch (addr->sa_family) {
99 case AF_INET6:
100 if (addr_len >= SIN6_LEN_RFC2133) {
101 if (type != SOCK_RAW) {
102 error = CheckNetworkConnectACL(1, type, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, ((struct sockaddr_in6 *) addr)->sin6_port);
103 } else {
104 error = CheckNetworkConnectACL(1, SOCK_RAW, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, htons(sock->sk->sk_protocol));
105 }
106 }
107 break;
108 case AF_INET:
109 if (addr_len >= sizeof(struct sockaddr_in)) {
110 if (type != SOCK_RAW) {
111 error = CheckNetworkConnectACL(0, type, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, ((struct sockaddr_in *) addr)->sin_port);
112 } else {
113 error = CheckNetworkConnectACL(0, SOCK_RAW, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, htons(sock->sk->sk_protocol));
114 }
115 }
116 break;
117 }
118 }
119 if (type == SOCK_STREAM) {
120 switch (sock->sk->sk_family) {
121 case PF_INET:
122 case PF_INET6:
123 error = CheckCapabilityACL(TOMOYO_INET_STREAM_SOCKET_CONNECT) ? -EPERM : error;
124 break;
125 }
126 }
127 return error;
128 }
129
130 static inline int CheckSocketBindPermission(struct socket *sock, struct sockaddr *addr, int addr_len)
131 {
132 int error = 0;
133 const unsigned int type = sock->type;
134 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
135 if (type == SOCK_STREAM || type == SOCK_DGRAM || type == SOCK_RAW) {
136 switch (addr->sa_family) {
137 case AF_INET6:
138 if (addr_len >= SIN6_LEN_RFC2133) {
139 if (type != SOCK_RAW) {
140 error = CheckNetworkBindACL(1, type, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, ((struct sockaddr_in6 *) addr)->sin6_port);
141 } else {
142 error = CheckNetworkBindACL(1, SOCK_RAW, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, htons(sock->sk->sk_protocol));
143 }
144 }
145 break;
146 case AF_INET:
147 if (addr_len >= sizeof(struct sockaddr_in)) {
148 if (type != SOCK_RAW) {
149 error = CheckNetworkBindACL(0, type, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, ((struct sockaddr_in *) addr)->sin_port);
150 } else {
151 error = CheckNetworkBindACL(0, SOCK_RAW, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, htons(sock->sk->sk_protocol));
152 }
153 }
154 break;
155 }
156 }
157 return error;
158 }
159
160 static inline int CheckSocketAcceptPermission(struct socket *sock, struct sockaddr *addr)
161 {
162 int error = 0;
163 int addr_len;
164 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
165 switch (sock->sk->sk_family) {
166 case PF_INET:
167 case PF_INET6:
168 if (sock->ops->getname(sock, addr, &addr_len, 2) == 0) {
169 switch (addr->sa_family) {
170 case AF_INET6:
171 error = CheckNetworkAcceptACL(1, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, ((struct sockaddr_in6 *) addr)->sin6_port);
172 break;
173 case AF_INET:
174 error = CheckNetworkAcceptACL(0, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, ((struct sockaddr_in *) addr)->sin_port);
175 break;
176 }
177 } else {
178 error = -EPERM;
179 }
180 }
181 return error;
182 }
183
184 static inline int CheckSocketSendMsgPermission(struct socket *sock, struct sockaddr *addr, int addr_len)
185 {
186 int error = 0;
187 const int type = sock->type;
188 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
189 if (addr && (type == SOCK_DGRAM || type == SOCK_RAW)) {
190 switch (addr->sa_family) {
191 case AF_INET6:
192 if (addr_len >= SIN6_LEN_RFC2133) {
193 error = CheckNetworkSendMsgACL(1, type, ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, type == SOCK_DGRAM ? ((struct sockaddr_in6 *) addr)->sin6_port : htons(sock->sk->sk_protocol));
194 }
195 break;
196 case AF_INET:
197 if (addr_len >= sizeof(struct sockaddr_in)) {
198 error = CheckNetworkSendMsgACL(0, type, (u8 *) &((struct sockaddr_in *) addr)->sin_addr, type == SOCK_DGRAM ? ((struct sockaddr_in *) addr)->sin_port : htons(sock->sk->sk_protocol));
199 }
200 break;
201 }
202 }
203 return error;
204 }
205
206 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
207
208 static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
209 {
210 return skb->nh.iph;
211 }
212
213 static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
214 {
215 return skb->h.uh;
216 }
217
218 static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
219 {
220 return skb->nh.ipv6h;
221 }
222
223 #endif
224
225 static inline int CheckSocketRecvDatagramPermission(struct sock *sk, struct sk_buff *skb, const unsigned int flags)
226 {
227 int error = 0;
228 const unsigned int type = sk->sk_type;
229 struct in6_addr sin6;
230 struct in_addr sin;
231 u16 port;
232
233 if (!skb) return 0;
234
235 if (in_interrupt()) return 0;
236
237 if (segment_eq(get_fs(), KERNEL_DS)) return 0;
238
239 if (type != SOCK_DGRAM && type != SOCK_RAW) return 0;
240
241 switch (sk->sk_family) {
242 case PF_INET6:
243 if (type == SOCK_DGRAM) { /* UDP IPv6 */
244 if (skb->protocol == htons(ETH_P_IP)) {
245 ipv6_addr_set(&sin6, 0, 0, htonl(0xffff), ip_hdr(skb)->saddr);
246 } else {
247 ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
248 }
249 port = udp_hdr(skb)->source;
250 } else { /* RAW IPv6 */
251 ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
252 port = htons(sk->sk_protocol);
253 }
254 error = CheckNetworkRecvMsgACL(1, type, (u8 *) &sin6, port);
255 break;
256 case PF_INET:
257 if (type == SOCK_DGRAM) { /* UDP IPv4 */
258 sin.s_addr = ip_hdr(skb)->saddr;
259 port = udp_hdr(skb)->source;
260 } else { /* RAW IPv4 */
261 sin.s_addr = ip_hdr(skb)->saddr;
262 port = htons(sk->sk_protocol);
263 }
264 error = CheckNetworkRecvMsgACL(0, type, (u8 *) &sin, port);
265 break;
266 }
267 if (error) {
268 /*
269 * Remove from queue if MSG_PEEK is used so that
270 * the head message from unwanted source in receive queue will not
271 * prevent the caller from picking up next message from wanted source
272 * when the caller is using MSG_PEEK flag for picking up.
273 */
274 if (flags & MSG_PEEK) {
275 unsigned long cpu_flags;
276 spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
277 if (skb == skb_peek(&sk->sk_receive_queue)) {
278 __skb_unlink(skb, &sk->sk_receive_queue);
279 atomic_dec(&skb->users);
280 }
281 spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
282 }
283 /* Drop reference count. */
284 skb_free_datagram(sk, skb);
285 /* Hope less harmful than -EPERM. */
286 error = -EAGAIN;
287 }
288 return error;
289 }
290
291 #else
292
293 static inline int CheckSocketCreatePermission(int family, int type, int protocol) { return 0; }
294 static inline int CheckSocketListenPermission(struct socket *sock) { return 0; }
295 static inline int CheckSocketConnectPermission(struct socket *sock, struct sockaddr *addr, int addr_len) { return 0; }
296 static inline int CheckSocketBindPermission(struct socket *sock, struct sockaddr *addr, int addr_len) { return 0; }
297 static inline int CheckSocketAcceptPermission(struct socket *sock, struct sockaddr *addr) { return 0; }
298 static inline int CheckSocketSendMsgPermission(struct socket *sock, struct sockaddr *addr, int addr_len) { return 0; }
299 static inline int CheckSocketRecvDatagramPermission(struct sock *sk, struct sk_buff *skb, const unsigned int flags) { return 0; }
300
301 #endif
302
303 /***** TOMOYO Linux end. *****/
304 #endif

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26