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

Collapse All | Expand All

(-)b/sys/amd64/include/vmparam.h (-1 / +1 lines)
Lines 170-176 Link Here
170
#define	VM_MAXUSER_ADDRESS	UVADDR(NUPML4E, 0, 0, 0)
170
#define	VM_MAXUSER_ADDRESS	UVADDR(NUPML4E, 0, 0, 0)
171
171
172
#define	SHAREDPAGE		(VM_MAXUSER_ADDRESS - PAGE_SIZE)
172
#define	SHAREDPAGE		(VM_MAXUSER_ADDRESS - PAGE_SIZE)
173
#define	USRSTACK		SHAREDPAGE
173
#define	USRSTACK		(SHAREDPAGE - 4*PAGE_SIZE)
174
174
175
#define	VM_MAX_ADDRESS		UPT_MAX_ADDRESS
175
#define	VM_MAX_ADDRESS		UPT_MAX_ADDRESS
176
#define	VM_MIN_ADDRESS		(0)
176
#define	VM_MIN_ADDRESS		(0)
(-)b/sys/compat/freebsd32/freebsd32_misc.c (+13 lines)
Lines 30-35 __FBSDID("$FreeBSD$"); Link Here
30
#include "opt_compat.h"
30
#include "opt_compat.h"
31
#include "opt_inet.h"
31
#include "opt_inet.h"
32
#include "opt_inet6.h"
32
#include "opt_inet6.h"
33
#include "opt_pax.h"
33
34
34
#define __ELF_WORD_SIZE 32
35
#define __ELF_WORD_SIZE 32
35
36
Lines 113-118 __FBSDID("$FreeBSD$"); Link Here
113
114
114
FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD");
115
FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD");
115
116
117
#ifdef PAX_ASLR
118
#include <sys/pax.h>
119
#endif /* PAX_ASLR */
120
116
#ifndef __mips__
121
#ifndef __mips__
117
CTASSERT(sizeof(struct timeval32) == 8);
122
CTASSERT(sizeof(struct timeval32) == 8);
118
CTASSERT(sizeof(struct timespec32) == 8);
123
CTASSERT(sizeof(struct timespec32) == 8);
Lines 2823-2828 freebsd32_copyout_strings(struct image_params *imgp) Link Here
2823
	int argc, envc, i;
2828
	int argc, envc, i;
2824
	u_int32_t *vectp;
2829
	u_int32_t *vectp;
2825
	char *stringp, *destp;
2830
	char *stringp, *destp;
2831
#ifdef PAX_ASLR
2832
	char *orig_destp;
2833
#endif /* PAX_ASLR */
2826
	u_int32_t *stack_base;
2834
	u_int32_t *stack_base;
2827
	struct freebsd32_ps_strings *arginfo;
2835
	struct freebsd32_ps_strings *arginfo;
2828
	char canary[sizeof(long) * 8];
2836
	char canary[sizeof(long) * 8];
Lines 2850-2855 freebsd32_copyout_strings(struct image_params *imgp) Link Here
2850
	    roundup(sizeof(pagesizes32), sizeof(char *)) -
2858
	    roundup(sizeof(pagesizes32), sizeof(char *)) -
2851
	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
2859
	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
2852
2860
2861
#ifdef PAX_ASLR
2862
	orig_destp = destp;
2863
	pax_aslr_stack(curthread, &destp, orig_destp);
2864
#endif /* PAX_ASLR */
2865
2853
	/*
2866
	/*
2854
	 * install sigcode
2867
	 * install sigcode
2855
	 */
2868
	 */
