tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: PaX: Heritage bug - Take 2
Updated diff
Index: kern/exec_elf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_elf.c,v
retrieving revision 1.75
diff -u -r1.75 exec_elf.c
--- kern/exec_elf.c 5 Aug 2015 15:58:01 -0000 1.75
+++ kern/exec_elf.c 6 Aug 2015 15:23:51 -0000
@@ -116,8 +116,7 @@
#define ELF_TRUNC(a, b) ((a) & ~((b) - 1))
static void
-elf_placedynexec(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh,
- Elf_Phdr *ph)
+elf_placedynexec(struct exec_package *epp, Elf_Ehdr *eh, Elf_Phdr *ph)
{
Elf_Addr align, offset;
int i;
@@ -127,7 +126,7 @@
align = ph[i].p_align;
#ifdef PAX_ASLR
- if (pax_aslr_active(l)) {
+ if (pax_aslr_epp_active(epp)) {
size_t pax_align, l2, delta;
uint32_t r;
@@ -717,12 +716,8 @@
pos = (Elf_Addr)startp;
}
-#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
- pax_setup_elf_flags(l, epp->ep_pax_flags);
-#endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */
-
if (is_dyn)
- elf_placedynexec(l, epp, eh, ph);
+ elf_placedynexec(epp, eh, ph);
/*
* Load all the necessary sections
@@ -947,8 +942,15 @@
np->n_descsz == ELF_NOTE_PAX_DESCSZ &&
memcmp(ndata, ELF_NOTE_PAX_NAME,
ELF_NOTE_PAX_NAMESZ) == 0) {
- memcpy(&epp->ep_pax_flags, ndesc,
- sizeof(epp->ep_pax_flags));
+ uint32_t flags;
+ memcpy(&flags, ndesc, sizeof(flags));
+#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
+ /* Convert the flags and insert them into
+ * the exec package. */
+ pax_setup_elf_flags(epp, flags);
+#else
+ (void)flags; /* UNUSED */
+#endif /* PAX_MPROTECT || PAX_SEGVGUARD || PAX_ASLR */
break;
}
BADNOTE("PaX tag");
Index: kern/exec_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_subr.c,v
retrieving revision 1.71
diff -u -r1.71 exec_subr.c
--- kern/exec_subr.c 29 Mar 2014 09:31:11 -0000 1.71
+++ kern/exec_subr.c 6 Aug 2015 15:23:51 -0000
@@ -408,7 +408,7 @@
max_stack_size);
#ifdef PAX_ASLR
- pax_aslr_stack(l, epp, &max_stack_size);
+ pax_aslr_stack(epp, &max_stack_size);
#endif /* PAX_ASLR */
l->l_proc->p_stackbase = epp->ep_minsaddr;
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.413
diff -u -r1.413 kern_exec.c
--- kern/kern_exec.c 31 Jul 2015 07:37:17 -0000 1.413
+++ kern/kern_exec.c 6 Aug 2015 15:23:51 -0000
@@ -705,9 +705,9 @@
*/
#ifdef PAX_ASLR
-#define ASLR_GAP(l) (pax_aslr_active(l) ? (cprng_fast32() % PAGE_SIZE) : 0)
+#define ASLR_GAP(epp) (pax_aslr_epp_active(epp) ? (cprng_fast32() %
PAGE_SIZE) : 0)
#else
-#define ASLR_GAP(l) 0
+#define ASLR_GAP(epp) 0
#endif
#ifdef __MACHINE_STACK_GROWS_UP
@@ -725,7 +725,7 @@
data->ed_argslen = calcargs(data, argenvstrlen);
- const size_t len = calcstack(data, ASLR_GAP(l) + RTLD_GAP);
+ const size_t len = calcstack(data, ASLR_GAP(epp) + RTLD_GAP);
if (len > epp->ep_ssize) {
/* in effect, compare to initial limit */
@@ -1097,6 +1097,9 @@
/* Remove POSIX timers */
timers_free(p, TIMERS_POSIX);
+ /* Set the PaX flags. */
+ p->p_pax = epp->ep_pax_flags;
+
/*
* Do whatever is necessary to prepare the address space
* for remapping. Note that this might replace the current
Index: kern/kern_pax.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_pax.c,v
retrieving revision 1.31
diff -u -r1.31 kern_pax.c
--- kern/kern_pax.c 4 Aug 2015 18:28:09 -0000 1.31
+++ kern/kern_pax.c 6 Aug 2015 15:23:51 -0000
@@ -285,7 +285,7 @@
}
void
-pax_setup_elf_flags(struct lwp *l, uint32_t elf_flags)
+pax_setup_elf_flags(struct exec_package *epp, uint32_t elf_flags)
{
uint32_t flags = 0;
@@ -305,7 +305,7 @@
}
#endif
- l->l_proc->p_pax = flags;
+ epp->ep_pax_flags = flags;
}
#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) || defined(PAX_ASLR)
@@ -372,6 +372,12 @@
}
bool
+pax_aslr_epp_active(struct exec_package *epp)
+{
+ return pax_flags_active(epp->ep_pax_flags, P_PAX_ASLR);
+}
+
+bool
pax_aslr_active(struct lwp *l)
{
return pax_flags_active(l->l_proc->p_pax, P_PAX_ASLR);
@@ -408,9 +414,9 @@
}
void
-pax_aslr_stack(struct lwp *l, struct exec_package *epp, u_long
*max_stack_size)
+pax_aslr_stack(struct exec_package *epp, u_long *max_stack_size)
{
- if (!pax_aslr_active(l))
+ if (!pax_aslr_epp_active(epp))
return;
u_long d = PAX_ASLR_DELTA(cprng_fast32(),
Index: sys/pax.h
===================================================================
RCS file: /cvsroot/src/sys/sys/pax.h,v
retrieving revision 1.14
diff -u -r1.14 pax.h
--- sys/pax.h 4 Aug 2015 18:28:10 -0000 1.14
+++ sys/pax.h 6 Aug 2015 15:23:51 -0000
@@ -50,7 +50,7 @@
#endif /* PAX_ASLR */
void pax_init(void);
-void pax_setup_elf_flags(struct lwp *, uint32_t);
+void pax_setup_elf_flags(struct exec_package *, uint32_t);
void pax_adjust(struct lwp *, uint32_t);
void pax_mprotect(struct lwp *, vm_prot_t *, vm_prot_t *);
@@ -58,9 +58,11 @@
#define PAX_ASLR_DELTA(delta, lsb, len) \
(((delta) & ((1UL << (len)) - 1)) << (lsb))
+
+bool pax_aslr_epp_active(struct exec_package *);
bool pax_aslr_active(struct lwp *);
void pax_aslr_init_vm(struct lwp *, struct vmspace *);
-void pax_aslr_stack(struct lwp *, struct exec_package *, u_long *);
+void pax_aslr_stack(struct exec_package *, u_long *);
void pax_aslr_mmap(struct lwp *, vaddr_t *, vaddr_t, int);
#endif /* !_SYS_PAX_H_ */
Le 03/08/2015 10:53, Maxime Villard a écrit :
> [I sent this mail some days ago, but it didn't reach tech-kern@.]
>
> http://marc.info/?l=netbsd-tech-kern&m=142486844004373&w=2
>
> Here is a new patch. Now, the PaX flag is converted and registered
> into the exec package by the loaders (only one loader does that, the
> native ELF). And right before launching the process, the flag is set
> in the proc structure - if it fails, the process is aborted, so this
> is not that bad. In the meantime, all the PaX operations read the
> exec package's flag instead of the LWP's.
>
> Important note, for the record:
> In exec_subr.c, exec_setup_stack() is called from the loaders, so it
> must read the exec package's flag. However, the other vmcmd_xx()
> functions are called when setting up the proc address space, which is
> done way later in execve_dovmcmds(); and they must therefore read the
> LWP's flag. A particular order must be followed:
> - The loaders set the exec package's PaX flag
> - The loaders call exec_setup_stack(), which does not require a PaX
> initialization. Which is perfectly fine, since nothing has been
> initialized for the moment.
> - Here, if the loaders return an error, the calling process's PaX
> flag is not overwritten.
> - Later, the proc's PaX flag is overwritten. It is set right after
> killing the LWPs associated to that proc, and right before calling
> pax_aslr_init_vm(). pax_aslr_init_vm() reads the proc's PaX flag,
> so that's fine.
> - Right after pax_aslr_init_vm(), execve_dovmcmds() is called, and
> reads the proc's PaX flag, and expects PaX to be initialized. Which
> is perfectly fine too.
> - So now everything is ok; and if the execution fails, the process is
> aborted.
>
> Please review this change before I commit it (if you understood
> something). Thanks.
>
Home |
Main Index |
Thread Index |
Old Index