Fix compilation error when building without INET6. Fix a number of minor
[dragonfly.git] / sys / kern / kern_jail.c
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  */
10 /*-
11  * Copyright (c) 2006 Victor Balada Diaz <victor@bsdes.net>
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36
37 /*
38  * $FreeBSD: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $
39  * $DragonFly: src/sys/kern/kern_jail.c,v 1.15 2006/12/31 19:36:54 dillon Exp $
40  */
41
42
43 #include <sys/param.h>
44 #include <sys/types.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/errno.h>
48 #include <sys/sysproto.h>
49 #include <sys/malloc.h>
50 #include <sys/nlookup.h>
51 #include <sys/namecache.h>
52 #include <sys/proc.h>
53 #include <sys/jail.h>
54 #include <sys/socket.h>
55 #include <sys/sysctl.h>
56 #include <sys/kern_syscall.h>
57 #include <net/if.h>
58 #include <netinet/in.h>
59 #include <netinet6/in6_var.h>
60
61 static struct prison    *prison_find(int);
62
63 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
64
65 SYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0,
66     "Jail rules");
67
68 int     jail_set_hostname_allowed = 1;
69 SYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
70     &jail_set_hostname_allowed, 0,
71     "Processes in jail can set their hostnames");
72
73 int     jail_socket_unixiproute_only = 1;
74 SYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
75     &jail_socket_unixiproute_only, 0,
76     "Processes in jail are limited to creating UNIX/IPv[46]/route sockets only");
77
78 int     jail_sysvipc_allowed = 0;
79 SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
80     &jail_sysvipc_allowed, 0,
81     "Processes in jail can use System V IPC primitives");
82
83 int    jail_chflags_allowed = 0;
84 SYSCTL_INT(_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW,
85     &jail_chflags_allowed, 0,
86     "Process in jail can set chflags(1)");
87
88 int     lastprid = 0;
89 int     prisoncount = 0;
90
91 LIST_HEAD(prisonlist, prison);
92 struct  prisonlist allprison = LIST_HEAD_INITIALIZER(&allprison);
93
94 static int
95 kern_jail_attach(int jid)
96 {
97         struct proc *p = curthread->td_proc;
98         struct prison *pr;
99         int error;
100
101         pr = prison_find(jid);
102         if (pr == NULL)
103                 return(EINVAL);
104
105         error = kern_chroot(&pr->pr_root);
106         if (error)
107                 return(error);
108
109         prison_hold(pr);
110         cratom(&p->p_ucred);
111         p->p_ucred->cr_prison = pr;
112         p->p_flag |= P_JAILED;
113
114         return(0);
115 }
116
117 /*
118  * jail()
119  *
120  * jail_args(syscallarg(struct jail *) jail)
121  */
122 int
123 sys_jail(struct jail_args *uap)
124 {
125         struct prison *pr, *tpr;
126         struct jail j;
127         struct jail_v0 jv0;
128         struct thread *td = curthread;
129         int error, tryprid, i;
130         uint32_t jversion;
131         struct nlookupdata nd;
132         /* Multiip */
133         struct sockaddr_storage *uips; /* Userland ips */
134         struct sockaddr_in ip4addr;
135         struct jail_ip_storage *jip;
136         /* Multiip */
137
138         error = suser(td);
139         if (error)
140                 return(error);
141         error = copyin(uap->jail, &jversion, sizeof jversion);
142         if (error)
143                 return(error);
144         pr = kmalloc(sizeof *pr , M_PRISON, M_WAITOK | M_ZERO);
145         SLIST_INIT(&pr->pr_ips);
146
147         switch (jversion) {
148         case 0:
149                 error = copyin(uap->jail, &jv0, sizeof(struct jail_v0));
150                 if (error)
151                         goto bail;
152                 jip = kmalloc(sizeof(*jip),  M_PRISON, M_WAITOK | M_ZERO);
153                 ip4addr.sin_family = AF_INET;
154                 ip4addr.sin_addr.s_addr = htonl(jv0.ip_number);
155                 memcpy(&jip->ip, &ip4addr, sizeof(ip4addr));
156                 SLIST_INSERT_HEAD(&pr->pr_ips, jip, entries);
157                 break;
158         case 1:
159                 error = copyin(uap->jail, &j, sizeof(j));
160                 if (error)
161                         goto bail;
162                 uips = kmalloc((sizeof(*uips) * j.n_ips), M_PRISON,
163                                 M_WAITOK | M_ZERO);
164                 error = copyin(j.ips, uips, (sizeof(*uips) * j.n_ips));
165                 if (error) {
166                         kfree(uips, M_PRISON);
167                         goto bail;
168                 }
169                 for (i = 0; i < j.n_ips; i++) {
170                         jip = kmalloc(sizeof(*jip),  M_PRISON,
171                                       M_WAITOK | M_ZERO);
172                         memcpy(&jip->ip, &uips[i], sizeof(*uips));
173                         SLIST_INSERT_HEAD(&pr->pr_ips, jip, entries);
174                 }
175                 kfree(uips, M_PRISON);
176                 break;
177         default:
178                 error = EINVAL;
179                 goto bail;
180         }
181
182         error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
183         if (error)
184                 goto bail;
185         error = nlookup_init(&nd, j.path, UIO_USERSPACE, NLC_FOLLOW);
186         if (error)
187                 goto nlookup_init_clean;
188         error = nlookup(&nd);
189         if (error)
190                 goto nlookup_init_clean;
191         cache_copy(&nd.nl_nch, &pr->pr_root);
192
193         varsymset_init(&pr->pr_varsymset, NULL);
194
195         tryprid = lastprid + 1;
196         if (tryprid == JAIL_MAX)
197                 tryprid = 1;
198 next:
199         LIST_FOREACH(tpr, &allprison, pr_list) {
200                 if (tpr->pr_id != tryprid)
201                         continue;
202                 tryprid++;
203                 if (tryprid == JAIL_MAX) {
204                         error = ERANGE;
205                         goto varsym_clean;
206                 }
207                 goto next;
208         }
209         pr->pr_id = lastprid = tryprid;
210         LIST_INSERT_HEAD(&allprison, pr, pr_list);
211         prisoncount++;
212
213         error = kern_jail_attach(pr->pr_id);
214         if (error)
215                 goto jail_attach_clean;
216
217         nlookup_done(&nd);
218         return (0);
219
220 jail_attach_clean:
221         LIST_REMOVE(pr, pr_list);
222 varsym_clean:
223         varsymset_clean(&pr->pr_varsymset);
224 nlookup_init_clean:
225         nlookup_done(&nd);
226 bail:
227         /* Delete all ips */
228         while (!SLIST_EMPTY(&pr->pr_ips)) {
229                 jip = SLIST_FIRST(&pr->pr_ips);
230                 SLIST_REMOVE_HEAD(&pr->pr_ips, entries);
231                 FREE(jip, M_PRISON);
232         }
233         FREE(pr, M_PRISON);
234         return(error);
235 }
236
237 /*
238  * int jail_attach(int jid);
239  */
240 int
241 sys_jail_attach(struct jail_attach_args *uap)
242 {
243         struct thread *td = curthread;
244         int error;
245
246         error = suser(td);
247         if (error)
248                 return(error);
249
250         return(kern_jail_attach(uap->jid));
251 }
252
253 /* 
254  * Changes INADDR_LOOPBACK for a valid jail address.
255  * ip is in network byte order.
256  * Returns 1 if the ip is among jail valid ips.
257  * Returns 0 if is not among jail valid ips or
258  * if couldn't replace INADDR_LOOPBACK for a valid
259  * IP.
260  */
261 int
262 prison_replace_wildcards(struct thread *td, struct sockaddr *ip)
263 {
264         struct sockaddr_in *ip4 = (struct sockaddr_in *)ip;
265         struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip;
266         struct prison *pr;
267
268         if (td->td_proc == NULL)
269                 return (1);
270         if ((pr = td->td_proc->p_ucred->cr_prison) == NULL)
271                 return (1);
272
273         if ((ip->sa_family == AF_INET &&
274             ip4->sin_addr.s_addr == htonl(INADDR_ANY)) ||
275             (ip->sa_family == AF_INET6 &&
276             IN6_IS_ADDR_UNSPECIFIED(&ip6->sin6_addr)))
277                 return (1);
278         if ((ip->sa_family == AF_INET &&
279             ip4->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) ||
280             (ip->sa_family == AF_INET6 &&
281             IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr))) {
282                 if (!prison_get_local(pr, ip) && !prison_get_nonlocal(pr, ip))
283                         return(0);
284                 else
285                         return(1);
286         }
287         if (jailed_ip(pr, ip))
288                 return(1);
289         return(0);
290 }
291
292 int
293 prison_remote_ip(struct thread *td, struct sockaddr *ip)
294 {
295         struct sockaddr_in *ip4 = (struct sockaddr_in *)ip;
296         struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)ip;
297         struct prison *pr;
298
299         if (td == NULL || td->td_proc == NULL)
300                 return(1);
301         if ((pr = td->td_proc->p_ucred->cr_prison) == NULL)
302                 return(1);
303         if ((ip->sa_family == AF_INET &&
304             ip4->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) ||
305             (ip->sa_family == AF_INET6 &&
306             IN6_IS_ADDR_LOOPBACK(&ip6->sin6_addr))) {
307                 if (!prison_get_local(pr, ip) && !prison_get_nonlocal(pr, ip))
308                         return(0);
309                 else
310                         return(1);
311         }
312         return(1);
313 }
314
315 /*
316  * Prison get non loopback ip:
317  * Put on *ip the first IP address that is not a loopback address.
318  * af is the address family of the ip we want (AF_INET|AF_INET6).
319  * ip is in network by order and we don't touch it unless we find a valid ip.
320  * Return 1 if we've found a non loopback ip, else return 0.
321  */
322 int
323 prison_get_nonlocal(struct prison *pr, struct sockaddr *ip)
324 {
325         struct jail_ip_storage *jis;
326         struct sockaddr_in *jip4, *ip4;
327         struct sockaddr_in6 *jip6, *ip6;
328
329         ip4 = (struct sockaddr_in *)ip;
330         ip6 = (struct sockaddr_in6 *)ip;
331         /* Check if it is cached */
332         switch(ip->sa_family) {
333                 case AF_INET:
334                         /* -1 Means that we don't have any address */
335                         if (pr->nonlocal_ip4 == (struct sockaddr_storage *)-1)
336                                 return(0);
337                         if (pr->nonlocal_ip4 != NULL) {
338                                 jip4 = (struct sockaddr_in *) pr->nonlocal_ip4;
339                                 ip4->sin_addr.s_addr = jip4->sin_addr.s_addr;
340                         }
341                 break;
342                 case AF_INET6:
343                         /* -1 Means that we don't have any address */
344                         if (pr->nonlocal_ip6 == (struct sockaddr_storage *)-1)
345                                 return(0);
346                         if (pr->nonlocal_ip6 != NULL) {
347                                 jip6 = (struct sockaddr_in6 *) pr->nonlocal_ip6;
348                                 ip6->sin6_addr = jip6->sin6_addr;
349                         }
350                 break;
351         };
352         SLIST_FOREACH(jis, &pr->pr_ips, entries) {
353                 switch (ip->sa_family) {
354                 case AF_INET:
355                         jip4 = (struct sockaddr_in *) &jis->ip;
356                         if (jip4->sin_family == AF_INET &&
357     ((ntohl(jip4->sin_addr.s_addr) >> IN_CLASSA_NSHIFT) != IN_LOOPBACKNET)) {
358                                 pr->nonlocal_ip4 = &jis->ip;
359                                 ip4->sin_addr.s_addr = jip4->sin_addr.s_addr;
360                                 return(1);
361                         }
362                         break;
363                 case AF_INET6:
364                         jip6 = (struct sockaddr_in6 *) &jis->ip;
365                         if ( jip6->sin6_family == AF_INET6 &&
366                              !IN6_IS_ADDR_LOOPBACK(&jip6->sin6_addr)) {
367                                 pr->nonlocal_ip6 = &jis->ip;
368                                 ip6->sin6_addr = jip6->sin6_addr;
369                                 return(1);
370                         }
371                         break;
372                 }
373         }
374         if (ip->sa_family == AF_INET)
375                 pr->nonlocal_ip4 = (struct sockaddr_storage *)-1;
376         else
377                 pr->nonlocal_ip6 = (struct sockaddr_storage *)-1;
378         return(0);
379 }
380
381 /*
382  * Prison get loopback ip.
383  * Put on *ip the first loopback IP address.
384  * af is the address family of the ip we want (AF_INET|PF_INET).
385  * *ip is in network by order and we don't touch it unless we find a valid ip.
386  * return 1 if we've found a loopback ip, else return 0.
387  */
388 int
389 prison_get_local(struct prison *pr, struct sockaddr *ip)
390 {
391         struct jail_ip_storage *jis;
392         struct sockaddr_in *jip4, *ip4;
393         struct sockaddr_in6 *jip6, *ip6;
394
395         ip4 = (struct sockaddr_in *)ip;
396         ip6 = (struct sockaddr_in6 *)ip;
397         /* Check if it is cached */
398         switch(ip->sa_family) {
399                 case AF_INET:
400                         /* -1 Means that we don't have any address */
401                         if (pr->local_ip4 == (struct sockaddr_storage *)-1)
402                                 return(0);
403                         if (pr->local_ip4 != NULL) {
404                                 jip4 = (struct sockaddr_in *) pr->local_ip4;
405                                 ip4->sin_addr.s_addr = jip4->sin_addr.s_addr;
406                         }
407                 break;
408                 case AF_INET6:
409                         /* -1 Means that we don't have any address */
410                         if (pr->local_ip6 == (struct sockaddr_storage *)-1)
411                                 return(0);
412                         if (pr->local_ip6 != NULL) {
413                                 jip6 = (struct sockaddr_in6 *) pr->local_ip6;
414                                 ip6->sin6_addr = jip6->sin6_addr;
415                         }
416                 break;
417         };
418         SLIST_FOREACH(jis, &pr->pr_ips, entries) {
419                 switch(ip->sa_family) {
420                 case AF_INET:
421                         jip4 = (struct sockaddr_in *) &jis->ip;
422                         if (jip4->sin_family == AF_INET &&
423                             ((ntohl(jip4->sin_addr.s_addr) >> IN_CLASSA_NSHIFT)
424                             == IN_LOOPBACKNET)) {
425                                 pr->local_ip4 = &jis->ip;
426                                 ip4->sin_addr.s_addr = jip4->sin_addr.s_addr;
427                                 return(1);
428                         }
429                         break;
430                 case AF_INET6:
431                         jip6 = (struct sockaddr_in6 *) &jis->ip;
432                         if (jip6->sin6_family == AF_INET6 &&
433                              IN6_IS_ADDR_LOOPBACK(&jip6->sin6_addr)) {
434                                 pr->local_ip6 = &jis->ip;
435                                 ip6->sin6_addr = jip6->sin6_addr;
436                                 return(1);
437                         }
438                         break;
439                 }
440         }
441         if (ip->sa_family == AF_INET)
442                 pr->local_ip4 = (struct sockaddr_storage *)-1;
443         else
444                 pr->local_ip6 = (struct sockaddr_storage *)-1;
445         return(0);
446 }
447
448 /* Check if the IP is among ours, if it is return 1, else 0 */
449 int
450 jailed_ip(struct prison *pr, struct sockaddr *ip)
451 {
452         struct jail_ip_storage *jis;
453         struct sockaddr_in *jip4, *ip4;
454         struct sockaddr_in6 *jip6, *ip6;
455
456         if (pr == NULL)
457                 return(0);
458         ip4 = (struct sockaddr_in *)ip;
459         ip6 = (struct sockaddr_in6 *)ip;
460         SLIST_FOREACH(jis, &pr->pr_ips, entries) {
461                 switch (ip->sa_family) {
462                 case AF_INET:
463                         jip4 = (struct sockaddr_in *) &jis->ip;
464                         if (jip4->sin_family == AF_INET &&
465                             ip4->sin_addr.s_addr == jip4->sin_addr.s_addr)
466                                 return(1);
467                         break;
468                 case AF_INET6:
469                         jip6 = (struct sockaddr_in6 *) &jis->ip;
470                         if (jip6->sin6_family == AF_INET6 &&
471                             IN6_ARE_ADDR_EQUAL(&ip6->sin6_addr,
472                                                &jip6->sin6_addr))
473                                 return(1);
474                         break;
475                 }
476         }
477         /* Ip not in list */
478         return(0);
479 }
480
481 int
482 prison_if(struct ucred *cred, struct sockaddr *sa)
483 {
484         struct prison *pr;
485         struct sockaddr_in *sai = (struct sockaddr_in*) sa;
486
487         pr = cred->cr_prison;
488
489         if (((sai->sin_family != AF_INET) && (sai->sin_family != AF_INET6))
490             && jail_socket_unixiproute_only)
491                 return(1);
492         else if ((sai->sin_family != AF_INET) && (sai->sin_family != AF_INET6))
493                 return(0);
494         else if (jailed_ip(pr, sa))
495                 return(0);
496         return(1);
497 }
498
499 /*
500  * Returns a prison instance, or NULL on failure.
501  */
502 static struct prison *
503 prison_find(int prid)
504 {
505         struct prison *pr;
506
507         LIST_FOREACH(pr, &allprison, pr_list) {
508                 if (pr->pr_id == prid)
509                         break;
510         }
511         return(pr);
512 }
513
514 static int
515 sysctl_jail_list(SYSCTL_HANDLER_ARGS)
516 {
517         struct jail_ip_storage *jip;
518 #ifdef INET6
519         struct sockaddr_in6 *jsin6;
520 #endif
521         struct sockaddr_in *jsin;
522         struct proc *p;
523         struct prison *pr;
524         unsigned int jlssize, jlsused;
525         int count, error;
526         char *jls; /* Jail list */
527         char *oip; /* Output ip */
528         char *fullpath, *freepath;
529
530         jlsused = 0;
531         p = curthread->td_proc;
532
533         if (jailed(p->p_ucred))
534                 return (0);
535 retry:
536         count = prisoncount;
537
538         if (count == 0)
539                 return(0);
540
541         jlssize = (count * 1024);
542         jls = kmalloc(jlssize + 1, M_TEMP, M_WAITOK | M_ZERO);
543         if (count < prisoncount) {
544                 kfree(jls, M_TEMP);
545                 goto retry;
546         }
547         count = prisoncount;
548
549         LIST_FOREACH(pr, &allprison, pr_list) {
550                 error = cache_fullpath(p, &pr->pr_root, &fullpath, &freepath);
551                 if (error)
552                         continue;
553                 if (jlsused && jlsused < jlssize)
554                         jls[jlsused++] = '\n';
555                 count = ksnprintf(jls + jlsused, (jlssize - jlsused),
556                                  "%d %s %s", 
557                                  pr->pr_id, pr->pr_host, fullpath);
558                 kfree(freepath, M_TEMP);                
559                 if (count < 0)
560                         goto end;
561                 jlsused += count;
562
563                 /* Copy the IPS */
564                 SLIST_FOREACH(jip, &pr->pr_ips, entries) {
565                         jsin = (struct sockaddr_in *)&jip->ip;
566
567                         switch(jsin->sin_family) {
568                         case AF_INET:
569                                 oip = inet_ntoa(jsin->sin_addr);
570                                 break;
571 #ifdef INET6
572                         case AF_INET6:
573                                 jsin6 = (struct sockaddr_in6 *)&jip->ip;
574                                 oip = ip6_sprintf(&jsin6->sin6_addr);
575                                 break;
576 #endif
577                         default:
578                                 oip = "?family?";
579                                 break;
580                         }
581
582                         if ((jlssize - jlsused) < (strlen(oip) + 1)) {
583                                 error = ERANGE;
584                                 goto end;
585                         }
586                         count = ksnprintf(jls + jlsused, (jlssize - jlsused),
587                                           " %s", oip);
588                         if (count < 0)
589                                 goto end;
590                         jlsused += count;
591                 }
592         }
593
594         /* 
595          * The format is:
596          * pr_id <SPC> hostname1 <SPC> PATH1 <SPC> IP1 <SPC> IP2\npr_id...
597          */
598         error = SYSCTL_OUT(req, jls, jlsused);
599 end:
600         kfree(jls, M_TEMP);
601         return(error);
602 }
603
604 SYSCTL_OID(_jail, OID_AUTO, list, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0,
605            sysctl_jail_list, "A", "List of active jails");
606
607 void
608 prison_hold(struct prison *pr)
609 {
610         pr->pr_ref++;
611 }
612
613 void
614 prison_free(struct prison *pr)
615 {
616         struct jail_ip_storage *jls;
617         KKASSERT(pr->pr_ref >= 1);
618
619         if (--pr->pr_ref > 0)
620                 return;
621
622         /* Delete all ips */
623         while (!SLIST_EMPTY(&pr->pr_ips)) {
624                 jls = SLIST_FIRST(&pr->pr_ips);
625                 SLIST_REMOVE_HEAD(&pr->pr_ips, entries);
626                 FREE(jls, M_PRISON);
627         }
628         LIST_REMOVE(pr, pr_list);
629         prisoncount--;
630
631         if (pr->pr_linux != NULL)
632                 kfree(pr->pr_linux, M_PRISON);
633         varsymset_clean(&pr->pr_varsymset);
634         cache_drop(&pr->pr_root);
635         kfree(pr, M_PRISON);
636 }