(-)b/sys/conf/files (+1 lines)
Lines 2799-2804 kern/kern_mtxpool.c standard Link Here
2799
kern/kern_mutex.c		standard
2799
kern/kern_mutex.c		standard
2800
kern/kern_ntptime.c		standard
2800
kern/kern_ntptime.c		standard
2801
kern/kern_osd.c			standard
2801
kern/kern_osd.c			standard
2802
kern/kern_pax.c			optional pax_aslr
2802
kern/kern_physio.c		standard
2803
kern/kern_physio.c		standard
2803
kern/kern_pmc.c			standard
2804
kern/kern_pmc.c			standard
2804
kern/kern_poll.c		optional device_polling
2805
kern/kern_poll.c		optional device_polling
(-)b/sys/conf/options (+3 lines)
Lines 915-920 RACCT opt_global.h Link Here
915
# Resource Limits
915
# Resource Limits
916
RCTL		opt_global.h
916
RCTL		opt_global.h
917
917
918
# PaX - hardening options
919
PAX_ASLR		opt_pax.h
920
PAX_ASLR_MAX_SEC	opt_pax.h
918
# Random number generator(s)
921
# Random number generator(s)
919
RANDOM_YARROW	opt_random.h
922
RANDOM_YARROW	opt_random.h
920
RANDOM_FORTUNA	opt_random.h
923
RANDOM_FORTUNA	opt_random.h
(-)b/sys/kern/imgact_elf.c (+11 lines)
Lines 34-39 __FBSDID("$FreeBSD$"); Link Here
34
#include "opt_capsicum.h"
34
#include "opt_capsicum.h"
35
#include "opt_compat.h"
35
#include "opt_compat.h"
36
#include "opt_core.h"
36
#include "opt_core.h"
37
#include "opt_pax.h"
37
38
38
#include <sys/param.h>
39
#include <sys/param.h>
39
#include <sys/capability.h>
40
#include <sys/capability.h>
Lines 47-53 __FBSDID("$FreeBSD$"); Link Here
47
#include <sys/mount.h>
48
#include <sys/mount.h>
48
#include <sys/mman.h>
49
#include <sys/mman.h>
49
#include <sys/namei.h>
50
#include <sys/namei.h>
51
#include <sys/pax.h>
50
#include <sys/pioctl.h>
52
#include <sys/pioctl.h>
53
#include <sys/jail.h>
51
#include <sys/proc.h>
54
#include <sys/proc.h>
52
#include <sys/procfs.h>
55
#include <sys/procfs.h>
53
#include <sys/racct.h>
56
#include <sys/racct.h>
Lines 600-605 __elfN(load_file)(struct proc *p, const char *file, u_long *addr, Link Here
600
	u_long rbase;
603
	u_long rbase;
601
	u_long base_addr = 0;
604
	u_long base_addr = 0;
602
	int error, i, numsegs;
605
	int error, i, numsegs;
606
    struct prison *pr; /* For ASLR */
603
607
604
#ifdef CAPABILITY_MODE
608
#ifdef CAPABILITY_MODE
605
	/*
609
	/*
Lines 664-669 __elfN(load_file)(struct proc *p, const char *file, u_long *addr, Link Here
664
		goto fail;
668
		goto fail;
665
	}
669
	}
666
670
671
#ifdef PAX_ASLR
672
    pr = pax_aslr_get_prison(NULL, imgp->proc);
673
    if (pax_aslr_active(NULL, imgp->proc)) {
674
        rbase += round_page(PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_EXEC_LSB, pr->pr_pax_aslr_exec_len));
675
    }
676
#endif
677
667
	/* Only support headers that fit within first page for now      */
678
	/* Only support headers that fit within first page for now      */
668
	if ((hdr->e_phoff > PAGE_SIZE) ||
679
	if ((hdr->e_phoff > PAGE_SIZE) ||
669
	    (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
680
	    (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
(-)b/sys/kern/kern_exec.c (-1 / +19 lines)
Lines 30-35 __FBSDID("$FreeBSD$"); Link Here
30
#include "opt_capsicum.h"
30
#include "opt_capsicum.h"
31
#include "opt_hwpmc_hooks.h"
31
#include "opt_hwpmc_hooks.h"
32
#include "opt_ktrace.h"
32
#include "opt_ktrace.h"
33
#include "opt_pax.h"
33
#include "opt_vm.h"
34
#include "opt_vm.h"
34
35
35
#include <sys/param.h>
36
#include <sys/param.h>
Lines 94-99 __FBSDID("$FreeBSD$"); Link Here
94
dtrace_execexit_func_t	dtrace_fasttrap_exec;
95
dtrace_execexit_func_t	dtrace_fasttrap_exec;
95
#endif
96
#endif
96
97
98
#ifdef PAX_ASLR
99
#include <sys/pax.h>
100
#endif /* PAX_ASLR */
101
97
SDT_PROVIDER_DECLARE(proc);
102
SDT_PROVIDER_DECLARE(proc);
98
SDT_PROBE_DEFINE1(proc, kernel, , exec, "char *");
103
SDT_PROBE_DEFINE1(proc, kernel, , exec, "char *");
99
SDT_PROBE_DEFINE1(proc, kernel, , exec__failure, "int");
104
SDT_PROBE_DEFINE1(proc, kernel, , exec__failure, "int");
Lines 1055-1060 exec_new_vmspace(imgp, sv) Link Here
1055
		map = &vmspace->vm_map;
1060
		map = &vmspace->vm_map;
1056
	}
1061
	}
1057
1062
1063
#ifdef PAX_ASLR
1064
	pax_aslr_init(curthread, imgp);
1065
#endif /* PAX_ASLR */
1066
1058
	/* Map a shared page */
1067
	/* Map a shared page */
1059
	obj = sv->sv_shared_page_obj;
1068
	obj = sv->sv_shared_page_obj;
1060
	if (obj != NULL) {
1069
	if (obj != NULL) {
Lines 1232-1243 exec_copyout_strings(imgp) Link Here
1232
	int argc, envc;
1241
	int argc, envc;
1233
	char **vectp;
1242
	char **vectp;
1234
	char *stringp, *destp;
1243
	char *stringp, *destp;
1244
#ifdef	PAX_ASLR
1245
	char *orig_destp;
1246
#endif /* PAX_ASLR */
1235
	register_t *stack_base;
1247
	register_t *stack_base;
1236
	struct ps_strings *arginfo;
1248
	struct ps_strings *arginfo;
1237
	struct proc *p;
1249
	struct proc *p;
1238
	size_t execpath_len;
1250
	size_t execpath_len;
1239
	int szsigcode, szps;
1251
	int szsigcode, szps;
1240
	char canary[sizeof(long) * 8];
1252
	char canary[sizeof(long) * 8];
1253
    unsigned int sgap;
1241
1254
1242
	szps = sizeof(pagesizes[0]) * MAXPAGESIZES;
1255
	szps = sizeof(pagesizes[0]) * MAXPAGESIZES;
1243
	/*
1256
	/*
Lines 1255-1265 exec_copyout_strings(imgp) Link Here
1255
		if (p->p_sysent->sv_szsigcode != NULL)
1268
		if (p->p_sysent->sv_szsigcode != NULL)
1256
			szsigcode = *(p->p_sysent->sv_szsigcode);
1269
			szsigcode = *(p->p_sysent->sv_szsigcode);
1257
	}
1270
	}
1258
	destp =	(caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
1271
    sgap=(unsigned int)(ALIGN(arc4random()&((64*1024)-1)));
1272
	destp =	(caddr_t)arginfo - szsigcode - SPARE_USRSPACE - sgap -
1259
	    roundup(execpath_len, sizeof(char *)) -
1273
	    roundup(execpath_len, sizeof(char *)) -
1260
	    roundup(sizeof(canary), sizeof(char *)) -
1274
	    roundup(sizeof(canary), sizeof(char *)) -
1261
	    roundup(szps, sizeof(char *)) -
1275
	    roundup(szps, sizeof(char *)) -
1262
	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
1276
	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
1277
#ifdef PAX_ASLR
1278
	orig_destp = destp;
1279
	pax_aslr_stack(curthread, &destp, orig_destp);
1280
#endif /* PAX_ASLR */
1263
1281
1264
	/*
1282
	/*
1265
	 * install sigcode
1283
	 * install sigcode
(-)b/sys/kern/kern_jail.c (+16 lines)
Lines 33-38 __FBSDID("$FreeBSD$"); Link Here
33
#include "opt_ddb.h"
33
#include "opt_ddb.h"
34
#include "opt_inet.h"
34
#include "opt_inet.h"
35
#include "opt_inet6.h"
35
#include "opt_inet6.h"
36
#include "opt_pax.h"
36
37
37
#include <sys/param.h>
38
#include <sys/param.h>
38
#include <sys/types.h>
39
#include <sys/types.h>
Lines 60-65 __FBSDID("$FreeBSD$"); Link Here
60
#include <sys/syscallsubr.h>
61
#include <sys/syscallsubr.h>
61
#include <sys/sysctl.h>
62
#include <sys/sysctl.h>
62
#include <sys/vnode.h>
63
#include <sys/vnode.h>
64
#include <sys/pax.h>
63
65
64
#include <net/if.h>
66
#include <net/if.h>
65
#include <net/if_var.h>
67
#include <net/if_var.h>
Lines 114-119 struct prison prison0 = { Link Here
114
	.pr_flags	= PR_HOST|_PR_IP_SADDRSEL,
116
	.pr_flags	= PR_HOST|_PR_IP_SADDRSEL,
115
#endif
117
#endif
116
	.pr_allow	= PR_ALLOW_ALL,
118
	.pr_allow	= PR_ALLOW_ALL,
119
#ifdef PAX_ASLR
120
    .pr_pax_set = 0,
121
    .pr_pax_aslr_status = 0,
122
    .pr_pax_aslr_debug = 0,
123
    .pr_pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_MIN_LEN,
124
    .pr_pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_MIN_LEN,
125
    .pr_pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_MIN_LEN,
126
#ifdef COMPAT_FREEBSD32
127
    .pr_pax_aslr_compat_status = 0,
128
    .pr_pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN,
129
    .pr_pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN,
130
    .pr_pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN,
131
#endif /* COMPAT_FREEBSD32 */
132
#endif /* PAX_ASLR */
117
};
133
};
118
MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
134
MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
119
135
(-)b/sys/kern/kern_pax.c (+589 lines)
Added Link Here
1
/*-
2
 * Copyright (c) 2013, by Oliver Pinter <oliver.pntr at gmail.com>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. The name of the developer may NOT be used to endorse or promote products
11
 *    derived from this software without specific prior written permission.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
 * SUCH DAMAGE.
24
 *
25
 * $FreeBSD$
26
 *
27
 * Enhancements made by Shawn "lattera" Webb under the direction of SoldierX.
28
 */
29
30
#include <sys/cdefs.h>
31
__FBSDID("$FreeBSD$");
32
33
#include "opt_pax.h"
34
#include "opt_compat.h"
35
36
#include <sys/param.h>
37
#include <sys/systm.h>
38
#include <sys/kernel.h>
39
#include <sys/imgact.h>
40
#include <sys/sysent.h>
41
#include <sys/proc.h>
42
#include <sys/elf_common.h>
43
#include <sys/pax.h>
44
#include <sys/sysctl.h>
45
#include <sys/vnode.h>
46
#include <sys/queue.h>
47
#include <sys/libkern.h>
48
#include <sys/jail.h>
49
50
#include <sys/mman.h>
51
#include <sys/libkern.h>
52
#include <sys/exec.h>
53
54
#include <vm/pmap.h>
55
#include <vm/vm_map.h>
56
57
static int sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS);
58
static int sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS);
59
static int sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS);
60
static int sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS);
61
62
/*
63
 * sysctls and tunables
64
 */
