View | Details | Raw Unified | Return to bug 257555
Collapse All | Expand All

(-)b/sys/kern/kern_jail.c (-4 / +18 lines)
Lines 51-56 __FBSDID("$FreeBSD$"); Link Here
51
#include <sys/jail.h>
51
#include <sys/jail.h>
52
#include <sys/linker.h>
52
#include <sys/linker.h>
53
#include <sys/lock.h>
53
#include <sys/lock.h>
54
#include <sys/mman.h>
54
#include <sys/mutex.h>
55
#include <sys/mutex.h>
55
#include <sys/racct.h>
56
#include <sys/racct.h>
56
#include <sys/rctl.h>
57
#include <sys/rctl.h>
Lines 143-148 static void prison_complete(void *context, int pending); Link Here
143
static void prison_deref(struct prison *pr, int flags);
144
static void prison_deref(struct prison *pr, int flags);
144
static void prison_deref_kill(struct prison *pr, struct prisonlist *freeprison);
145
static void prison_deref_kill(struct prison *pr, struct prisonlist *freeprison);
145
static int prison_lock_xlock(struct prison *pr, int flags);
146
static int prison_lock_xlock(struct prison *pr, int flags);
147
static void prison_cleanup(struct prison *pr);
146
static void prison_free_not_last(struct prison *pr);
148
static void prison_free_not_last(struct prison *pr);
147
static void prison_proc_free_not_last(struct prison *pr);
149
static void prison_proc_free_not_last(struct prison *pr);
148
static void prison_set_allow_locked(struct prison *pr, unsigned flag,
150
static void prison_set_allow_locked(struct prison *pr, unsigned flag,
Lines 2994-3001 prison_deref(struct prison *pr, int flags) Link Here
2994
					pr->pr_state = PRISON_STATE_DYING;
2996
					pr->pr_state = PRISON_STATE_DYING;
2995
					mtx_unlock(&pr->pr_mtx);
2997
					mtx_unlock(&pr->pr_mtx);
2996
					flags &= ~PD_LOCKED;
2998
					flags &= ~PD_LOCKED;
2997
					(void)osd_jail_call(pr,
2999
					prison_cleanup(pr);
2998
					    PR_METHOD_REMOVE, NULL);
2999
				}
3000
				}
3000
			}
3001
			}
3001
		}
3002
		}
Lines 3150-3156 prison_deref_kill(struct prison *pr, struct prisonlist *freeprison) Link Here
3150
		}
3151
		}
3151
		if (!(cpr->pr_flags & PR_REMOVE))
3152
		if (!(cpr->pr_flags & PR_REMOVE))
3152
			continue;
3153
			continue;
3153
		(void)osd_jail_call(cpr, PR_METHOD_REMOVE, NULL);
3154
		prison_cleanup(cpr);
3154
		mtx_lock(&cpr->pr_mtx);
3155
		mtx_lock(&cpr->pr_mtx);
3155
		cpr->pr_flags &= ~PR_REMOVE;
3156
		cpr->pr_flags &= ~PR_REMOVE;
