* [kernel-hardening] [PATCH] mark most percpu globals as __ro_after_init
@ 2017-05-10 17:36 Daniel Micay
2017-05-10 17:52 ` [kernel-hardening] " Tejun Heo
2017-05-10 18:16 ` [kernel-hardening] " Kees Cook
0 siblings, 2 replies; 7+ messages in thread
From: Daniel Micay @ 2017-05-10 17:36 UTC (permalink / raw)
To: Tejun Heo, Christoph Lameter; +Cc: Kees Cook, kernel-hardening, Daniel Micay
Moving pcpu_base_addr to this section comes from PaX where it's part of
KERNEXEC. This extends it to the rest of the globals only written by the
init code.
Signed-off-by: Daniel Micay <danielmicay@gmail.com>
---
mm/percpu.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/mm/percpu.c b/mm/percpu.c
index e0aa8ae7bde7..c03753054099 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -121,35 +121,35 @@ struct pcpu_chunk {
unsigned long populated[]; /* populated bitmap */
};
-static int pcpu_unit_pages __read_mostly;
-static int pcpu_unit_size __read_mostly;
-static int pcpu_nr_units __read_mostly;
-static int pcpu_atom_size __read_mostly;
-static int pcpu_nr_slots __read_mostly;
-static size_t pcpu_chunk_struct_size __read_mostly;
+static int pcpu_unit_pages __ro_after_init;
+static int pcpu_unit_size __ro_after_init;
+static int pcpu_nr_units __ro_after_init;
+static int pcpu_atom_size __ro_after_init;
+static int pcpu_nr_slots __ro_after_init;
+static size_t pcpu_chunk_struct_size __ro_after_init;
/* cpus with the lowest and highest unit addresses */
-static unsigned int pcpu_low_unit_cpu __read_mostly;
-static unsigned int pcpu_high_unit_cpu __read_mostly;
+static unsigned int pcpu_low_unit_cpu __ro_after_init;
+static unsigned int pcpu_high_unit_cpu __ro_after_init;
/* the address of the first chunk which starts with the kernel static area */
-void *pcpu_base_addr __read_mostly;
+void *pcpu_base_addr __ro_after_init;
EXPORT_SYMBOL_GPL(pcpu_base_addr);
-static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */
-const unsigned long *pcpu_unit_offsets __read_mostly; /* cpu -> unit offset */
+static const int *pcpu_unit_map __ro_after_init; /* cpu -> unit */
+const unsigned long *pcpu_unit_offsets __ro_after_init; /* cpu -> unit offset */
/* group information, used for vm allocation */
-static int pcpu_nr_groups __read_mostly;
-static const unsigned long *pcpu_group_offsets __read_mostly;
-static const size_t *pcpu_group_sizes __read_mostly;
+static int pcpu_nr_groups __ro_after_init;
+static const unsigned long *pcpu_group_offsets __ro_after_init;
+static const size_t *pcpu_group_sizes __ro_after_init;
/*
* The first chunk which always exists. Note that unlike other
* chunks, this one can be allocated and mapped in several different
* ways and thus often doesn't live in the vmalloc area.
*/
-static struct pcpu_chunk *pcpu_first_chunk;
+static struct pcpu_chunk *pcpu_first_chunk __ro_after_init;
/*
* Optional reserved chunk. This chunk reserves part of the first
@@ -158,13 +158,13 @@ static struct pcpu_chunk *pcpu_first_chunk;
* area doesn't exist, the following variables contain NULL and 0
* respectively.
*/
-static struct pcpu_chunk *pcpu_reserved_chunk;
-static int pcpu_reserved_chunk_limit;
+static struct pcpu_chunk *pcpu_reserved_chunk __ro_after_init;
+static int pcpu_reserved_chunk_limit __ro_after_init;
static DEFINE_SPINLOCK(pcpu_lock); /* all internal data structures */
static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext */
-static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
+static struct list_head *pcpu_slot __ro_after_init; /* chunk list slots */
/* chunks which need their map areas extended, protected by pcpu_lock */
static LIST_HEAD(pcpu_map_extend_chunks);
--
2.12.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [kernel-hardening] Re: [PATCH] mark most percpu globals as __ro_after_init
2017-05-10 17:36 [kernel-hardening] [PATCH] mark most percpu globals as __ro_after_init Daniel Micay
@ 2017-05-10 17:52 ` Tejun Heo
2017-05-10 17:59 ` Daniel Micay
2017-05-10 18:16 ` [kernel-hardening] " Kees Cook
1 sibling, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2017-05-10 17:52 UTC (permalink / raw)
To: Daniel Micay; +Cc: Christoph Lameter, Kees Cook, kernel-hardening
Hello, Daniel.
On Wed, May 10, 2017 at 01:36:37PM -0400, Daniel Micay wrote:
> Moving pcpu_base_addr to this section comes from PaX where it's part of
> KERNEXEC. This extends it to the rest of the globals only written by the
> init code.
How did you test the patch?
> -static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
> +static struct list_head *pcpu_slot __ro_after_init; /* chunk list slots */
At least this one isn't read only.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 7+ messages in thread
* [kernel-hardening] Re: [PATCH] mark most percpu globals as __ro_after_init
2017-05-10 17:52 ` [kernel-hardening] " Tejun Heo
@ 2017-05-10 17:59 ` Daniel Micay
2017-05-10 18:31 ` Daniel Micay
2017-05-10 19:20 ` Tejun Heo
0 siblings, 2 replies; 7+ messages in thread
From: Daniel Micay @ 2017-05-10 17:59 UTC (permalink / raw)
To: Tejun Heo; +Cc: Christoph Lameter, Kees Cook, kernel-hardening
On Wed, 2017-05-10 at 13:52 -0400, Tejun Heo wrote:
> Hello, Daniel.
>
> On Wed, May 10, 2017 at 01:36:37PM -0400, Daniel Micay wrote:
> > Moving pcpu_base_addr to this section comes from PaX where it's part
> > of
> > KERNEXEC. This extends it to the rest of the globals only written by
> > the
> > init code.
>
> How did you test the patch?
Booted / did some stuff on x86 (it's running right now), and currently
building it for a 3.18 arm64 kernel to test there.
>
> > -static struct list_head *pcpu_slot __read_mostly; /* chunk list
> > slots */
> > +static struct list_head *pcpu_slot __ro_after_init; /* chunk list
> > slots */
>
> At least this one isn't read only.
It's the array it points to being modified after it gets assigned to
during init with pcpu_slot = memblock_virt_alloc(...), not the pointer
variable itself. The references after init are all pcpu_slot[...]
including taking references to slots in the array so there's always a
dereference happening first.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mark most percpu globals as __ro_after_init
2017-05-10 17:36 [kernel-hardening] [PATCH] mark most percpu globals as __ro_after_init Daniel Micay
@ 2017-05-10 18:16 ` Kees Cook
2017-05-10 18:16 ` [kernel-hardening] " Kees Cook
1 sibling, 0 replies; 7+ messages in thread
From: Kees Cook @ 2017-05-10 18:16 UTC (permalink / raw)
To: Daniel Micay, Andrew Morton
Cc: Tejun Heo, Christoph Lameter, kernel-hardening, LKML
On Wed, May 10, 2017 at 10:36 AM, Daniel Micay <danielmicay@gmail.com> wrote:
> Moving pcpu_base_addr to this section comes from PaX where it's part of
> KERNEXEC. This extends it to the rest of the globals only written by the
> init code.
>
> Signed-off-by: Daniel Micay <danielmicay@gmail.com>
Excellent, thanks!
Acked-by: Kees Cook <keescook@chromium.org>
-Kees
> ---
> mm/percpu.c | 36 ++++++++++++++++++------------------
> 1 file changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/mm/percpu.c b/mm/percpu.c
> index e0aa8ae7bde7..c03753054099 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -121,35 +121,35 @@ struct pcpu_chunk {
> unsigned long populated[]; /* populated bitmap */
> };
>
> -static int pcpu_unit_pages __read_mostly;
> -static int pcpu_unit_size __read_mostly;
> -static int pcpu_nr_units __read_mostly;
> -static int pcpu_atom_size __read_mostly;
> -static int pcpu_nr_slots __read_mostly;
> -static size_t pcpu_chunk_struct_size __read_mostly;
> +static int pcpu_unit_pages __ro_after_init;
> +static int pcpu_unit_size __ro_after_init;
> +static int pcpu_nr_units __ro_after_init;
> +static int pcpu_atom_size __ro_after_init;
> +static int pcpu_nr_slots __ro_after_init;
> +static size_t pcpu_chunk_struct_size __ro_after_init;
>
> /* cpus with the lowest and highest unit addresses */
> -static unsigned int pcpu_low_unit_cpu __read_mostly;
> -static unsigned int pcpu_high_unit_cpu __read_mostly;
> +static unsigned int pcpu_low_unit_cpu __ro_after_init;
> +static unsigned int pcpu_high_unit_cpu __ro_after_init;
>
> /* the address of the first chunk which starts with the kernel static area */
> -void *pcpu_base_addr __read_mostly;
> +void *pcpu_base_addr __ro_after_init;
> EXPORT_SYMBOL_GPL(pcpu_base_addr);
>
> -static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */
> -const unsigned long *pcpu_unit_offsets __read_mostly; /* cpu -> unit offset */
> +static const int *pcpu_unit_map __ro_after_init; /* cpu -> unit */
> +const unsigned long *pcpu_unit_offsets __ro_after_init; /* cpu -> unit offset */
>
> /* group information, used for vm allocation */
> -static int pcpu_nr_groups __read_mostly;
> -static const unsigned long *pcpu_group_offsets __read_mostly;
> -static const size_t *pcpu_group_sizes __read_mostly;
> +static int pcpu_nr_groups __ro_after_init;
> +static const unsigned long *pcpu_group_offsets __ro_after_init;
> +static const size_t *pcpu_group_sizes __ro_after_init;
>
> /*
> * The first chunk which always exists. Note that unlike other
> * chunks, this one can be allocated and mapped in several different
> * ways and thus often doesn't live in the vmalloc area.
> */
> -static struct pcpu_chunk *pcpu_first_chunk;
> +static struct pcpu_chunk *pcpu_first_chunk __ro_after_init;
>
> /*
> * Optional reserved chunk. This chunk reserves part of the first
> @@ -158,13 +158,13 @@ static struct pcpu_chunk *pcpu_first_chunk;
> * area doesn't exist, the following variables contain NULL and 0
> * respectively.
> */
> -static struct pcpu_chunk *pcpu_reserved_chunk;
> -static int pcpu_reserved_chunk_limit;
> +static struct pcpu_chunk *pcpu_reserved_chunk __ro_after_init;
> +static int pcpu_reserved_chunk_limit __ro_after_init;
>
> static DEFINE_SPINLOCK(pcpu_lock); /* all internal data structures */
> static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext */
>
> -static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
> +static struct list_head *pcpu_slot __ro_after_init; /* chunk list slots */
>
> /* chunks which need their map areas extended, protected by pcpu_lock */
> static LIST_HEAD(pcpu_map_extend_chunks);
> --
> 2.12.2
>
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 7+ messages in thread
* [kernel-hardening] Re: [PATCH] mark most percpu globals as __ro_after_init
@ 2017-05-10 18:16 ` Kees Cook
0 siblings, 0 replies; 7+ messages in thread
From: Kees Cook @ 2017-05-10 18:16 UTC (permalink / raw)
To: Daniel Micay, Andrew Morton
Cc: Tejun Heo, Christoph Lameter, kernel-hardening, LKML
On Wed, May 10, 2017 at 10:36 AM, Daniel Micay <danielmicay@gmail.com> wrote:
> Moving pcpu_base_addr to this section comes from PaX where it's part of
> KERNEXEC. This extends it to the rest of the globals only written by the
> init code.
>
> Signed-off-by: Daniel Micay <danielmicay@gmail.com>
Excellent, thanks!
Acked-by: Kees Cook <keescook@chromium.org>
-Kees
> ---
> mm/percpu.c | 36 ++++++++++++++++++------------------
> 1 file changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/mm/percpu.c b/mm/percpu.c
> index e0aa8ae7bde7..c03753054099 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -121,35 +121,35 @@ struct pcpu_chunk {
> unsigned long populated[]; /* populated bitmap */
> };
>
> -static int pcpu_unit_pages __read_mostly;
> -static int pcpu_unit_size __read_mostly;
> -static int pcpu_nr_units __read_mostly;
> -static int pcpu_atom_size __read_mostly;
> -static int pcpu_nr_slots __read_mostly;
> -static size_t pcpu_chunk_struct_size __read_mostly;
> +static int pcpu_unit_pages __ro_after_init;
> +static int pcpu_unit_size __ro_after_init;
> +static int pcpu_nr_units __ro_after_init;
> +static int pcpu_atom_size __ro_after_init;
> +static int pcpu_nr_slots __ro_after_init;
> +static size_t pcpu_chunk_struct_size __ro_after_init;
>
> /* cpus with the lowest and highest unit addresses */
> -static unsigned int pcpu_low_unit_cpu __read_mostly;
> -static unsigned int pcpu_high_unit_cpu __read_mostly;
> +static unsigned int pcpu_low_unit_cpu __ro_after_init;
> +static unsigned int pcpu_high_unit_cpu __ro_after_init;
>
> /* the address of the first chunk which starts with the kernel static area */
> -void *pcpu_base_addr __read_mostly;
> +void *pcpu_base_addr __ro_after_init;
> EXPORT_SYMBOL_GPL(pcpu_base_addr);
>
> -static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */
> -const unsigned long *pcpu_unit_offsets __read_mostly; /* cpu -> unit offset */
> +static const int *pcpu_unit_map __ro_after_init; /* cpu -> unit */
> +const unsigned long *pcpu_unit_offsets __ro_after_init; /* cpu -> unit offset */
>
> /* group information, used for vm allocation */
> -static int pcpu_nr_groups __read_mostly;
> -static const unsigned long *pcpu_group_offsets __read_mostly;
> -static const size_t *pcpu_group_sizes __read_mostly;
> +static int pcpu_nr_groups __ro_after_init;
> +static const unsigned long *pcpu_group_offsets __ro_after_init;
> +static const size_t *pcpu_group_sizes __ro_after_init;
>
> /*
> * The first chunk which always exists. Note that unlike other
> * chunks, this one can be allocated and mapped in several different
> * ways and thus often doesn't live in the vmalloc area.
> */
> -static struct pcpu_chunk *pcpu_first_chunk;
> +static struct pcpu_chunk *pcpu_first_chunk __ro_after_init;
>
> /*
> * Optional reserved chunk. This chunk reserves part of the first
> @@ -158,13 +158,13 @@ static struct pcpu_chunk *pcpu_first_chunk;
> * area doesn't exist, the following variables contain NULL and 0
> * respectively.
> */
> -static struct pcpu_chunk *pcpu_reserved_chunk;
> -static int pcpu_reserved_chunk_limit;
> +static struct pcpu_chunk *pcpu_reserved_chunk __ro_after_init;
> +static int pcpu_reserved_chunk_limit __ro_after_init;
>
> static DEFINE_SPINLOCK(pcpu_lock); /* all internal data structures */
> static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext */
>
> -static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
> +static struct list_head *pcpu_slot __ro_after_init; /* chunk list slots */
>
> /* chunks which need their map areas extended, protected by pcpu_lock */
> static LIST_HEAD(pcpu_map_extend_chunks);
> --
> 2.12.2
>
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 7+ messages in thread
* [kernel-hardening] Re: [PATCH] mark most percpu globals as __ro_after_init
2017-05-10 17:59 ` Daniel Micay
@ 2017-05-10 18:31 ` Daniel Micay
2017-05-10 19:20 ` Tejun Heo
1 sibling, 0 replies; 7+ messages in thread
From: Daniel Micay @ 2017-05-10 18:31 UTC (permalink / raw)
To: Tejun Heo; +Cc: Christoph Lameter, Kees Cook, kernel-hardening
> Booted / did some stuff on x86 (it's running right now), and currently
> building it for a 3.18 arm64 kernel to test there.
Yeah, confirmed to work on an Android 3.18 arm64 kernel (Pixel phone)
too in addition to 4.11 and master for x86_64.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [kernel-hardening] Re: [PATCH] mark most percpu globals as __ro_after_init
2017-05-10 17:59 ` Daniel Micay
2017-05-10 18:31 ` Daniel Micay
@ 2017-05-10 19:20 ` Tejun Heo
1 sibling, 0 replies; 7+ messages in thread
From: Tejun Heo @ 2017-05-10 19:20 UTC (permalink / raw)
To: Daniel Micay; +Cc: Christoph Lameter, Kees Cook, kernel-hardening
On Wed, May 10, 2017 at 01:59:32PM -0400, Daniel Micay wrote:
> On Wed, 2017-05-10 at 13:52 -0400, Tejun Heo wrote:
> > Hello, Daniel.
> >
> > On Wed, May 10, 2017 at 01:36:37PM -0400, Daniel Micay wrote:
> > > Moving pcpu_base_addr to this section comes from PaX where it's part
> > > of
> > > KERNEXEC. This extends it to the rest of the globals only written by
> > > the
> > > init code.
> >
> > How did you test the patch?
>
> Booted / did some stuff on x86 (it's running right now), and currently
> building it for a 3.18 arm64 kernel to test there.
>
> >
> > > -static struct list_head *pcpu_slot __read_mostly; /* chunk list
> > > slots */
> > > +static struct list_head *pcpu_slot __ro_after_init; /* chunk list
> > > slots */
> >
> > At least this one isn't read only.
>
> It's the array it points to being modified after it gets assigned to
> during init with pcpu_slot = memblock_virt_alloc(...), not the pointer
> variable itself. The references after init are all pcpu_slot[...]
> including taking references to slots in the array so there's always a
> dereference happening first.
Ah, right. Cool, applying to percpu/for-4.13.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-05-10 19:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10 17:36 [kernel-hardening] [PATCH] mark most percpu globals as __ro_after_init Daniel Micay
2017-05-10 17:52 ` [kernel-hardening] " Tejun Heo
2017-05-10 17:59 ` Daniel Micay
2017-05-10 18:31 ` Daniel Micay
2017-05-10 19:20 ` Tejun Heo
2017-05-10 18:16 ` Kees Cook
2017-05-10 18:16 ` [kernel-hardening] " Kees Cook
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.