65
int pax_aslr_status = PAX_ASLR_ENABLED;
66
int pax_aslr_debug = 0;
67
68
#ifdef PAX_ASLR_MAX_SEC
69
int pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_MAX_LEN;
70
int pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_MAX_LEN;
71
int pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_MAX_LEN;
72
#else
73
int pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_MIN_LEN;
74
int pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_MIN_LEN;
75
int pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_MIN_LEN;
76
#endif /* PAX_ASLR_MAX_SEC */
77
78
79
SYSCTL_NODE(_security, OID_AUTO, pax, CTLFLAG_RD, 0,
80
    "PaX (exploit mitigation) features.");
81
SYSCTL_NODE(_security_pax, OID_AUTO, aslr, CTLFLAG_RD, 0,
82
    "Address Space Layout Randomization.");
83
84
SYSCTL_PROC(_security_pax_aslr, OID_AUTO, status,
85
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
86
    NULL, 0, sysctl_pax_aslr_status, "I",
87
    "Restrictions status. "
88
    "0 - disabled, "
89
    "1 - enabled,  "
90
    "2 - global enabled, "
91
    "3 - force global enabled");
92
TUNABLE_INT("security.pax.aslr.status", &pax_aslr_status);
93
94
SYSCTL_INT(_security_pax_aslr, OID_AUTO, debug, CTLFLAG_RWTUN|CTLFLAG_PRISON, &pax_aslr_debug, 0, "ASLR debug mode");
95
TUNABLE_INT("security.pax.aslr.debug", &pax_aslr_debug);
96
97
SYSCTL_PROC(_security_pax_aslr, OID_AUTO, mmap_len,
98
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
99
    NULL, 0, sysctl_pax_aslr_mmap, "I",
100
    "Number of bits randomized for mmap(2) calls. "
101
    "32 bit: [8,16] 64 bit: [16,32]");
102
TUNABLE_INT("security.pax.aslr.mmap", &pax_aslr_mmap_len);
103
104
SYSCTL_PROC(_security_pax_aslr, OID_AUTO, stack_len,
105
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
106
    NULL, 0, sysctl_pax_aslr_stack, "I",
107
    "Number of bits randomized for the stack. "
108
    "32 bit: [6,12] 64 bit: [12,21]");
109
TUNABLE_INT("security.pax.aslr.stack", &pax_aslr_stack_len);
110
111
SYSCTL_PROC(_security_pax_aslr, OID_AUTO, exec_len,
112
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
113
    NULL, 0, sysctl_pax_aslr_exec, "I",
114
    "Number of bits randomized for the PIE exec base. "
115
    "32 bit: [6,12] 64 bit: [12,21]");
