1 /*- 2 * Copyright (c) 1999 Poul-Henning Kamp. 3 * Copyright (c) 2008 Bjoern A. Zeeb. 4 * Copyright (c) 2009 James Gritton. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include "opt_ddb.h" 33 #include "opt_inet.h" 34 #include "opt_inet6.h" 35 36 #include <sys/param.h> 37 #include <sys/types.h> 38 #include <sys/kernel.h> 39 #include <sys/systm.h> 40 #include <sys/errno.h> 41 #include <sys/sysproto.h> 42 #include <sys/malloc.h> 43 #include <sys/osd.h> 44 #include <sys/priv.h> 45 #include <sys/proc.h> 46 #include <sys/taskqueue.h> 47 #include <sys/fcntl.h> 48 #include <sys/jail.h> 49 #include <sys/lock.h> 50 #include <sys/mutex.h> 51 #include <sys/racct.h> 52 #include <sys/refcount.h> 53 #include <sys/sx.h> 54 #include <sys/sysent.h> 55 #include <sys/namei.h> 56 #include <sys/mount.h> 57 #include <sys/queue.h> 58 #include <sys/socket.h> 59 #include <sys/syscallsubr.h> 60 #include <sys/sysctl.h> 61 #include <sys/vnode.h> 62 63 #include <net/if.h> 64 #include <net/vnet.h> 65 66 #include <netinet/in.h> 67 68 int 69 prison_qcmp_v6(const void *ip1, const void *ip2) 70 { 71 const struct in6_addr *ia6a, *ia6b; 72 int i, rc; 73 74 ia6a = (const struct in6_addr *)ip1; 75 ia6b = (const struct in6_addr *)ip2; 76 77 rc = 0; 78 for (i = 0; rc == 0 && i < sizeof(struct in6_addr); i++) { 79 if (ia6a->s6_addr[i] > ia6b->s6_addr[i]) 80 rc = 1; 81 else if (ia6a->s6_addr[i] < ia6b->s6_addr[i]) 82 rc = -1; 83 } 84 return (rc); 85 } 86 87 int 88 prison_restrict_ip6(struct prison *pr, struct in6_addr *newip6) 89 { 90 int ii, ij, used; 91 struct prison *ppr; 92 93 ppr = pr->pr_parent; 94 if (!(pr->pr_flags & PR_IP6_USER)) { 95 /* This has no user settings, so just copy the parent's list. */ 96 if (pr->pr_ip6s < ppr->pr_ip6s) { 97 /* 98 * There's no room for the parent's list. Use the 99 * new list buffer, which is assumed to be big enough 100 * (if it was passed). If there's no buffer, try to 101 * allocate one. 102 */ 103 used = 1; 104 if (newip6 == NULL) { 105 newip6 = malloc(ppr->pr_ip6s * sizeof(*newip6), 106 M_PRISON, M_NOWAIT); 107 if (newip6 != NULL) 108 used = 0; 109 } 110 if (newip6 != NULL) { 111 bcopy(ppr->pr_ip6, newip6, 112 ppr->pr_ip6s * sizeof(*newip6)); 113 free(pr->pr_ip6, M_PRISON); 114 pr->pr_ip6 = newip6; 115 pr->pr_ip6s = ppr->pr_ip6s; 116 } 117 return (used); 118 } 119 pr->pr_ip6s = ppr->pr_ip6s; 120 if (pr->pr_ip6s > 0) 121 bcopy(ppr->pr_ip6, pr->pr_ip6, 122 pr->pr_ip6s * sizeof(*newip6)); 123 else if (pr->pr_ip6 != NULL) { 124 free(pr->pr_ip6, M_PRISON); 125 pr->pr_ip6 = NULL; 126 } 127 } else if (pr->pr_ip6s > 0) { 128 /* Remove addresses that aren't in the parent. */ 129 for (ij = 0; ij < ppr->pr_ip6s; ij++) 130 if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], 131 &ppr->pr_ip6[ij])) 132 break; 133 if (ij < ppr->pr_ip6s) 134 ii = 1; 135 else { 136 bcopy(pr->pr_ip6 + 1, pr->pr_ip6, 137 --pr->pr_ip6s * sizeof(*pr->pr_ip6)); 138 ii = 0; 139 } 140 for (ij = 1; ii < pr->pr_ip6s; ) { 141 if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[ii], 142 &ppr->pr_ip6[0])) { 143 ii++; 144 continue; 145 } 146 switch (ij >= ppr->pr_ip6s ? -1 : 147 prison_qcmp_v6(&pr->pr_ip6[ii], &ppr->pr_ip6[ij])) { 148 case -1: 149 bcopy(pr->pr_ip6 + ii + 1, pr->pr_ip6 + ii, 150 (--pr->pr_ip6s - ii) * sizeof(*pr->pr_ip6)); 151 break; 152 case 0: 153 ii++; 154 ij++; 155 break; 156 case 1: 157 ij++; 158 break; 159 } 160 } 161 if (pr->pr_ip6s == 0) { 162 free(pr->pr_ip6, M_PRISON); 163 pr->pr_ip6 = NULL; 164 } 165 } 166 return 0; 167 } 168 169 /* 170 * Pass back primary IPv6 address for this jail. 171 * 172 * If not restricted return success but do not alter the address. Caller has 173 * to make sure to initialize it correctly (e.g. IN6ADDR_ANY_INIT). 174 * 175 * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6. 176 */ 177 int 178 prison_get_ip6(struct ucred *cred, struct in6_addr *ia6) 179 { 180 struct prison *pr; 181 182 KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); 183 KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__)); 184 185 pr = cred->cr_prison; 186 if (!(pr->pr_flags & PR_IP6)) 187 return (0); 188 mtx_lock(&pr->pr_mtx); 189 if (!(pr->pr_flags & PR_IP6)) { 190 mtx_unlock(&pr->pr_mtx); 191 return (0); 192 } 193 if (pr->pr_ip6 == NULL) { 194 mtx_unlock(&pr->pr_mtx); 195 return (EAFNOSUPPORT); 196 } 197 198 bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); 199 mtx_unlock(&pr->pr_mtx); 200 return (0); 201 } 202 203 /* 204 * Return 1 if we should do proper source address selection or are not jailed. 205 * We will return 0 if we should bypass source address selection in favour 206 * of the primary jail IPv6 address. Only in this case *ia will be updated and 207 * returned in NBO. 208 * Return EAFNOSUPPORT, in case this jail does not allow IPv6. 209 */ 210 int 211 prison_saddrsel_ip6(struct ucred *cred, struct in6_addr *ia6) 212 { 213 struct prison *pr; 214 struct in6_addr lia6; 215 int error; 216 217 KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); 218 KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__)); 219 220 if (!jailed(cred)) 221 return (1); 222 223 pr = cred->cr_prison; 224 if (pr->pr_flags & PR_IP6_SADDRSEL) 225 return (1); 226 227 lia6 = in6addr_any; 228 error = prison_get_ip6(cred, &lia6); 229 if (error) 230 return (error); 231 if (IN6_IS_ADDR_UNSPECIFIED(&lia6)) 232 return (1); 233 234 bcopy(&lia6, ia6, sizeof(struct in6_addr)); 235 return (0); 236 } 237 238 /* 239 * Return true if pr1 and pr2 have the same IPv6 address restrictions. 240 */ 241 int 242 prison_equal_ip6(struct prison *pr1, struct prison *pr2) 243 { 244 245 if (pr1 == pr2) 246 return (1); 247 248 while (pr1 != &prison0 && 249 #ifdef VIMAGE 250 !(pr1->pr_flags & PR_VNET) && 251 #endif 252 !(pr1->pr_flags & PR_IP6_USER)) 253 pr1 = pr1->pr_parent; 254 while (pr2 != &prison0 && 255 #ifdef VIMAGE 256 !(pr2->pr_flags & PR_VNET) && 257 #endif 258 !(pr2->pr_flags & PR_IP6_USER)) 259 pr2 = pr2->pr_parent; 260 return (pr1 == pr2); 261 } 262 263 /* 264 * Make sure our (source) address is set to something meaningful to this jail. 265 * 266 * v6only should be set based on (inp->inp_flags & IN6P_IPV6_V6ONLY != 0) 267 * when needed while binding. 268 * 269 * Returns 0 if jail doesn't restrict IPv6 or if address belongs to jail, 270 * EADDRNOTAVAIL if the address doesn't belong, or EAFNOSUPPORT if the jail 271 * doesn't allow IPv6. 272 */ 273 int 274 prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only) 275 { 276 struct prison *pr; 277 int error; 278 279 KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); 280 KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__)); 281 282 pr = cred->cr_prison; 283 if (!(pr->pr_flags & PR_IP6)) 284 return (0); 285 mtx_lock(&pr->pr_mtx); 286 if (!(pr->pr_flags & PR_IP6)) { 287 mtx_unlock(&pr->pr_mtx); 288 return (0); 289 } 290 if (pr->pr_ip6 == NULL) { 291 mtx_unlock(&pr->pr_mtx); 292 return (EAFNOSUPPORT); 293 } 294 295 if (IN6_IS_ADDR_UNSPECIFIED(ia6)) { 296 /* 297 * In case there is only 1 IPv6 address, and v6only is true, 298 * then bind directly. 299 */ 300 if (v6only != 0 && pr->pr_ip6s == 1) 301 bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); 302 mtx_unlock(&pr->pr_mtx); 303 return (0); 304 } 305 306 error = prison_check_ip6_locked(pr, ia6); 307 if (error == EADDRNOTAVAIL && IN6_IS_ADDR_LOOPBACK(ia6)) { 308 bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); 309 error = 0; 310 } 311 312 mtx_unlock(&pr->pr_mtx); 313 return (error); 314 } 315 316 /* 317 * Rewrite destination address in case we will connect to loopback address. 318 * 319 * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6. 320 */ 321 int 322 prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6) 323 { 324 struct prison *pr; 325 326 KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); 327 KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__)); 328 329 pr = cred->cr_prison; 330 if (!(pr->pr_flags & PR_IP6)) 331 return (0); 332 mtx_lock(&pr->pr_mtx); 333 if (!(pr->pr_flags & PR_IP6)) { 334 mtx_unlock(&pr->pr_mtx); 335 return (0); 336 } 337 if (pr->pr_ip6 == NULL) { 338 mtx_unlock(&pr->pr_mtx); 339 return (EAFNOSUPPORT); 340 } 341 342 if (IN6_IS_ADDR_LOOPBACK(ia6) && 343 prison_check_ip6_locked(pr, ia6) == EADDRNOTAVAIL) { 344 bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); 345 mtx_unlock(&pr->pr_mtx); 346 return (0); 347 } 348 349 /* 350 * Return success because nothing had to be changed. 351 */ 352 mtx_unlock(&pr->pr_mtx); 353 return (0); 354 } 355 356 /* 357 * Check if given address belongs to the jail referenced by cred/prison. 358 * 359 * Returns 0 if address belongs to jail, 360 * EADDRNOTAVAIL if the address doesn't belong to the jail. 361 */ 362 int 363 prison_check_ip6_locked(const struct prison *pr, const struct in6_addr *ia6) 364 { 365 int i, a, z, d; 366 367 /* 368 * Check the primary IP. 369 */ 370 if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], ia6)) 371 return (0); 372 373 /* 374 * All the other IPs are sorted so we can do a binary search. 375 */ 376 a = 0; 377 z = pr->pr_ip6s - 2; 378 while (a <= z) { 379 i = (a + z) / 2; 380 d = prison_qcmp_v6(&pr->pr_ip6[i+1], ia6); 381 if (d > 0) 382 z = i - 1; 383 else if (d < 0) 384 a = i + 1; 385 else 386 return (0); 387 } 388 389 return (EADDRNOTAVAIL); 390 } 391 392 int 393 prison_check_ip6(const struct ucred *cred, const struct in6_addr *ia6) 394 { 395 struct prison *pr; 396 int error; 397 398 KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); 399 KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__)); 400 401 pr = cred->cr_prison; 402 if (!(pr->pr_flags & PR_IP6)) 403 return (0); 404 mtx_lock(&pr->pr_mtx); 405 if (!(pr->pr_flags & PR_IP6)) { 406 mtx_unlock(&pr->pr_mtx); 407 return (0); 408 } 409 if (pr->pr_ip6 == NULL) { 410 mtx_unlock(&pr->pr_mtx); 411 return (EAFNOSUPPORT); 412 } 413 414 error = prison_check_ip6_locked(pr, ia6); 415 mtx_unlock(&pr->pr_mtx); 416 return (error); 417 } 418