View | Details | Raw Unified | Return to bug 48471 | Differences between
and this patch

Collapse All | Expand All

(-)kern/kern_jail.c (-58 / +100 lines)
Lines 557-564 Link Here
557
	void *op;
557
	void *op;
558
#endif
558
#endif
559
	unsigned long hid;
559
	unsigned long hid;
560
	size_t namelen, onamelen;
560
	size_t namelen, onamelen, pnamelen;
561
	int created, cuflags, descend, enforce, error, errmsg_len, errmsg_pos;
561
	int born, created, cuflags, descend, enforce;
562
	int error, errmsg_len, errmsg_pos;
562
	int gotchildmax, gotenforce, gothid, gotrsnum, gotslevel;
563
	int gotchildmax, gotenforce, gothid, gotrsnum, gotslevel;
563
	int fi, jid, jsys, len, level;
564
	int fi, jid, jsys, len, level;
564
	int childmax, osreldt, rsnum, slevel;
565
	int childmax, osreldt, rsnum, slevel;
Lines 581-587 Link Here
581
		error = priv_check(td, PRIV_JAIL_ATTACH);
582
		error = priv_check(td, PRIV_JAIL_ATTACH);
582
	if (error)
583
	if (error)
583
		return (error);
584
		return (error);
584
	mypr = ppr = td->td_ucred->cr_prison;
585
	mypr = td->td_ucred->cr_prison;
585
	if ((flags & JAIL_CREATE) && mypr->pr_childmax == 0)
586
	if ((flags & JAIL_CREATE) && mypr->pr_childmax == 0)
586
		return (EPERM);
587
		return (EPERM);
587
	if (flags & ~JAIL_SET_MASK)
588
	if (flags & ~JAIL_SET_MASK)
Lines 608-613 Link Here
608
#endif
609
#endif
609
	g_path = NULL;
610
	g_path = NULL;
610
611
612
	cuflags = flags & (JAIL_CREATE | JAIL_UPDATE);
613
	if (!cuflags) {
614
		error = EINVAL;
615
		vfs_opterror(opts, "no valid operation (create or update)");
616
		goto done_errmsg;
617
	}
618
611
	error = vfs_copyopt(opts, "jid", &jid, sizeof(jid));
619
	error = vfs_copyopt(opts, "jid", &jid, sizeof(jid));
612
	if (error == ENOENT)
620
	if (error == ENOENT)
613
		jid = 0;
621
		jid = 0;
Lines 1013-1048 Link Here
1013
	}
1021
	}
1014
1022
1015
	/*
1023
	/*
1016
	 * Grab the allprison lock before letting modules check their
1024
	 * Find the specified jail, or at least its parent.
1017
	 * parameters.  Once we have it, do not let go so we'll have a
1018
	 * consistent view of the OSD list.
1019
	 */
1020
	sx_xlock(&allprison_lock);
1021
	error = osd_jail_call(NULL, PR_METHOD_CHECK, opts);
1022
	if (error)
1023
		goto done_unlock_list;
1024
1025
	/* By now, all parameters should have been noted. */
1026
	TAILQ_FOREACH(opt, opts, link) {
1027
		if (!opt->seen && strcmp(opt->name, "errmsg")) {
1028
			error = EINVAL;
1029
			vfs_opterror(opts, "unknown parameter: %s", opt->name);
1030
			goto done_unlock_list;
1031
		}
1032
	}
1033
1034
	/*
1035
	 * See if we are creating a new record or updating an existing one.
1036
	 * This abuses the file error codes ENOENT and EEXIST.
1025
	 * This abuses the file error codes ENOENT and EEXIST.
1037
	 */
1026
	 */
1038
	cuflags = flags & (JAIL_CREATE | JAIL_UPDATE);
1039
	if (!cuflags) {
1040
		error = EINVAL;
1041
		vfs_opterror(opts, "no valid operation (create or update)");
1042
		goto done_unlock_list;
1043
	}
1044
	pr = NULL;
1027
	pr = NULL;
1045
	namelc = NULL;
1028
	ppr = mypr;
1046
	if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) {
1029
	if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) {
1047
		namelc = strrchr(name, '.');
1030
		namelc = strrchr(name, '.');
1048
		jid = strtoul(namelc != NULL ? namelc + 1 : name, &p, 10);
1031
		jid = strtoul(namelc != NULL ? namelc + 1 : name, &p, 10);
Lines 1049-1054 Link Here
1049
		if (*p != '\0')
1032
		if (*p != '\0')
1050
			jid = 0;
1033
			jid = 0;
1051
	}