116
TUNABLE_INT("security.pax.aslr.stack", &pax_aslr_exec_len);
117
118
static int
119
sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS)
120
{
121
    int err;
122
    int val;
123
    struct prison *pr=NULL;
124
125
    pr = pax_aslr_get_prison(req->td, NULL);
126
127
    if ((pr) && !(pr->pr_pax_set))
128
        pax_aslr_init_prison(pr);
129
130
    val = (pr != NULL) ? pr->pr_pax_aslr_status : pax_aslr_status;
131
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
132
    if (err || !req->newptr)
133
        return (err);
134
135
    switch (val) {
136
        case    PAX_ASLR_DISABLED:
137
        case    PAX_ASLR_ENABLED:
138
        case    PAX_ASLR_GLOBAL_ENABLED:
139
        case    PAX_ASLR_FORCE_GLOBAL_ENABLED:
140
            pax_aslr_status = val;
141
            if (pr)
142
                pr->pr_pax_aslr_status = val;
143
            break;
144
        default:
145
            return (EINVAL);
146
    }
147
148
    return (0);
149
}
150
151
static int
152
sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS)
153
{
154
    int err;
155
    int val;
156
    struct prison *pr=NULL;
157
158
    pr = pax_aslr_get_prison(req->td, NULL);
159
160
    if ((pr) && !(pr->pr_pax_set))
161
        pax_aslr_init_prison(pr);
162
163
    val = (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len;
164
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
165
    if (err || !req->newptr)
166
        return (err);
167
168
    if (val < PAX_ASLR_DELTA_MMAP_MIN_LEN
169
        || val > PAX_ASLR_DELTA_MMAP_MAX_LEN)
170
        return (EINVAL);
171
172
    pax_aslr_mmap_len = val;
173
    if (pr)
174
        pr->pr_pax_aslr_mmap_len = val;
175
176
    return (0);
177
}
178
179
static int
180
sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS)
181
{
182
    int err;
183
    int val;
184
    struct prison *pr=NULL;
185
186
    pr = pax_aslr_get_prison(req->td, NULL);
187
188
    if ((pr) && !(pr->pr_pax_set))
189
        pax_aslr_init_prison(pr);
190
191
    val = (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len;
192
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
193
    if (err || !req->newptr)
194
        return (err);
195
196
    if (val < PAX_ASLR_DELTA_STACK_MIN_LEN
197
        || val > PAX_ASLR_DELTA_STACK_MAX_LEN)
198
        return (EINVAL);
199
200
    pax_aslr_stack_len = val;
201
    if (pr)
202
        pr->pr_pax_aslr_stack_len = val;
203
204
    return (0);
205
}
206
207
static int
208
sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS)
209
{
210
    int err;
211
    int val;
212
    struct prison *pr=NULL;
213
214
    pr = pax_aslr_get_prison(req->td, NULL);
215
216
    if ((pr) && !(pr->pr_pax_set))
217
        pax_aslr_init_prison(pr);
218
219
    val = (pr != NULL) ? pr->pr_pax_aslr_exec_len : pax_aslr_exec_len;
220
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
221
    if (err || !req->newptr)
222
        return (err);
223
224
    if (val < PAX_ASLR_DELTA_EXEC_MIN_LEN
225
        || val > PAX_ASLR_DELTA_EXEC_MAX_LEN)
226
        return (EINVAL);
227
228
    pax_aslr_exec_len = val;
229
    if (pr)
230
        pr->pr_pax_aslr_exec_len = val;
231
232
    return (0);
233
}
234
235
/*
236
 * COMPAT_FREEBSD32 and linuxulator..
237
 */
238
#ifdef COMPAT_FREEBSD32
239
int pax_aslr_compat_status = PAX_ASLR_ENABLED;
240
241
static int sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS);
242
static int sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS);
243
static int sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS);
244
static int sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS);
245
246
#ifdef PAX_ASLR_MAX_SEC
247
int pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN;
248
int pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN;
249
int pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN;
250
#else
251
int pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN;
252
int pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN;
253
int pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN;
254
#endif /* PAX_ASLR_MAX_SEC */
255
256
SYSCTL_NODE(_security_pax_aslr, OID_AUTO, compat, CTLFLAG_RD, 0,
257
    "Setting for COMPAT_FREEBSD32 and linuxulator.");
258
259
SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, status,
260
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
261
    NULL, 0, sysctl_pax_aslr_compat_status, "I",
262
    "Restrictions status. "
263
    "0 - disabled, "
264
    "1 - enabled,  "
265
    "2 - global enabled, "
266
    "3 - force global enabled");
267
TUNABLE_INT("security.pax.aslr.compat.status", &pax_aslr_compat_status);
268
269
SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, mmap_len,
270
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
271
    NULL, 0, sysctl_pax_aslr_compat_mmap, "I",
272
    "Number of bits randomized for mmap(2) calls. "
273
    "32 bit: [8,16]");
274
TUNABLE_INT("security.pax.aslr.compat.mmap", &pax_aslr_compat_mmap_len);
275
276
SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, stack_len,
277
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
278
    NULL, 0, sysctl_pax_aslr_compat_stack, "I",
279
    "Number of bits randomized for the stack. "
280
    "32 bit: [6,12]");
281
TUNABLE_INT("security.pax.aslr.compat.stack", &pax_aslr_compat_stack_len);
282
283
SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, exec_len,
284
    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON,
285
    NULL, 0, sysctl_pax_aslr_compat_exec, "I",
286
    "Number of bits randomized for the PIE exec base. "
287
    "32 bit: [6,12]");
288
TUNABLE_INT("security.pax.aslr.compat.stack", &pax_aslr_compat_exec_len);
289
290
291
static int
292
sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS)
293
{
294
    int err;
295
    int val, *ptr;
296
    struct prison *pr=NULL;
297
298
    pr = pax_aslr_get_prison(req->td, NULL);
299
    ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_status) : &pax_aslr_compat_status;
300
301
    if ((pr) && !(pr->pr_pax_set))
302
        pax_aslr_init_prison(pr);
303
304
    val = *ptr;
305
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
306
    if (err || !req->newptr)
307
        return (err);
