Page MenuHomeFreeBSD

D21352.id61507.diff
No OneTemporary

D21352.id61507.diff

Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -3338,6 +3338,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));
@@ -3370,6 +3371,7 @@
break;
case PROC_ASLR_STATUS:
case PROC_PROTMAX_STATUS:
+ case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
data = &flags;
@@ -3400,6 +3402,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: sys/kern/kern_procctl.c
===================================================================
--- sys/kern/kern_procctl.c
+++ sys/kern/kern_procctl.c
@@ -520,6 +520,34 @@
return (0);
}
+static int
+stackgap_ctl(struct thread *td, struct proc *p, int state)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ switch (state) {
+ case PROC_STACKGAP_ENABLE:
+ p->p_flag2 &= ~P2_STKGAP_DISABLE;
+ break;
+ case PROC_STACKGAP_DISABLE:
+ p->p_flag2 |= P2_STKGAP_DISABLE;
+ 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;
+ return (0);
+}
+
#ifndef _SYS_SYSPROTO_H_
struct procctl_args {
idtype_t idtype;
@@ -548,6 +576,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 +607,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 +637,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 +667,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 +713,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 +763,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: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -762,6 +762,7 @@
#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 */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
Index: sys/sys/procctl.h
===================================================================
--- sys/sys/procctl.h
+++ 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)
@@ -134,6 +136,9 @@
#define PROC_PROTMAX_NOFORCE 3
#define PROC_PROTMAX_ACTIVE 0x80000000
+#define PROC_STACKGAP_ENABLE 1
+#define PROC_STACKGAP_DISABLE 2
+
#ifndef _KERNEL
__BEGIN_DECLS
int procctl(idtype_t, id_t, int, void *);
Index: sys/vm/vm_map.c
===================================================================
--- sys/vm/vm_map.c
+++ 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,22 +4184,25 @@
KASSERT((orient & MAP_STACK_GROWS_UP) == 0 ||
(new_entry->eflags & MAP_ENTRY_GROWS_UP) != 0,
("new entry lacks MAP_ENTRY_GROWS_UP"));
- 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));
- if (rv == KERN_SUCCESS) {
- /*
- * Gap can never successfully handle a fault, so
- * read-ahead logic is never used for it. Re-use
- * next_read of the gap entry to store
- * stack_guard_page for vm_map_growstack().
- */
- if (orient == MAP_STACK_GROWS_DOWN)
- new_entry->prev->next_read = sgp;
- else
- new_entry->next->next_read = sgp;
- } else {
- (void)vm_map_delete(map, bot, top);
+ if (gap_bot != gap_top) {
+ 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));
+ if (rv == KERN_SUCCESS) {
+ /*
+ * Gap can never successfully handle a fault, so
+ * read-ahead logic is never used for it. Re-use
+ * next_read of the gap entry to store
+ * stack_guard_page for vm_map_growstack().
+ */
+ if (orient == MAP_STACK_GROWS_DOWN)
+ new_entry->prev->next_read = sgp;
+ else
+ new_entry->next->next_read = sgp;
+ } else {
+ (void)vm_map_delete(map, bot, top);
+ }
}
return (rv);
}
@@ -4266,7 +4270,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);
Index: usr.bin/proccontrol/proccontrol.c
===================================================================
--- usr.bin/proccontrol/proccontrol.c
+++ usr.bin/proccontrol/proccontrol.c
@@ -44,6 +44,7 @@
MODE_TRACE,
MODE_TRAPCAP,
MODE_PROTMAX,
+ MODE_STACKGAP,
#ifdef PROC_KPTI_CTL
MODE_KPTI,
#endif
@@ -73,8 +74,8 @@
usage(void)
{
- fprintf(stderr, "Usage: proccontrol -m (aslr|protmax|trace|trapcap"
- KPTI_USAGE") [-q] "
+ fprintf(stderr, "Usage: proccontrol -m (aslr|protmax|trace|trapcap|"
+ "stackgap"KPTI_USAGE") [-q] "
"[-s (enable|disable)] [-p pid | command]\n");
exit(1);
}
@@ -101,6 +102,8 @@
mode = MODE_TRACE;
else if (strcmp(optarg, "trapcap") == 0)
mode = MODE_TRAPCAP;
+ else if (strcmp(optarg, "stackgap") == 0)
+ mode = MODE_STACKGAP;
#ifdef PROC_KPTI_CTL
else if (strcmp(optarg, "kpti") == 0)
mode = MODE_KPTI;
@@ -153,6 +156,9 @@
case MODE_PROTMAX:
error = procctl(P_PID, pid, PROC_PROTMAX_STATUS, &arg);
break;
+ case MODE_STACKGAP:
+ error = procctl(P_PID, pid, PROC_STACKGAP_STATUS, &arg);
+ break;
#ifdef PROC_KPTI_CTL
case MODE_KPTI:
error = procctl(P_PID, pid, PROC_KPTI_STATUS, &arg);
@@ -217,6 +223,16 @@
else
printf(", not active\n");
break;
+ case MODE_STACKGAP:
+ switch (arg) {
+ case PROC_STACKGAP_ENABLE:
+ printf("enabled\n");
+ break;
+ case PROC_STACKGAP_DISABLE:
+ printf("disabled\n");
+ break;
+ }
+ break;
#ifdef PROC_KPTI_CTL
case MODE_KPTI:
switch (arg & ~PROC_KPTI_STATUS_ACTIVE) {
@@ -256,6 +272,11 @@
PROC_PROTMAX_FORCE_DISABLE;
error = procctl(P_PID, pid, PROC_PROTMAX_CTL, &arg);
break;
+ case MODE_STACKGAP:
+ arg = enable ? PROC_STACKGAP_ENABLE :
+ PROC_STACKGAP_DISABLE;
+ error = procctl(P_PID, pid, PROC_STACKGAP_CTL, &arg);
+ break;
#ifdef PROC_KPTI_CTL
case MODE_KPTI:
arg = enable ? PROC_KPTI_CTL_ENABLE_ON_EXEC :

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 17, 10:03 PM (6 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27699859
Default Alt Text
D21352.id61507.diff (8 KB)

Event Timeline