Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105941909
D21352.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D21352.diff
View Options
Index: head/lib/libc/sys/procctl.2
===================================================================
--- head/lib/libc/sys/procctl.2
+++ head/lib/libc/sys/procctl.2
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 9, 2019
+.Dd August 31, 2019
.Dt PROCCTL 2
.Os
.Sh NAME
@@ -503,6 +503,67 @@
.Vt int .
If signal delivery has not been requested, it will contain zero
on return.
+.It Dv PROC_STACKGAP_CTL
+Controls the stack gaps in the specified process.
+A stack gap is the part of the growth area for a
+.Dv MAP_STACK
+mapped region that is reserved and never filled by memory.
+Instead, the process is guaranteed to receive a
+.Dv SIGSEGV
+signal on accessing pages in the gap.
+Gaps protect against stack overflow corrupting memory adjacent
+to the stack.
+.Pp
+The
+.Fa data
+argument must point to an integer variable containing flags.
+The following flags are allowed:
+.Bl -tag -width PROC_STACKGAP_DISABLE_EXEC
+.It Dv PROC_STACKGAP_ENABLE
+This flag is only accepted for consistency with
+.Dv PROC_STACKGAP_STATUS .
+If stack gaps are enabled, the flag is ignored.
+If disabled, the flag causes an
+.Ev EINVAL
+error to be returned.
+After gaps are disabled in a process, they can only be re-enabled when an
+.Xr execve 2
+is performed.
+.It Dv PROC_STACKGAP_DISABLE
+Disable stack gaps for the process.
+For existing stacks, the gap is no longer a reserved part of the growth
+area and can be filled by memory on access.
+.It Dv PROC_STACKGAP_ENABLE_EXEC
+Enable stack gaps for programs started after an
+.Xr execve 2
+by the specified process.
+.It Dv PROC_STACKGAP_DISABLE_EXEC
+Inherit disabled stack gaps state after
+.Xr execve 2 .
+In other words, if the currently executing program has stack gaps disabled,
+they are kept disabled on exec.
+If gaps were enabled, they are kept enabled after exec.
+.El
+.Pp
+The stack gap state is inherited from the parent on
+.Xr fork 2 .
+.It Dv PROC_STACKGAP_STATUS
+Returns the current stack gap state for the specified process.
+.Fa data
+must point to an integer variable, which is used to return a bitmask
+consisting of the following flags:
+.Bl -tag -width PROC_STACKGAP_DISABLE_EXEC
+.It Dv PROC_STACKGAP_ENABLE
+Stack gaps are enabled.
+.It Dv PROC_STACKGAP_DISABLE
+Stack gaps are disabled.
+.It Dv PROC_STACKGAP_ENABLE_EXEC
+Stack gaps are enabled in the process after
+.Xr execve 2 .
+.It Dv PROC_STACKGAP_DISABLE_EXEC
+Stack gaps are disabled in the process after
+.Xr execve 2 .
+.El
.El
.Sh NOTES
Disabling tracing on a process should not be considered a security
Index: head/sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c
+++ head/sys/compat/freebsd32/freebsd32_misc.c
@@ -3364,6 +3364,7 @@
case PROC_ASLR_CTL:
case PROC_PROTMAX_CTL:
case PROC_SPROTECT:
+ case PROC_STACKGAP_CTL:
case PROC_TRACE_CTL:
case PROC_TRAPCAP_CTL:
error = copyin(PTRIN(uap->data), &flags, sizeof(flags));
@@ -3396,6 +3397,7 @@
break;
case PROC_ASLR_STATUS:
case PROC_PROTMAX_STATUS:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
data = &flags;
@@ -3426,6 +3428,7 @@
break;
case PROC_ASLR_STATUS:
case PROC_PROTMAX_STATUS:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
if (error == 0)
Index: head/sys/kern/kern_exec.c
===================================================================
--- head/sys/kern/kern_exec.c
+++ head/sys/kern/kern_exec.c
@@ -745,6 +745,8 @@
p->p_flag |= P_EXEC;
if ((p->p_flag2 & P2_NOTRACE_EXEC) == 0)
p->p_flag2 &= ~P2_NOTRACE;
+ if ((p->p_flag2 & P2_STKGAP_DISABLE_EXEC) == 0)
+ p->p_flag2 &= ~P2_STKGAP_DISABLE;
if (p->p_flag & P_PPWAIT) {
p->p_flag &= ~(P_PPWAIT | P_PPTRACE);
cv_broadcast(&p->p_pwait);
Index: head/sys/kern/kern_fork.c
===================================================================
--- head/sys/kern/kern_fork.c
+++ head/sys/kern/kern_fork.c
@@ -460,7 +460,8 @@
p2->p_flag = P_INMEM;
p2->p_flag2 = p1->p_flag2 & (P2_ASLR_DISABLE | P2_ASLR_ENABLE |
P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC |
- P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP);
+ P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP |
+ P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC);
p2->p_swtick = ticks;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
Index: head/sys/kern/kern_procctl.c
===================================================================
--- head/sys/kern/kern_procctl.c
+++ head/sys/kern/kern_procctl.c
@@ -520,6 +520,55 @@
return (0);
}
+static int
+stackgap_ctl(struct thread *td, struct proc *p, int state)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ if ((state & ~(PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE |
+ PROC_STACKGAP_ENABLE_EXEC | PROC_STACKGAP_DISABLE_EXEC)) != 0)
+ return (EINVAL);
+ switch (state & (PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE)) {
+ case PROC_STACKGAP_ENABLE:
+ if ((p->p_flag2 & P2_STKGAP_DISABLE) != 0)
+ return (EINVAL);
+ break;
+ case PROC_STACKGAP_DISABLE:
+ p->p_flag2 |= P2_STKGAP_DISABLE;
+ break;
+ case 0:
+ break;
+ default:
+ return (EINVAL);
+ }
+ switch (state & (PROC_STACKGAP_ENABLE_EXEC |
+ PROC_STACKGAP_DISABLE_EXEC)) {
+ case PROC_STACKGAP_ENABLE_EXEC:
+ p->p_flag2 &= ~P2_STKGAP_DISABLE_EXEC;
+ break;
+ case PROC_STACKGAP_DISABLE_EXEC:
+ p->p_flag2 |= P2_STKGAP_DISABLE_EXEC;
+ break;
+ case 0:
+ break;
+ default:
+ return (EINVAL);
+ }
+ return (0);
+}
+
+static int
+stackgap_status(struct thread *td, struct proc *p, int *data)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ *data = (p->p_flag2 & P2_STKGAP_DISABLE) != 0 ? PROC_STACKGAP_DISABLE :
+ PROC_STACKGAP_ENABLE;
+ *data |= (p->p_flag2 & P2_STKGAP_DISABLE_EXEC) != 0 ?
+ PROC_STACKGAP_DISABLE_EXEC : PROC_STACKGAP_ENABLE_EXEC;
+ return (0);
+}
+
#ifndef _SYS_SYSPROTO_H_
struct procctl_args {
idtype_t idtype;
@@ -548,6 +597,7 @@
case PROC_ASLR_CTL:
case PROC_PROTMAX_CTL:
case PROC_SPROTECT:
+ case PROC_STACKGAP_CTL:
case PROC_TRACE_CTL:
case PROC_TRAPCAP_CTL:
error = copyin(uap->data, &flags, sizeof(flags));
@@ -578,6 +628,7 @@
break;
case PROC_ASLR_STATUS:
case PROC_PROTMAX_STATUS:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
data = &flags;
@@ -607,6 +658,7 @@
break;
case PROC_ASLR_STATUS:
case PROC_PROTMAX_STATUS:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
if (error == 0)
@@ -636,6 +688,10 @@
return (protmax_ctl(td, p, *(int *)data));
case PROC_PROTMAX_STATUS:
return (protmax_status(td, p, data));
+ case PROC_STACKGAP_CTL:
+ return (stackgap_ctl(td, p, *(int *)data));
+ case PROC_STACKGAP_STATUS:
+ return (stackgap_status(td, p, data));
case PROC_REAP_ACQUIRE:
return (reap_acquire(td, p));
case PROC_REAP_RELEASE:
@@ -678,6 +734,8 @@
case PROC_REAP_STATUS:
case PROC_REAP_GETPIDS:
case PROC_REAP_KILL:
+ case PROC_STACKGAP_CTL:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
case PROC_PDEATHSIG_CTL:
@@ -726,6 +784,8 @@
case PROC_ASLR_STATUS:
case PROC_PROTMAX_CTL:
case PROC_PROTMAX_STATUS:
+ case PROC_STACKGAP_CTL:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
tree_locked = false;
Index: head/sys/sys/proc.h
===================================================================
--- head/sys/sys/proc.h
+++ head/sys/sys/proc.h
@@ -762,6 +762,8 @@
#define P2_ASLR_IGNSTART 0x00000100 /* Enable ASLR to consume sbrk area. */
#define P2_PROTMAX_ENABLE 0x00000200 /* Force enable implied PROT_MAX. */
#define P2_PROTMAX_DISABLE 0x00000400 /* Force disable implied PROT_MAX. */
+#define P2_STKGAP_DISABLE 0x00000800 /* Disable stack gap for MAP_STACK */
+#define P2_STKGAP_DISABLE_EXEC 0x00001000 /* Stack gap disabled after exec */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
Index: head/sys/sys/procctl.h
===================================================================
--- head/sys/sys/procctl.h
+++ head/sys/sys/procctl.h
@@ -61,6 +61,8 @@
#define PROC_ASLR_STATUS 14 /* query ASLR status */
#define PROC_PROTMAX_CTL 15 /* en/dis implicit PROT_MAX */
#define PROC_PROTMAX_STATUS 16 /* query implicit PROT_MAX status */
+#define PROC_STACKGAP_CTL 17 /* en/dis stack gap on MAP_STACK */
+#define PROC_STACKGAP_STATUS 18 /* query stack gap */
/* Operations for PROC_SPROTECT (passed in integer arg). */
#define PPROT_OP(x) ((x) & 0xf)
@@ -133,6 +135,11 @@
#define PROC_PROTMAX_FORCE_DISABLE 2
#define PROC_PROTMAX_NOFORCE 3
#define PROC_PROTMAX_ACTIVE 0x80000000
+
+#define PROC_STACKGAP_ENABLE 0x0001
+#define PROC_STACKGAP_DISABLE 0x0002
+#define PROC_STACKGAP_ENABLE_EXEC 0x0004
+#define PROC_STACKGAP_DISABLE_EXEC 0x0008
#ifndef _KERNEL
__BEGIN_DECLS
Index: head/sys/vm/vm_map.c
===================================================================
--- head/sys/vm/vm_map.c
+++ head/sys/vm/vm_map.c
@@ -4132,7 +4132,8 @@
addrbos + max_ssize > vm_map_max(map) ||
addrbos + max_ssize <= addrbos)
return (KERN_INVALID_ADDRESS);
- sgp = (vm_size_t)stack_guard_page * PAGE_SIZE;
+ sgp = (curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 ? 0 :
+ (vm_size_t)stack_guard_page * PAGE_SIZE;
if (sgp >= max_ssize)
return (KERN_INVALID_ARGUMENT);
@@ -4183,6 +4184,8 @@
KASSERT((orient & MAP_STACK_GROWS_UP) == 0 ||
(new_entry->eflags & MAP_ENTRY_GROWS_UP) != 0,
("new entry lacks MAP_ENTRY_GROWS_UP"));
+ if (gap_bot == gap_top)
+ return (KERN_SUCCESS);
rv = vm_map_insert(map, NULL, 0, gap_bot, gap_top, VM_PROT_NONE,
VM_PROT_NONE, MAP_CREATE_GUARD | (orient == MAP_STACK_GROWS_DOWN ?
MAP_CREATE_STACK_GAP_DN : MAP_CREATE_STACK_GAP_UP));
@@ -4266,7 +4269,8 @@
} else {
return (KERN_FAILURE);
}
- guard = gap_entry->next_read;
+ guard = (curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 ? 0 :
+ gap_entry->next_read;
max_grow = gap_entry->end - gap_entry->start;
if (guard > max_grow)
return (KERN_NO_SPACE);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 23, 9:26 PM (19 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15580193
Default Alt Text
D21352.diff (9 KB)
Attached To
Mode
D21352: procctl(PROC_STACKGAP_CTL)
Attached
Detach File
Event Timeline
Log In to Comment