308
309
    switch (val) {
310
        case    PAX_ASLR_DISABLED:
311
        case    PAX_ASLR_ENABLED:
312
        case    PAX_ASLR_GLOBAL_ENABLED:
313
        case    PAX_ASLR_FORCE_GLOBAL_ENABLED:
314
            pax_aslr_compat_status = val;
315
            *ptr = val;
316
            break;
317
        default:
318
            return (EINVAL);
319
    }
320
321
    return (0);
322
}
323
324
static int
325
sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS)
326
{
327
    int err;
328
    int val, *ptr;
329
    struct prison *pr=NULL;
330
331
    pr = pax_aslr_get_prison(req->td, NULL);
332
    ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_mmap_len) : &pax_aslr_compat_mmap_len;
333
334
    if ((pr) && !(pr->pr_pax_set))
335
        pax_aslr_init_prison(pr);
336
337
    val = *ptr;
338
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
339
    if (err || !req->newptr)
340
        return (err);
341
342
    if (val < PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN
343
        || val > PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN)
344
        return (EINVAL);
345
346
    pax_aslr_compat_mmap_len = val;
347
    *ptr = val;
348
349
    return (0);
350
}
351
352
static int
353
sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS)
354
{
355
    int err;
356
    int val, *ptr;
357
    struct prison *pr=NULL;
358
359
    pr = pax_aslr_get_prison(req->td, NULL);
360
    ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_stack_len) : &pax_aslr_compat_stack_len;
361
362
    if ((pr) && !(pr->pr_pax_set))
363
        pax_aslr_init_prison(pr);
364
365
    val = (pr != NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len;
366
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
367
    if (err || !req->newptr)
368
        return (err);
369
370
    if (val < PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN
371
        || val > PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN)
372
        return (EINVAL);
373
374
    pax_aslr_compat_stack_len = val;
375
    *ptr = val;
376
377
    return (0);
378
}
379
380
static int
381
sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS)
382
{
383
    int err;
384
    int val, *ptr;
385
    struct prison *pr=NULL;
386
387
    pr = pax_aslr_get_prison(req->td, NULL);
388
    ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_exec_len) : &pax_aslr_compat_exec_len;
389
390
    if ((pr) && !(pr->pr_pax_set))
391
        pax_aslr_init_prison(pr);
392
393
    val = *ptr;
394
    err = sysctl_handle_int(oidp, &val, sizeof(int), req);
395
    if (err || !req->newptr)
396
        return (err);
397
398
    if (val < PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN
399
        || val > PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN)
400
        return (EINVAL);
401
402
    pax_aslr_compat_exec_len = val;
403
    *ptr = val;
404
405
    return (0);
406
}
407
#endif /* COMPAT_FREEBSD32 */
408
409
410
/*
411
 * ASLR functions
412
 */
413
bool
414
pax_aslr_active(struct thread *td, struct proc *proc)
415
{
416
    int status;
417
    struct prison *pr=NULL;
418
#ifdef  notyet
419
    uint32_t    flags;
420
#endif /* notyet */
421
422
    if (!(td) && !(proc))
423
        return (true);
424
425
#ifdef notyet
426
    flags = (td != NULL) ? td->td_proc->p_pax : proc->p_pax;
427
#endif /* notyet */
428
    pr = pax_aslr_get_prison(td, proc);
429
430
    if ((pr) && !(pr->pr_pax_set))
431
        pax_aslr_init_prison(pr);
432
433
    status = (pr != NULL) ? pr->pr_pax_aslr_status : pax_aslr_status;
434
435
    switch (status) {
436
    case    PAX_ASLR_DISABLED:
437
        return (false);
438
    case    PAX_ASLR_FORCE_GLOBAL_ENABLED:
439
        return (true);
440
    case    PAX_ASLR_ENABLED:
441
#ifdef notyet
442
        if ((flags & ELF_NOTE_PAX_ASLR) == 0)
443
            return (false);
444
#endif /* notyet */
445
        break;
446
    case    PAX_ASLR_GLOBAL_ENABLED:
447
#ifdef notyet
448
        if ((flags & ELF_NOTE_PAX_NOASLR) != 0)
449
            return (false);
450
#endif /* notyet */
451
        break;
452
    default:
453
        return (true);
454
    }
455
456
    return (true);
457
}
458
459
struct prison *
460
pax_aslr_get_prison(struct thread *td, struct proc *proc)
461
{
462
    if ((td)) {
463
        if ((td->td_proc) && (td->td_proc->p_ucred))
464
            return td->td_proc->p_ucred->cr_prison;
465
466
        return NULL;
467
    }
468
469
    if (!(proc))
470
        return NULL;
471
472
    return proc->p_ucred->cr_prison;
473
}
474
475
void
476
pax_aslr_init_prison(struct prison *pr)
477
{
478
    if (!(pr))
479
        return;
480
481
    if (pr->pr_pax_set)
482
        return;
483
484
    if (pax_aslr_debug)
485
        uprintf("[PaX ASLR] pax_aslr_init_prison: Setting prison %s ASLR variables\n", pr->pr_name);
486
487
    pr->pr_pax_aslr_status = pax_aslr_status;
488
    pr->pr_pax_aslr_debug = pax_aslr_debug;
489
    pr->pr_pax_aslr_mmap_len = pax_aslr_mmap_len;
490
    pr->pr_pax_aslr_stack_len = pax_aslr_stack_len;
491
    pr->pr_pax_aslr_exec_len = pax_aslr_exec_len;
492
493
#ifdef COMPAT_FREEBSD32
494
    pr->pr_pax_aslr_compat_status = pax_aslr_compat_status;
495
    pr->pr_pax_aslr_compat_mmap_len = pax_aslr_compat_mmap_len;
496
    pr->pr_pax_aslr_compat_stack_len = pax_aslr_compat_stack_len;
497
    pr->pr_pax_aslr_compat_exec_len = pax_aslr_compat_exec_len;
498
#endif /* COMPAT_FREEBSD32 */
499
500
    pr->pr_pax_set = 1;
501
}
502
503
void
504
pax_aslr_init(struct thread *td, struct image_params *imgp)
505
{
506
    struct vmspace *vm;
507
    u_int sv_flags;
508
    struct prison *pr=NULL;
509
510
    pr = pax_aslr_get_prison(td, NULL);
511
512
    if ((pr) && !(pr->pr_pax_set))
513
        pax_aslr_init_prison(pr);
514
515
    if (imgp == NULL) {
516
        panic("[PaX ASLR] pax_aslr_init - imgp == NULL");
517
    }
518
519
    if (!pax_aslr_active(td, NULL))
520
        return;
521
522
    vm = imgp->proc->p_vmspace;
523
    sv_flags = imgp->proc->p_sysent->sv_flags;
524
525
#ifndef COMPAT_FREEBSD32
526
    vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(),
527
        PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len);