1034
	}
1035
	sx_xlock(&allprison_lock);
1052
	if (jid != 0) {
1036
	if (jid != 0) {
1053
		/*
1037
		/*
1054
		 * See if a requested jid already exists.  There is an
1038
		 * See if a requested jid already exists.  There is an
Lines 1114-1119 Link Here
1114
	 * and updates keyed by the name itself (where the name must exist
1098
	 * and updates keyed by the name itself (where the name must exist
1115
	 * because that is the jail being updated).
1099
	 * because that is the jail being updated).
1116
	 */
1100
	 */
1101
	namelc = NULL;
1117
	if (name != NULL) {
1102
	if (name != NULL) {
1118
		namelc = strrchr(name, '.');
1103
		namelc = strrchr(name, '.');
1119
		if (namelc == NULL)
1104
		if (namelc == NULL)
Lines 1124-1130 Link Here
1124
			 * parent and child names, and make sure the parent
1109
			 * parent and child names, and make sure the parent
1125
			 * exists or matches an already found jail.
1110
			 * exists or matches an already found jail.
1126
			 */
1111
			 */
1127
			*namelc = '\0';
1128
			if (pr != NULL) {
1112
			if (pr != NULL) {
1129
				if (strncmp(name, ppr->pr_name, namelc - name)
1113
				if (strncmp(name, ppr->pr_name, namelc - name)
1130
				    || ppr->pr_name[namelc - name] != '\0') {
1114
				    || ppr->pr_name[namelc - name] != '\0') {
Lines 1135-1140 Link Here
1135
					goto done_unlock_list;
1119
					goto done_unlock_list;
1136
				}
1120
				}
1137
			} else {
1121
			} else {
1122
				*namelc = '\0';
1138
				ppr = prison_find_name(mypr, name);
1123
				ppr = prison_find_name(mypr, name);
1139
				if (ppr == NULL) {
1124
				if (ppr == NULL) {
1140
					error = ENOENT;
1125
					error = ENOENT;
Lines 1143-1159 Link Here
1143
					goto done_unlock_list;
1128
					goto done_unlock_list;
1144
				}
1129
				}
1145
				mtx_unlock(&ppr->pr_mtx);
1130
				mtx_unlock(&ppr->pr_mtx);
1131
				*namelc = '.';
1146
			}
1132
			}
1147
			name = ++namelc;
1133
			namelc++;
1148
		}
1134
		}
1149
		if (name[0] != '\0') {
1135
		if (namelc[0] != '\0') {
1150
			namelen =
1136
			pnamelen =
1151
			    (ppr == &prison0) ? 0 : strlen(ppr->pr_name) + 1;
1137
			    (ppr == &prison0) ? 0 : strlen(ppr->pr_name) + 1;
1152
 name_again:
1138
 name_again:
1153
			deadpr = NULL;
1139
			deadpr = NULL;
1154
			FOREACH_PRISON_CHILD(ppr, tpr) {
1140
			FOREACH_PRISON_CHILD(ppr, tpr) {
1155
				if (tpr != pr && tpr->pr_ref > 0 &&
1141
				if (tpr != pr && tpr->pr_ref > 0 &&
1156
				    !strcmp(tpr->pr_name + namelen, name)) {
1142
				    !strcmp(tpr->pr_name + pnamelen, namelc)) {
1157
					if (pr == NULL &&
1143
					if (pr == NULL &&
1158
					    cuflags != JAIL_CREATE) {
1144
					    cuflags != JAIL_CREATE) {
1159
						mtx_lock(&tpr->pr_mtx);
1145
						mtx_lock(&tpr->pr_mtx);
Lines 1227-1236 Link Here
1227
			}
1213
			}
1228
		created = 1;
1214
		created = 1;
1229
		mtx_lock(&ppr->pr_mtx);
1215
		mtx_lock(&ppr->pr_mtx);
1230
		if (ppr->pr_ref == 0 || (ppr->pr_flags & PR_REMOVE)) {
1216
		if (ppr->pr_ref == 0) {
1231
			mtx_unlock(&ppr->pr_mtx);
1217
			mtx_unlock(&ppr->pr_mtx);
1232
			error = ENOENT;
1218
			error = ENOENT;
1233
			vfs_opterror(opts, "parent jail went away!");
1219
			vfs_opterror(opts, "jail \"%s\" not found",
1220
			    prison_name(mypr, ppr));
1234
			goto done_unlock_list;
1221
			goto done_unlock_list;
1235
		}
1222
		}
1236
		ppr->pr_ref++;
1223
		ppr->pr_ref++;
Lines 1284-1291 Link Here
1284
		pr->pr_id = jid;
1271
		pr->pr_id = jid;
1285
1272
1286
		/* Set some default values, and inherit some from the parent. */
1273
		/* Set some default values, and inherit some from the parent. */
1287
		if (name == NULL)
1274
		if (namelc == NULL)
1288
			name = "";
1275
			namelc = "";
1289
		if (path == NULL) {
1276
		if (path == NULL) {
1290
			path = "/";
1277
			path = "/";
1291
			root = mypr->pr_root;
1278
			root = mypr->pr_root;
Lines 1365-1371 Link Here
1365
		mtx_lock(&pr->pr_mtx);
1352
		mtx_lock(&pr->pr_mtx);
1366
		/*
1353
		/*
1367
		 * New prisons do not yet have a reference, because we do not
1354
		 * New prisons do not yet have a reference, because we do not
1368
		 * want other to see the incomplete prison once the
1355
		 * want others to see the incomplete prison once the
1369
		 * allprison_lock is downgraded.
1356
		 * allprison_lock is downgraded.
1370
		 */
1357
		 */
1371
	} else {
1358
	} else {
Lines 1579-1591 Link Here
1579
	}
1566
	}
1580
#endif
1567
#endif
1581
	onamelen = namelen = 0;
1568
	onamelen = namelen = 0;
1582
	if (name != NULL) {
1569
	if (namelc != NULL) {
1583
		/* Give a default name of the jid.  Also allow the name to be
1570
		/* Give a default name of the jid.  Also allow the name to be
1584
		 * explicitly the jid - but not any other number, and only in
1571
		 * explicitly the jid - but not any other number, and only in
1585
		 * normal form (no leading zero/etc).
1572
		 * normal form (no leading zero/etc).
1586
		 */
1573
		 */
1587
		if (name[0] == '\0')
1574
		if (namelc[0] == '\0')
1588
			snprintf(name = numbuf, sizeof(numbuf), "%d", jid);
1575
			snprintf(namelc = numbuf, sizeof(numbuf), "%d", jid);
1589
		else if ((strtoul(namelc, &p, 10) != jid ||
1576
		else if ((strtoul(namelc, &p, 10) != jid ||
1590
			  namelc[0] < '1' || namelc[0] > '9') && *p == '\0') {
1577
			  namelc[0] < '1' || namelc[0] > '9') && *p == '\0') {
1591
			error = EINVAL;
1578
			error = EINVAL;
Lines 1597-1605 Link Here
1597
		 * Make sure the name isn't too long for the prison or its
1584
		 * Make sure the name isn't too long for the prison or its
1598
		 * children.
1585
		 * children.
1599
		 */
1586
		 */
1600
		onamelen = strlen(pr->pr_name);
1587
		pnamelen = (ppr == &prison0) ? 0 : strlen(ppr->pr_name) + 1;
1601
		namelen = strlen(name);
1588
		onamelen = strlen(pr->pr_name + pnamelen);
1602
		if (strlen(ppr->pr_name) + namelen + 2 > sizeof(pr->pr_name)) {
1589
		namelen = strlen(namelc);
1590
		if (pnamelen + namelen + 1 > sizeof(pr->pr_name)) {
1603
			error = ENAMETOOLONG;
1591
			error = ENAMETOOLONG;
1604
			goto done_deref_locked;
1592
			goto done_deref_locked;
1605
		}
1593
		}
Lines 1616-1621 Link Here
1616
		goto done_deref_locked;
1604
		goto done_deref_locked;
1617
	}
1605
	}
1618
1606
1607
	/*
1608
	 * Let modules check their parameters.  This requires unlocking and
1609
	 * then re-locking the prison, but this is still a valid state as long
1610
	 * as allprison_lock remains xlocked.
1611
	 */
1612
	mtx_unlock(&pr->pr_mtx);
1613
	error = osd_jail_call(pr, PR_METHOD_CHECK, opts);
1614
	if (error != 0) {
1615
		prison_deref(pr, created
1616
		    ? PD_LIST_XLOCKED
1617
		    : PD_DEREF | PD_LIST_XLOCKED);
1618
		goto done_releroot;
1619
	}
1620
	mtx_unlock(&pr->pr_mtx);
1621
1622
	/* At this point, all valid parameters should have been noted. */
1623
	TAILQ_FOREACH(opt, opts, link) {
1624
		if (!opt->seen && strcmp(opt->name, "errmsg")) {
1625
			error = EINVAL;
1626
			vfs_opterror(opts, "unknown parameter: %s", opt->name);
1627
			goto done_deref_locked;
1628
		}
1629
	}
1630
1619
	/* Set the parameters of the prison. */
1631
	/* Set the parameters of the prison. */
1620
#ifdef INET
1632
#ifdef INET
1621
	redo_ip4 = 0;
1633
	redo_ip4 = 0;
Lines 1689-1700 Link Here
1689
		FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend)
1701
		FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend)
1690
			tpr->pr_devfs_rsnum = rsnum;
1702
			tpr->pr_devfs_rsnum = rsnum;
1691
	}
1703
	}
1692
	if (name != NULL) {
1704
	if (namelc != NULL) {
1693
		if (ppr == &prison0)
1705
		if (ppr == &prison0)
1694
			strlcpy(pr->pr_name, name, sizeof(pr->pr_name));
1706
			strlcpy(pr->pr_name, namelc, sizeof(pr->pr_name));
1695
		else
1707
		else
1696
			snprintf(pr->pr_name, sizeof(pr->pr_name), "%s.%s",
1708
			snprintf(pr->pr_name, sizeof(pr->pr_name), "%s.%s",
1697
			    ppr->pr_name, name);
1709
			    ppr->pr_name, namelc);
1698
		/* Change this component of child names. */
1710
		/* Change this component of child names. */
1699
		FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) {
1711
		FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) {
1700
			bcopy(tpr->pr_name + onamelen, tpr->pr_name + namelen,
1712
			bcopy(tpr->pr_name + onamelen, tpr->pr_name + namelen,
Lines 1772-1777 Link Here
1772
	 * for now, so new ones will remain unseen until after the module
1784
	 * for now, so new ones will remain unseen until after the module
1773
	 * handlers have completed.
1785
	 * handlers have completed.
1774
	 */
1786
	 */
1787
	born = pr->pr_uref == 0;
1775
	if (!created && (ch_flags & PR_PERSIST & (pr_flags ^ pr->pr_flags))) {
1788
	if (!created && (ch_flags & PR_PERSIST & (pr_flags ^ pr->pr_flags))) {
1776
		if (pr_flags & PR_PERSIST) {
1789
		if (pr_flags & PR_PERSIST) {
1777
			pr->pr_ref++;
1790
			pr->pr_ref++;
Lines 1841-1855 Link Here
1841
1854
1842
	/* Let the modules do their work. */
1855
	/* Let the modules do their work. */
1843
	sx_downgrade(&allprison_lock);
1856
	sx_downgrade(&allprison_lock);
1844
	if (created) {
1857
	if (born) {
1845
		error = osd_jail_call(pr, PR_METHOD_CREATE, opts);
1858
		error = osd_jail_call(pr, PR_METHOD_CREATE, opts);
1846
		if (error) {
1859
		if (error) {
1847
			prison_deref(pr, PD_LIST_SLOCKED);
1860
			(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
1861
			prison_deref(pr, created
1862
			    ? PD_LIST_SLOCKED
1863
			    : PD_DEREF | PD_LIST_SLOCKED);
1848
			goto done_errmsg;
1864
			goto done_errmsg;
1849
		}
1865
		}
1850
	}
1866
	}
1851
	error = osd_jail_call(pr, PR_METHOD_SET, opts);
1867
	error = osd_jail_call(pr, PR_METHOD_SET, opts);
1852
	if (error) {
1868
	if (error) {
1869
		if (born)
1870
			(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
1853
		prison_deref(pr, created
1871
		prison_deref(pr, created
1854
		    ? PD_LIST_SLOCKED
1872
		    ? PD_LIST_SLOCKED
1855
		    : PD_DEREF | PD_LIST_SLOCKED);
1873
		    : PD_DEREF | PD_LIST_SLOCKED);
Lines 1901-1907 Link Here
1901
			sx_sunlock(&allprison_lock);
1919
			sx_sunlock(&allprison_lock);
1902
	}
1920
	}
1903
1921
1904
	goto done_errmsg;
1922
	goto done_free;
1905
1923
1906
 done_deref_locked:
1924
 done_deref_locked:
1907
	prison_deref(pr, created
1925
	prison_deref(pr, created
Lines 2281-2287 Link Here
2281
2299
2282
	/* Remove all descendants of this prison, then remove this prison. */
2300
	/* Remove all descendants of this prison, then remove this prison. */
2283
	pr->pr_ref++;
2301
	pr->pr_ref++;
2284
	pr->pr_flags |= PR_REMOVE;
2285
	if (!LIST_EMPTY(&pr->pr_children)) {
2302
	if (!LIST_EMPTY(&pr->pr_children)) {
2286
		mtx_unlock(&pr->pr_mtx);
2303
		mtx_unlock(&pr->pr_mtx);
2287
		lpr = NULL;
2304
		lpr = NULL;
Lines 2290-2296 Link Here
2290
			if (cpr->pr_ref > 0) {
2307
			if (cpr->pr_ref > 0) {
2291
				tpr = cpr;
2308
				tpr = cpr;
2292
				cpr->pr_ref++;
2309
				cpr->pr_ref++;
2293
				cpr->pr_flags |= PR_REMOVE;
2294
			} else {
2310
			} else {
2295
				/* Already removed - do not do it again. */
2311
				/* Already removed - do not do it again. */
2296
				tpr = NULL;
2312
				tpr = NULL;
Lines 2606-2611 Link Here
2606
prison_deref(struct prison *pr, int flags)
2622
prison_deref(struct prison *pr, int flags)
2607
{
2623
{
2608
	struct prison *ppr, *tpr;
2624
	struct prison *ppr, *tpr;
2625
	int ref, lasturef;
2609
2626
2610
	if (!(flags & PD_LOCKED))
2627
	if (!(flags & PD_LOCKED))
2611
		mtx_lock(&pr->pr_mtx);
2628
		mtx_lock(&pr->pr_mtx);
Lines 2612-2624 Link Here
2612
	for (;;) {
2629
	for (;;) {
2613
		if (flags & PD_DEUREF) {
2630
		if (flags & PD_DEUREF) {
2614
			pr->pr_uref--;
2631
			pr->pr_uref--;
2632
			lasturef = pr->pr_uref == 0;
2633
			if (lasturef)
2634
				pr->pr_ref++;
2615
			KASSERT(prison0.pr_uref != 0, ("prison0 pr_uref=0"));
2635
			KASSERT(prison0.pr_uref != 0, ("prison0 pr_uref=0"));
2616
		}
2636
		} else
2637
			lasturef = 0;
2617
		if (flags & PD_DEREF)
2638
		if (flags & PD_DEREF)
2618
			pr->pr_ref--;
2639
			pr->pr_ref--;
2640
		ref = pr->pr_ref;
2641
		mtx_unlock(&pr->pr_mtx);
2642
2643
		/*
2644
		 * Tell the modules if the last user reference was removed
2645
		 * (even it sticks around in dying state).
2646
		 */
2647
		if (lasturef) {
2648
			if (!(flags & (PD_LIST_SLOCKED | PD_LIST_XLOCKED))) {
2649
				if (ref > 1) {
2650
					sx_slock(&allprison_lock);
2651
					flags |= PD_LIST_SLOCKED;
2652
				} else {
2653
					sx_xlock(&allprison_lock);
2654
					flags |= PD_LIST_XLOCKED;
2655
				}
2656
			}
2657
			(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
2658
			mtx_lock(&pr->pr_mtx);
2659
			ref = --pr->pr_ref;
2660
			mtx_unlock(&pr->pr_mtx);
2661
		}
2662
2619
		/* If the prison still has references, nothing else to do. */
2663
		/* If the prison still has references, nothing else to do. */
2620
		if (pr->pr_ref > 0) {
2664
		if (ref > 0) {
2621
			mtx_unlock(&pr->pr_mtx);
2622
			if (flags & PD_LIST_SLOCKED)
2665
			if (flags & PD_LIST_SLOCKED)
2623
				sx_sunlock(&allprison_lock);
2666
				sx_sunlock(&allprison_lock);
2624
			else if (flags & PD_LIST_XLOCKED)
2667
			else if (flags & PD_LIST_XLOCKED)
Lines 2626-2632 Link Here
2626
			return;
2669
			return;
2627
		}
2670
		}
2628
2671
2629
		mtx_unlock(&pr->pr_mtx);
2630
		if (flags & PD_LIST_SLOCKED) {
2672
		if (flags & PD_LIST_SLOCKED) {
2631
			if (!sx_try_upgrade(&allprison_lock)) {
2673
			if (!sx_try_upgrade(&allprison_lock)) {
2632
				sx_sunlock(&allprison_lock);
2674
				sx_sunlock(&allprison_lock);

Return to bug 48471