3156
		if (cpr->pr_flags & PR_PERSIST) {
3157
		if (cpr->pr_flags & PR_PERSIST) {
Lines 3186-3192 prison_deref_kill(struct prison *pr, struct prisonlist *freeprison) Link Here
3186
	if (rpr != NULL)
3187
	if (rpr != NULL)
3187
		LIST_REMOVE(rpr, pr_sibling);
3188
		LIST_REMOVE(rpr, pr_sibling);
3188
3189
3189
	(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
3190
	prison_cleanup(pr);
3190
	mtx_lock(&pr->pr_mtx);
3191
	mtx_lock(&pr->pr_mtx);
3191
	if (pr->pr_flags & PR_PERSIST) {
3192
	if (pr->pr_flags & PR_PERSIST) {
3192
		pr->pr_flags &= ~PR_PERSIST;
3193
		pr->pr_flags &= ~PR_PERSIST;
Lines 3232-3237 prison_lock_xlock(struct prison *pr, int flags) Link Here
3232
	return flags;
3233
	return flags;
3233
}
3234
}
3234
3235
3236
/*
3237
 * Release prison resources when it starts dying (when the last user
3238
 * reference is dropped, or when it is killed).
3239
 */
3240
static void
3241
prison_cleanup(struct prison *pr)
3242
{
3243
	sx_assert(&allprison_lock, SA_XLOCKED);
3244
	mtx_assert(&pr->pr_mtx, MA_NOTOWNED);
3245
	shm_prison_cleanup(pr);
3246
	(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
3247
}
3248
3235
/*
3249
/*
3236
 * Set or clear a permission bit in the pr_allow field, passing restrictions
3250
 * Set or clear a permission bit in the pr_allow field, passing restrictions
3237
 * (cleared permission) down to child jails.
3251
 * (cleared permission) down to child jails.
(-)b/sys/kern/sysv_shm.c (-7 / +7 lines)
Lines 149-155 static int shm_prison_check(void *, void *); Link Here
149
static int shm_prison_set(void *, void *);
149
static int shm_prison_set(void *, void *);
150
static int shm_prison_get(void *, void *);
150
static int shm_prison_get(void *, void *);
151
static int shm_prison_remove(void *, void *);
151
static int shm_prison_remove(void *, void *);
152
static void shm_prison_cleanup(struct prison *);
152
static void shm_prison_doremove(struct prison *);
153
153
154
/*
154
/*
155
 * Tuneable values.
155
 * Tuneable values.
Lines 1158-1164 shm_prison_set(void *obj, void *data) Link Here
1158
		prison_unlock(pr);
1158
		prison_unlock(pr);
1159
		if (orpr != NULL) {
1159
		if (orpr != NULL) {
1160
			if (orpr == pr)
1160
			if (orpr == pr)
1161
				shm_prison_cleanup(pr);
1161
				shm_prison_doremove(pr);
1162
			/* Disable all child jails as well. */
1162
			/* Disable all child jails as well. */
1163
			FOREACH_PRISON_DESCENDANT(pr, tpr, descend) {
1163
			FOREACH_PRISON_DESCENDANT(pr, tpr, descend) {
1164
				prison_lock(tpr);
1164
				prison_lock(tpr);
Lines 1167-1173 shm_prison_set(void *obj, void *data) Link Here
1167
					osd_jail_del(tpr, shm_prison_slot);
1167
					osd_jail_del(tpr, shm_prison_slot);
1168
					prison_unlock(tpr);
1168
					prison_unlock(tpr);
1169
					if (trpr == tpr)
1169
					if (trpr == tpr)
1170
						shm_prison_cleanup(tpr);
1170
						shm_prison_doremove(tpr);
1171
				} else {
1171
				} else {
1172
					prison_unlock(tpr);
1172
					prison_unlock(tpr);
1173
					descend = 0;
1173
					descend = 0;
Lines 1193-1199 shm_prison_set(void *obj, void *data) Link Here
1193
		prison_unlock(pr);
1193
		prison_unlock(pr);
1194
		if (orpr != nrpr) {
1194
		if (orpr != nrpr) {
1195
			if (orpr == pr)
1195
			if (orpr == pr)
1196
				shm_prison_cleanup(pr);
1196
				shm_prison_doremove(pr);
1197
			if (orpr != NULL) {
1197
			if (orpr != NULL) {
1198
				/* Change child jails matching the old root, */
1198
				/* Change child jails matching the old root, */
1199
				FOREACH_PRISON_DESCENDANT(pr, tpr, descend) {
1199
				FOREACH_PRISON_DESCENDANT(pr, tpr, descend) {
Lines 1205-1211 shm_prison_set(void *obj, void *data) Link Here
1205
						    shm_prison_slot, nrpr);
1205
						    shm_prison_slot, nrpr);
1206
						prison_unlock(tpr);
1206
						prison_unlock(tpr);
1207
						if (trpr == tpr)
1207
						if (trpr == tpr)
1208
							shm_prison_cleanup(tpr);
1208
							shm_prison_doremove(tpr);
1209
					} else {
1209
					} else {
1210
						prison_unlock(tpr);
1210
						prison_unlock(tpr);
1211
						descend = 0;
1211
						descend = 0;
Lines 1249-1261 shm_prison_remove(void *obj, void *data __unused) Link Here
1249
	rpr = osd_jail_get(pr, shm_prison_slot);
1249
	rpr = osd_jail_get(pr, shm_prison_slot);
1250
	prison_unlock(pr);
1250
	prison_unlock(pr);
1251
	if (rpr == pr)
1251
	if (rpr == pr)
1252
		shm_prison_cleanup(pr);
1252
		shm_prison_doremove(pr);
1253
	SYSVSHM_UNLOCK();
1253
	SYSVSHM_UNLOCK();
1254
	return (0);
1254
	return (0);
1255
}
1255
}
1256
1256
1257
static void
1257
static void
1258
shm_prison_cleanup(struct prison *pr)
1258
shm_prison_doremove(struct prison *pr)
1259
{
1259
{
1260
	struct shmid_kernel *shmseg;
1260
	struct shmid_kernel *shmseg;
1261
	int i;
1261
	int i;
(-)b/sys/kern/uipc_shm.c (-5 / +32 lines)
Lines 125-130 static void shm_init(void *arg); Link Here
125
static void	shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd);
125
static void	shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd);
126
static struct shmfd *shm_lookup(char *path, Fnv32_t fnv);
126
static struct shmfd *shm_lookup(char *path, Fnv32_t fnv);
127
static int	shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred);
127
static int	shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred);
128
static void	shm_doremove(struct shm_mapping *map);
128
static int	shm_dotruncate_cookie(struct shmfd *shmfd, off_t length,
129
static int	shm_dotruncate_cookie(struct shmfd *shmfd, off_t length,
129
    void *rl_cookie);
130
    void *rl_cookie);
130
static int	shm_dotruncate_locked(struct shmfd *shmfd, off_t length,
131
static int	shm_dotruncate_locked(struct shmfd *shmfd, off_t length,
Lines 982-987 shm_init(void *arg) Link Here
982
}
983
}
983
SYSINIT(shm_init, SI_SUB_SYSV_SHM, SI_ORDER_ANY, shm_init, NULL);
984
SYSINIT(shm_init, SI_SUB_SYSV_SHM, SI_ORDER_ANY, shm_init, NULL);
984
985
986
/*
987
 * Remove shared memory objects that belong to a dying prison.
988
 */
989
void
990
shm_prison_cleanup(struct prison *pr)
991
{
992
	struct shm_mapping *shmm, *tshmm;
993
	u_long i;
994
995
	sx_xlock(&shm_dict_lock);
996
	for (i = 0; i < shm_hash + 1; i++) {
997
		LIST_FOREACH_SAFE(shmm, &shm_dictionary[i], sm_link, tshmm) {
998
			if (shmm->sm_shmfd->shm_object->cred &&
999
			    shmm->sm_shmfd->shm_object->cred->cr_prison == pr)
1000
				shm_doremove(shmm);
1001
		}
1002
	}
1003
	sx_xunlock(&shm_dict_lock);
1004
}
1005
985
/*
1006
/*
986
 * Dictionary management.  We maintain an in-kernel dictionary to map
1007
 * Dictionary management.  We maintain an in-kernel dictionary to map
987
 * paths to shmfd objects.  We use the FNV hash on the path to store
1008
 * paths to shmfd objects.  We use the FNV hash on the path to store
Lines 1034-1044 shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred) Link Here
1034
			    FREAD | FWRITE);
1055
			    FREAD | FWRITE);
1035
			if (error)
1056
			if (error)
1036
				return (error);
1057
				return (error);
1037
			map->sm_shmfd->shm_path = NULL;
1058
			shm_doremove(map);
1038
			LIST_REMOVE(map, sm_link);
1039
			shm_drop(map->sm_shmfd);
1040
			free(map->sm_path, M_SHMFD);
1041
			free(map, M_SHMFD);
1042
			return (0);
1059
			return (0);
1043
		}
1060
		}
1044
	}
1061
	}
Lines 1046-1051 shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred) Link Here
1046
	return (ENOENT);
1063
	return (ENOENT);
1047
}
1064
}
1048
1065
1066
static void
1067
shm_doremove(struct shm_mapping *map)
1068
{
1069
	map->sm_shmfd->shm_path = NULL;
1070
	LIST_REMOVE(map, sm_link);
1071
	shm_drop(map->sm_shmfd);
1072
	free(map->sm_path, M_SHMFD);
1073
	free(map, M_SHMFD);
1074
}
1075
1049
int
1076
int
1050
kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
1077
kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
1051
    int shmflags, struct filecaps *fcaps, const char *name __unused)
1078
    int shmflags, struct filecaps *fcaps, const char *name __unused)
(-)b/sys/sys/mman.h (+3 lines)
Lines 300-305 struct shmfd { Link Here
300
#endif
300
#endif
301
301
302
#ifdef _KERNEL
302
#ifdef _KERNEL
303
struct prison;
304
303
int	shm_map(struct file *fp, size_t size, off_t offset, void **memp);
305
int	shm_map(struct file *fp, size_t size, off_t offset, void **memp);
304
int	shm_unmap(struct file *fp, void *mem, size_t size);
306
int	shm_unmap(struct file *fp, void *mem, size_t size);
305
307
Lines 309-314 struct shmfd *shm_hold(struct shmfd *shmfd); Link Here
309
void	shm_drop(struct shmfd *shmfd);
311
void	shm_drop(struct shmfd *shmfd);
310
int	shm_dotruncate(struct shmfd *shmfd, off_t length);
312
int	shm_dotruncate(struct shmfd *shmfd, off_t length);
311
bool	shm_largepage(struct shmfd *shmfd);
313
bool	shm_largepage(struct shmfd *shmfd);
314
void	shm_prison_cleanup(struct prison *pr);
312
315
313
extern struct fileops shm_ops;
316
extern struct fileops shm_ops;
314
317

Return to bug 257555