528
    vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(),
529
        PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len);
530
    vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack);
531
    vm->vm_aslr_delta_exec = round_page(PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_EXEC_LSB, (pr != NULL) ? pr->pr_pax_aslr_exec_len : pax_aslr_exec_len));
532
#else /* COMPAT_FREEBSD32 */
533
    if ((sv_flags & SV_LP64) != 0) {
534
        vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(),
535
            PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len);
536
        vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(),
537
            PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len);
538
        vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack);
539
    } else {
540
        vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(),
541
            PAX_ASLR_COMPAT_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_mmap_len : pax_aslr_compat_mmap_len);
542
        vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(),
543
            PAX_ASLR_COMPAT_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len);
544
        vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack);
545
    }
546
#endif /* !COMPAT_FREEBSD32 */
547
}
548
549
void
550
pax_aslr_mmap(struct thread *td, vm_offset_t *addr, vm_offset_t orig_addr, int flags)
551
{
552
    struct prison *pr=NULL;
553
554
    pr = pax_aslr_get_prison(td, NULL);
555
556
    if (!pax_aslr_active(td, NULL))
557
        return;
558
559
    if (!(flags & MAP_FIXED) && ((orig_addr == 0) || !(flags & MAP_ANON))) {
560
        if (pax_aslr_debug)
561
            uprintf("[PaX ASLR] applying to %p orig_addr=%p f=%x\n",
562
                (void *)*addr, (void *)orig_addr, flags);
563
        if (!(td->td_proc->p_vmspace->vm_map.flags & MAP_ENTRY_GROWS_DOWN))
564
            *addr += td->td_proc->p_vmspace->vm_aslr_delta_mmap;
565
        else
566
            *addr -= td->td_proc->p_vmspace->vm_aslr_delta_mmap;
567
        if (pax_aslr_debug)
568
            uprintf("[PaX ASLR] result %p\n", (void *)*addr);
569
    }
570
    else if (pax_aslr_debug)
571
        uprintf("[PaX ASLR] not applying to %p orig_addr=%p f=%x\n",
572
        (void *)*addr, (void *)orig_addr, flags);
573
}
574
575
void
576
pax_aslr_stack(struct thread *td, char **addr, char *orig_addr)
577
{
578
    struct prison *pr=NULL;
579
580
    pr = pax_aslr_get_prison(td, NULL);
581
582
    if (!pax_aslr_active(td, NULL))
583
        return;
584
585
    *addr -= td->td_proc->p_vmspace->vm_aslr_delta_stack;
586
    if ((pr) && pr->pr_pax_aslr_debug)
587
        uprintf("[PaX ASLR] orig_addr=%p, addr=%p\n",
588
            (void *)orig_addr, (void *)*addr);
589
}
(-)b/sys/sys/jail.h (+14 lines)
Lines 184-189 struct prison { Link Here
184
	char		 pr_hostname[MAXHOSTNAMELEN];	/* (p) jail hostname */
184
	char		 pr_hostname[MAXHOSTNAMELEN];	/* (p) jail hostname */
185
	char		 pr_domainname[MAXHOSTNAMELEN];	/* (p) jail domainname */
185
	char		 pr_domainname[MAXHOSTNAMELEN];	/* (p) jail domainname */
186
	char		 pr_hostuuid[HOSTUUIDLEN];	/* (p) jail hostuuid */
186
	char		 pr_hostuuid[HOSTUUIDLEN];	/* (p) jail hostuuid */
187
#ifdef PAX_ASLR
188
    int pr_pax_set;
189
    int pr_pax_aslr_status;
190
    int pr_pax_aslr_debug;
191
    int pr_pax_aslr_mmap_len;
192
    int pr_pax_aslr_stack_len;
193
    int pr_pax_aslr_exec_len;
194
#endif /* PAX_ASLR */
195
#if defined(PAX_ASLR) && defined(COMPAT_FREEBSD32)
196
    int pr_pax_aslr_compat_status;
197
    int pr_pax_aslr_compat_mmap_len;
198
    int pr_pax_aslr_compat_stack_len;
199
    int pr_pax_aslr_compat_exec_len;
200
#endif /* COMPAT_FREEBSD32 */
187
};
201
};
188
202
189
struct prison_racct {
203
struct prison_racct {
(-)b/sys/sys/pax.h (+166 lines)
Added Link Here
1
/*-
2
 * Copyright (c) 2013, by Oliver Pinter <oliver.pntr at gmail.com>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. The name of the developer may NOT be used to endorse or promote products
11
 *    derived from this software without specific prior written permission.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
 * SUCH DAMAGE.
24
 *
25
 * $FreeBSD$
26
 *
27
 * Enhancements made by Shawn "lattera" Webb under the direction of SoldierX.
28
 */
29
30
#ifndef	__SYS_PAX_H
31
#define	__SYS_PAX_H
32
33
struct image_params;
34
struct thread;
35
struct vmspace;
36
struct vm_offset_t;
37
38
/*
39
 * used in sysctl handler
40
 */
41
#define	PAX_ASLR_DISABLED		0
42
#define PAX_ASLR_ENABLED		1
43
#define PAX_ASLR_GLOBAL_ENABLED		2
44
#define	PAX_ASLR_FORCE_GLOBAL_ENABLED	3
45
46
#ifndef PAX_ASLR_DELTA
47
#define	PAX_ASLR_DELTA(delta, lsb, len)	\
48
	(((delta) & ((1UL << (len)) - 1)) << (lsb))
49
#endif /* PAX_ASLR_DELTA */
50
51
#ifdef PAX_ASLR
52
/*
53
 * generic ASLR values
54
 *
55
 *  	MMAP	| 32 bit | 64 bit |
56
 * 	+-------+--------+--------+
57
 * 	| MIN	|  8 bit | 16 bit |
58
 * 	+-------+--------+--------+
59
 * 	| MAX   | 16 bit | 32 bit |
60
 * 	+-------+--------+--------+
61
 *
62
 *  	STACK	| 32 bit | 64 bit |
63
 * 	+-------+--------+--------+
64
 * 	| MIN	|  6 bit | 12 bit |
65
 * 	+-------+--------+--------+
66
 * 	| MAX   | 10 bit | 21 bit |
67
 * 	+-------+--------+--------+
68
 *
69
 *  	EXEC	| 32 bit | 64 bit |
70
 * 	+-------+--------+--------+
71
 * 	| MIN	|  6 bit | 12 bit |
72
 * 	+-------+--------+--------+
73
 * 	| MAX   | 10 bit | 21 bit |
74
 * 	+-------+--------+--------+
75
 *
76
 */
77
#ifndef PAX_ASLR_DELTA_MMAP_LSB
78
#define PAX_ASLR_DELTA_MMAP_LSB		PAGE_SHIFT
79
#endif /* PAX_ASLR_DELTA_MMAP_LSB */
80
81
#ifndef PAX_ASLR_DELTA_MMAP_MIN_LEN
82
#define PAX_ASLR_DELTA_MMAP_MIN_LEN	((sizeof(void *) * NBBY) / 4)
83
#endif /* PAX_ASLR_DELTA_MMAP_MAX_LEN */
84
85
#ifndef PAX_ASLR_DELTA_MMAP_MAX_LEN
86
#define PAX_ASLR_DELTA_MMAP_MAX_LEN	((sizeof(void *) * NBBY) / 2)
87
#endif /* PAX_ASLR_DELTA_MMAP_MAX_LEN */
88
89
#ifndef PAX_ASLR_DELTA_STACK_LSB
90
#define PAX_ASLR_DELTA_STACK_LSB	3
91
#endif /* PAX_ASLR_DELTA_STACK_LSB */
92
93
#ifndef PAX_ASLR_DELTA_STACK_MIN_LEN
94
#define PAX_ASLR_DELTA_STACK_MIN_LEN	((sizeof(void *) * NBBY) / 5)
95
#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */
96
97
#ifndef PAX_ASLR_DELTA_STACK_MAX_LEN
98
#define PAX_ASLR_DELTA_STACK_MAX_LEN	((sizeof(void *) * NBBY) / 3)
99
#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */
100
101
#ifndef PAX_ASLR_DELTA_EXEC_LSB
102
#define PAX_ASLR_DELTA_EXEC_LSB		PAGE_SHIFT
103
#endif /* PAX_ASLR_DELTA_EXEC_LSB */
104
105
#ifndef PAX_ASLR_DELTA_EXEC_MIN_LEN
106
#define PAX_ASLR_DELTA_EXEC_MIN_LEN	((sizeof(void *) * NBBY) / 5)
107
#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */
108
109
#ifndef PAX_ASLR_DELTA_EXEC_MAX_LEN
110
#define PAX_ASLR_DELTA_EXEC_MAX_LEN	((sizeof(void *) * NBBY) / 3)
111
#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */
112
113
/*
114
 * ASLR values for COMPAT_FREEBSD32 and COMPAT_LINUX
115
 */
116
#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_LSB
117
#define PAX_ASLR_COMPAT_DELTA_MMAP_LSB		PAGE_SHIFT
118
#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_LSB */
119
120
#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN
121
#define PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN	((sizeof(int) * NBBY) / 4)
122
#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN */
123
124
#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN
125
#define PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN	((sizeof(int) * NBBY) / 2)
126
#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN */
127
128
#ifndef PAX_ASLR_COMPAT_DELTA_STACK_LSB
129
#define PAX_ASLR_COMPAT_DELTA_STACK_LSB		3
130
#endif /* PAX_ASLR_COMPAT_DELTA_STACK_LSB */
131
132
#ifndef PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN
133
#define PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN	((sizeof(int) * NBBY) / 5)
134
#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */
135
136
#ifndef PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN
137
#define PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN	((sizeof(int) * NBBY) / 3)
138
#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */
139
140
#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN
141
#define PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN	((sizeof(int) * NBBY) / 5)
142
#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */
143
144
#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN
145
#define PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN	((sizeof(int) * NBBY) / 3)
146
#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */
147
148
extern int pax_aslr_status;
149
extern int pax_aslr_debug;
150
extern int pax_aslr_compat_status;
151
152
extern int pax_aslr_mmap_len;
153
extern int pax_aslr_stack_len;
154
extern int pax_aslr_exec_len;
155
#endif /* PAX_ASLR */
156
157
void pax_init(void);
158
void pax_aslr_init_prison(struct prison *pr);
159
bool pax_aslr_active(struct thread *td, struct proc *proc);
160
void pax_aslr_init(struct thread *td, struct image_params *imgp);
161
void pax_aslr_mmap(struct thread *td, vm_offset_t *addr,
162
			vm_offset_t orig_addr, int flags);
163
void pax_aslr_stack(struct thread *td, char **addr, char *orig_addr);
164
struct prison *pax_aslr_get_prison(struct thread *td, struct proc *proc);
165
166
#endif /* __SYS_PAX_H */
(-)b/sys/vm/vm_map.c (+6 lines)
Lines 65-70 Link Here
65
#include <sys/cdefs.h>
65
#include <sys/cdefs.h>
66
__FBSDID("$FreeBSD$");
66
__FBSDID("$FreeBSD$");
67
67
68
#include "opt_pax.h"
69
68
#include <sys/param.h>
70
#include <sys/param.h>
69
#include <sys/systm.h>
71
#include <sys/systm.h>
70
#include <sys/kernel.h>
72
#include <sys/kernel.h>
Lines 289-294 vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit) Link Here
289
	vm->vm_taddr = 0;
291
	vm->vm_taddr = 0;
290
	vm->vm_daddr = 0;
292
	vm->vm_daddr = 0;
291
	vm->vm_maxsaddr = 0;
293
	vm->vm_maxsaddr = 0;
294
#ifdef PAX_ASLR
295
	vm->vm_aslr_delta_mmap = 0;
296
	vm->vm_aslr_delta_stack = 0;
297
#endif /* PAX_ASLR */
292
	return (vm);
298
	return (vm);
293
}
299
}
294
300
(-)b/sys/vm/vm_map.h (+2 lines)
Lines 241-246 struct vmspace { Link Here
241
	caddr_t vm_taddr;	/* (c) user virtual address of text */
241
	caddr_t vm_taddr;	/* (c) user virtual address of text */
242
	caddr_t vm_daddr;	/* (c) user virtual address of data */
242
	caddr_t vm_daddr;	/* (c) user virtual address of data */
243
	caddr_t vm_maxsaddr;	/* user VA at max stack growth */
243
	caddr_t vm_maxsaddr;	/* user VA at max stack growth */
244
	vm_size_t vm_aslr_delta_mmap;	/* mmap() random delta for ASLR */
245
	vm_size_t vm_aslr_delta_stack;	/* stack random delta for ASLR */
244
	volatile int vm_refcnt;	/* number of references */
246
	volatile int vm_refcnt;	/* number of references */
245
	/*
247
	/*
246
	 * Keep the PMAP last, so that CPU-specific variations of that
248
	 * Keep the PMAP last, so that CPU-specific variations of that
(-)b/sys/vm/vm_mmap.c (-3 / +19 lines)
Lines 45-50 __FBSDID("$FreeBSD$"); Link Here
45
45
46
#include "opt_compat.h"
46
#include "opt_compat.h"
47
#include "opt_hwpmc_hooks.h"
47
#include "opt_hwpmc_hooks.h"
48
#include "opt_pax.h"
48
49
49
#include <sys/param.h>
50
#include <sys/param.h>
50
#include <sys/systm.h>
51
#include <sys/systm.h>
Lines 91-96 __FBSDID("$FreeBSD$"); Link Here
91
#include <sys/pmckern.h>
92
#include <sys/pmckern.h>
92
#endif
93
#endif
93
94
95
#ifdef PAX_ASLR
96
#include <sys/pax.h>
97
#endif /* PAX_ASLR */
98
94
int old_mlock = 0;
99
int old_mlock = 0;
95
SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW | CTLFLAG_TUN, &old_mlock, 0,
100
SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW | CTLFLAG_TUN, &old_mlock, 0,
96
    "Do not apply RLIMIT_MEMLOCK on mlockall");
