All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: Siarhei Liakh <sliakh.lkml@gmail.com>
Cc: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	Arjan van de Ven <arjan@infradead.org>,
	James Morris <jmorris@namei.org>,
	Andrew Morton <akpm@linux-foundation.org>, Andi Kleen <ak@muc.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@elte.hu>
Subject: Re: [PATCH v3] RO/NX protection for loadable kernel modules
Date: Mon, 6 Jul 2009 10:43:09 +0930	[thread overview]
Message-ID: <200907061043.11793.rusty@rustcorp.com.au> (raw)
In-Reply-To: <817ecb6f0907051623l46ad93e9uc24d8d61669c938e@mail.gmail.com>

On Mon, 6 Jul 2009 08:53:56 am Siarhei Liakh wrote:
> This patch is a logical extension of the protection provided by
> CONFIG_DEBUG_RODATA to LKMs.

Hi Siarhei,

   Concept looks good, but needs a bit more de-macroing.

> +/* Modules' sections will be aligned on page boundaries
> + * to ensure complete separation of code and data */
> +#ifdef CONFIG_DEBUG_RODATA
> +#define ALIGN_MODULE_SECTION(SECTION, ALIGNMENT) \
> +	do { SECTION = ALIGN(SECTION, ALIGNMENT); } while (0)
> +#else
> +#define ALIGN_MODULE_SECTION(SECTION, ALIGNMENT) do { ; } while (0)
> +#endif
> +
> +/* Given a virtual address returns 1 if the address is page-aligned,
> + * 0 otherwise */
> +#define PAGE_ALIGNED(ADDR) (((unsigned long) ADDR & \
> +				((1UL << PAGE_SHIFT) - 1UL)) ? \
> +					(0) : (1))
> +
> +/* Given a virtual address returns a virtual page number
> + * that contains that address */
> +#define PAGE_NUMBER(ADDR) (((unsigned long) ADDR) >> PAGE_SHIFT)
> +
> +/* Given BASE and SIZE this macro calculates the number of pages the
> + * memory regions occupies */
> +#define NUMBER_OF_PAGES(BASE, SIZE) ((SIZE > 0) ?	\
> +		(PAGE_NUMBER(BASE + SIZE - 1) -		\
> +			 PAGE_NUMBER(BASE) + 1)		\
> +		: (0UL))
> +
> +/* This macro catches a section group with SEC_ID and records it's
> + * size into SEC_SIZE, aligning it (as well as SIZE) on page boundary
> + * if necessary */
> +#define CATCH_MODULE_SECTION(SEC_GROUP, SEC_ID, SEC_SIZE, SIZE)	\
> +	do {							\
> +		if (SEC_GROUP == SEC_ID) {			\
> +			/* align section size to a page */	\
> +			ALIGN_MODULE_SECTION(SIZE, PAGE_SIZE);	\
> +			/* set new module section size */	\
> +			SEC_SIZE = SIZE;			\
> +		}						\
> +	} while (0)

This is far clearer open-coded.  As a switch statement:

	switch (m) {
	case 0: /* executable */
		mod->core_text_size = debug_align(mod->core_text_size);
		mod->core_size = mod->core_text_size;
		break;
	case 1: /* RO data (executable code + RO data) */
		mod->core_ro_size = debug_align(mod->core_ro_size);
		mod->core_size = mod->core_ro_size;
		break;
	case 3: /* whole module (executable + RO data + RW data + small alloc) */
		mod->core_size = debug_align(mod->core_size);
		break;
	}

Later, we can create a nice struct to hold the section parts and merge the 
layout code between init and core loops.

> +/* Generic memory allocation for modules, since
> + * module_alloc() is platform-specific */
> +#define generic_module_alloc(size) module_alloc(size)
> +
> +/* Free memory returned from generic_module_alloc, since
> + * module_free() is platform-specific */
> +void generic_module_free(struct module *mod, void *module_region)

I don't like the gratuitous unused generic_module_alloc, nor the 
generic_module_free name.   Probably best to implement unset_section_ro_nx() 
and call it explicitly in the three places needed: two in free_module and one 
in sys_init_module.

> +/* LKM RO/NX protection: protect module's text/ro-data
> + * from modification and any data from execution.
> + * Siarhei Liakh, Xuxian Jiang  */
> +static void set_section_ro_nx(unsigned long base,
> +			unsigned long text_size,
> +			unsigned long ro_size,
> +			unsigned long total_size)

A void * first arg would make the callers not need to cast: does it make the 
implementation messier?  (Remember, gcc lets you do arithmetic on void * 
pointers).

Thanks!
Rusty.

  parent reply	other threads:[~2009-07-06  1:13 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-05 23:23 [PATCH v3] RO/NX protection for loadable kernel modules Siarhei Liakh
2009-07-06  0:03 ` Arjan van de Ven
2009-07-06  1:13 ` Rusty Russell [this message]
2009-07-08  0:47   ` [PATCH v4] " Siarhei Liakh
2009-07-08  5:06     ` Arjan van de Ven
2009-07-08 22:31       ` Siarhei Liakh
2009-07-11 11:49         ` Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200907061043.11793.rusty@rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=ak@muc.de \
    --cc=akpm@linux-foundation.org \
    --cc=arjan@infradead.org \
    --cc=hpa@zytor.com \
    --cc=jmorris@namei.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=sliakh.lkml@gmail.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.