101
    "Do not apply RLIMIT_MEMLOCK on mlockall");
Lines 203-208 sys_mmap(td, uap) Link Here
203
	struct file *fp;
208
	struct file *fp;
204
	struct vnode *vp;
209
	struct vnode *vp;
205
	vm_offset_t addr;
210
	vm_offset_t addr;
211
#ifdef PAX_ASLR
212
	vm_offset_t orig_addr;
213
#endif /* PAX_ASLR */
206
	vm_size_t size, pageoff;
214
	vm_size_t size, pageoff;
207
	vm_prot_t cap_maxprot, prot, maxprot;
215
	vm_prot_t cap_maxprot, prot, maxprot;
208
	void *handle;
216
	void *handle;
Lines 213-218 sys_mmap(td, uap) Link Here
213
	cap_rights_t rights;
221
	cap_rights_t rights;
214
222
215
	addr = (vm_offset_t) uap->addr;
223
	addr = (vm_offset_t) uap->addr;
224
#ifdef PAX_ASLR
225
	orig_addr = addr;
226
#endif /* PAX_ASLR */
216
	size = uap->len;
227
	size = uap->len;
217
	prot = uap->prot & VM_PROT_ALL;
228
	prot = uap->prot & VM_PROT_ALL;
218
	flags = uap->flags;
229
	flags = uap->flags;
Lines 309-317 sys_mmap(td, uap) Link Here
309
		if (addr == 0 ||
320
		if (addr == 0 ||
310
		    (addr >= round_page((vm_offset_t)vms->vm_taddr) &&
321
		    (addr >= round_page((vm_offset_t)vms->vm_taddr) &&
311
		    addr < round_page((vm_offset_t)vms->vm_daddr +
322
		    addr < round_page((vm_offset_t)vms->vm_daddr +
312
		    lim_max(td->td_proc, RLIMIT_DATA))))
323
		    lim_max(td->td_proc, RLIMIT_DATA)))) {
313
			addr = round_page((vm_offset_t)vms->vm_daddr +
324
                addr = round_page((vm_offset_t)vms->vm_daddr +
314
			    lim_max(td->td_proc, RLIMIT_DATA));
325
                    lim_max(td->td_proc, RLIMIT_DATA));
326
                addr = round_page(addr + (arc4random()&(256*1024*1024-1)));
327
        }
315
		PROC_UNLOCK(td->td_proc);
328
		PROC_UNLOCK(td->td_proc);
316
	}
329
	}
317
	if (flags & MAP_ANON) {
330
	if (flags & MAP_ANON) {
Lines 414-419 sys_mmap(td, uap) Link Here
414
map:
427
map:
415
	td->td_fpop = fp;
428
	td->td_fpop = fp;
416
	maxprot &= cap_maxprot;
429
	maxprot &= cap_maxprot;
430
#ifdef PAX_ASLR
431
	pax_aslr_mmap(td, &addr, orig_addr, flags);
432
#endif /* PAX_ASLR */
417
	error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
433
	error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
418
	    flags, handle_type, handle, pos);
434
	    flags, handle_type, handle, pos);
419
	td->td_fpop = NULL;
435
	td->td_fpop = NULL;

Return to bug 181497