All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yu-cheng Yu <yu-cheng.yu@intel.com>
To: Kees Cook <keescook@chromium.org>, Andy Lutomirski <luto@amacapital.net>
Cc: X86 ML <x86@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>,
	"open list:DOCUMENTATION" <linux-doc@vger.kernel.org>,
	Linux-MM <linux-mm@kvack.org>,
	linux-arch <linux-arch@vger.kernel.org>,
	Linux API <linux-api@vger.kernel.org>,
	Arnd Bergmann <arnd@arndb.de>,
	Balbir Singh <bsingharora@gmail.com>,
	Cyrill Gorcunov <gorcunov@gmail.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Florian Weimer <fweimer@redhat.com>,
	"H.J. Lu" <hjl.tools@gmail.com>, Jann Horn <jannh@google.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Mike Kravetz <mike.kravetz@oracle.com>,
	Nadav Amit <nadav.amit@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>, Pavel Machek <pavel@ucw.cz>,
	Peter Zijlstra <peterz@infradead.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	"Ravi V. Shankar" <ravi.v.shankar@intel.com>,
	Vedvyas Shanbhogue <vedvyas.shanbhogue@intel.com>
Subject: Re: [RFC PATCH v4 21/27] x86/cet/shstk: ELF header parsing of Shadow Stack
Date: Tue, 16 Oct 2018 10:23:43 -0700	[thread overview]
Message-ID: <124c1c2805286c70a9b2cc8e4b0abad7ef997ed4.camel@intel.com> (raw)
In-Reply-To: <CAGXu5jKO5Ot5VAJBMHudgx40g4N2tqhLKHeCdS7rkFj1bPaHig@mail.gmail.com>

On Mon, 2018-10-15 at 16:40 -0700, Kees Cook wrote:
> On Fri, Sep 21, 2018 at 8:03 AM, Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
> > Look in .note.gnu.property of an ELF file and check if Shadow Stack needs
> > to be enabled for the task.

[...]

> > +/*
> > + * The .note.gnu.property layout:
> > + *
> > + *     struct elf_note {
> > + *             u32 n_namesz; --> sizeof(n_name[]); always (4)
> > + *             u32 n_ndescsz;--> sizeof(property[])
> > + *             u32 n_type;   --> always NT_GNU_PROPERTY_TYPE_0
> > + *     };
> > + *     char n_name[4]; --> always 'GNU\0'
> > + *
> > + *     struct {
> > + *             struct property_x86 {
> > + *                     u32 pr_type;
> > + *                     u32 pr_datasz;
> > + *             };
> > + *             u8 pr_data[pr_datasz];
> > + *     }[];
> > + */
> 
> Does NT_GNU_PROPERTY_TYPE_0 only ever contain property_x86 bytes? (I
> assume not, since there is a pr_type?)

There are other property types, but we only look for NT_GNU_PROPERTY_TYPE_0.

> > +
> > +#define BUF_SIZE (PAGE_SIZE / 4)
> > +
> > +struct property_x86 {
> > +       u32 pr_type;
> > +       u32 pr_datasz;
> > +};
> > +
> > +typedef bool (test_fn)(void *buf, u32 *arg);
> > +typedef void *(next_fn)(void *buf, u32 *arg);
> > +
> > +static inline bool test_note_type_0(void *buf, u32 *arg)
> > +{
> > +       struct elf_note *n = buf;
> > +
> > +       return ((n->n_namesz == 4) && (memcmp(n + 1, "GNU", 4) == 0) &&
> > +               (n->n_type == NT_GNU_PROPERTY_TYPE_0));
> 
> Cheaper to test n_type first...

Yes, Thanks!

> 
> > +}
> > +
> > +static inline void *next_note(void *buf, u32 *arg)
> > +{
> > +       struct elf_note *n = buf;
> > +       u32 align = *arg;
> > +       int size;
> > +
> > +       size = round_up(sizeof(*n) + n->n_namesz, align);
> 
> I think this could overflow: n_namesz can be u64 for elf64_note.
> 
> > +       size = round_up(size + n->n_descsz, align);
> 
> Same here. You may want to use check_add_overflow(), etc, an u64 types.

Note->n_namesz is always four-byte.  I should have used u32.

> 
> > +
> > +       if (buf + size < buf)
> > +               return NULL;
> 
> I don't understand this. You want to check size not exceeding the
> allocation, which isn't passed into this function. Checking for a full
> unsigned address wrap around is not sufficient to detect overflow.

Here we only detect the warp around.  After this returns we then check other
types of overflow in scan().

> 
> > +       else
> > +               return (buf + size);
> > +}
> > +
> > +static inline bool test_property_x86(void *buf, u32 *arg)
> > +{
> > +       struct property_x86 *pr = buf;
> > +       u32 max_type = *arg;
> > +
> > +       if (pr->pr_type > max_type)
> > +               *arg = pr->pr_type;
> 
> Why is *arg being updated? I don't see last_pr used outside of here --
> are properties required to be pr_type-ordered?

Yes, they need to be in ascending order.

> 
> > +
> > +       return (pr->pr_type == GNU_PROPERTY_X86_FEATURE_1_AND);
> > +}
> > +
> > +static inline void *next_property(void *buf, u32 *arg)
> > +{
> > +       struct property_x86 *pr = buf;
> > +       u32 max_type = *arg;
> > +
> > +       if ((buf + sizeof(*pr) +  pr->pr_datasz < buf) ||
> 
> Again, this "< buf" test doesn't look at all correct to me.
> 
> > +           (pr->pr_type > GNU_PROPERTY_X86_FEATURE_1_AND) ||
> > +           (pr->pr_type > max_type))
> > +               return NULL;
> > +       else
> > +               return (buf + sizeof(*pr) + pr->pr_datasz);
> > +}
> > +
> > +/*
> > + * Scan 'buf' for a pattern; return true if found.
> > + * *pos is the distance from the beginning of buf to where
> > + * the searched item or the next item is located.
> > + */
> > +static int scan(u8 *buf, u32 buf_size, int item_size,
> > +                test_fn test, next_fn next, u32 *arg, u32 *pos)
> 
> I'm not a fan of the short "scan", "test" and "next" names, and I
> really don't like an arg named "arg". Something slightly more
> descriptive for all of these would be nice, please.

I need to work on that :-)  What would you suggest?

> 
> > +{
> > +       int found = 0;
> > +       u8 *p, *max;
> > +
> > +       max = buf + buf_size;
> > +       if (max < buf)
> > +               return 0;
> > +
> > +       p = buf;
> > +
> > +       while ((p + item_size < max) && (p + item_size > buf)) {
> 
> These comparisons are safe due to the BUF_SIZE limit of buf_size and
> the only used size of item_size, but if this becomes more generic, it
> should be more defensive on the size calculations (e.g. make sure than
> "item_size < max" and then here "p < max - item_size", etc).
> 
> I'd kind of rather this code walked the base type and check each for
> the matching feature. What is the general specification for what
> NT_GNU_PROPERTY_TYPE_0 contains?

There are other property types, but the kernel does not look at most of them.
If the kernel needs to look at others, we need to rewrite this.

[...]

> > +
> > +/*
> > + * Search a PT_NOTE segment for the first NT_GNU_PROPERTY_TYPE_0.
> > + */
> > +static int find_note_type_0(struct file *file, unsigned long note_size,
> > +                           loff_t file_offset, u32 align, u32 *feature)
> > +{
> > +       u8 *buf;
> > +       u32 buf_pos;
> > +       unsigned long read_size;
> > +       unsigned long done;
> > +       int found = 0;
> > +       int ret = 0;
> > +
> > +       buf = kmalloc(BUF_SIZE, GFP_KERNEL);
> > +       if (!buf)
> > +               return -ENOMEM;
> 
> Why kmalloc over stack variable? (Or, does BUF_SIZE here really need
> to be 1024?)

BUF_SIZE can be smaller, for example 64.  If it is too small, we need to do
kernel_read() too often.

> 
> > +
> > +       *feature = 0;
> > +       buf_pos = 0;
> > +
> > +       for (done = 0; done < note_size; done += buf_pos) {
> > +               read_size = note_size - done;
> > +               if (read_size > BUF_SIZE)
> > +                       read_size = BUF_SIZE;
> > +
> > +               ret = kernel_read(file, buf, read_size, &file_offset);
> > +
> > +               if (ret != read_size) {
> > +                       ret = (ret < 0) ? ret : -EIO;
> > +                       kfree(buf);
> > +                       return ret;
> > +               }
> > +
> > +               /*
> > +                * item_size = sizeof(struct elf_note) + elf_note.n_namesz.
> > +                * n_namesz is 4 for the note type we look for.
> > +                */
> > +               ret = 0;
> > +               found += scan(buf, read_size, sizeof(struct elf_note) + 4,
> > +                             test_note_type_0, next_note,
> > +                             &align, &buf_pos);
> > +
> > +               file_offset += buf_pos - read_size;
> > +
> > +               if (found == 1) {
> > +                       struct elf_note *n =
> > +                               (struct elf_note *)(buf + buf_pos);
> > +                       u32 start = round_up(sizeof(*n) + n->n_namesz,
> > align);
> > +                       u32 total = round_up(start + n->n_descsz, align);
> 
> Same overflow notes from earlier...
> 
> > +
> > +                       ret = find_feature_x86(file, n->n_descsz,
> > +                                              file_offset + start,
> > +                                              buf, feature);
> > +                       file_offset += total;
> > +                       buf_pos += total;
> > +               } else if (!buf_pos) {
> > +                       *feature = 0;
> > +                       break;
> > +               }
> > +       }
> > +
> > +       kfree(buf);
> > +       return ret;
> > +}
> > +
> > +#ifdef CONFIG_COMPAT
> > +static int check_notes_32(struct file *file, struct elf32_phdr *phdr,
> > +                         int phnum, u32 *feature)
> > +{
> > +       int i;
> > +       int err = 0;
> > +
> > +       for (i = 0; i < phnum; i++, phdr++) {
> > +               if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 4))
> > +                       continue;
> > +
> > +               err = find_note_type_0(file, phdr->p_filesz, phdr->p_offset,
> > +                                      phdr->p_align, feature);
> > +               if (err)
> > +                       return err;
> > +       }
> > +
> > +       return 0;
> > +}
> > +#endif
> > +
> > +#ifdef CONFIG_X86_64
> > +static int check_notes_64(struct file *file, struct elf64_phdr *phdr,
> > +                         int phnum, u32 *feature)
> > +{
> > +       int i;
> > +       int err = 0;
> > +
> > +       for (i = 0; i < phnum; i++, phdr++) {
> > +               if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 8))
> > +                       continue;
> 
> Instead of a separate parser here, wouldn't it be a bit nicer to
> attach this to the existing binfmt_elf program header parsing loop:

We need to wait until SET_PERSONALITY2() is done.

[...]

> > +int arch_setup_features(void *ehdr_p, void *phdr_p,
> > +                       struct file *file, bool interp)
> > +{
> > +       int err = 0;
> > +       u32 feature = 0;
> > +
> > +       struct elf64_hdr *ehdr64 = ehdr_p;
> > +
> > +       if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
> > +               return 0;
> > +
> > +       if (ehdr64->e_ident[EI_CLASS] == ELFCLASS64) {
> > +               struct elf64_phdr *phdr64 = phdr_p;
> > +
> > +               err = check_notes_64(file, phdr64, ehdr64->e_phnum,
> > +                                    &feature);
> > +               if (err < 0)
> > +                       goto out;
> > +       } else {
> > +#ifdef CONFIG_COMPAT
> > +               struct elf32_hdr *ehdr32 = ehdr_p;
> > +
> > +               if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
> > +                       struct elf32_phdr *phdr32 = phdr_p;
> > +
> > +                       err = check_notes_32(file, phdr32, ehdr32->e_phnum,
> > +                                            &feature);
> > +                       if (err < 0)
> > +                               goto out;
> > +               }
> > +#endif
> 
> Should there be an #else error here?

Yes, thanks.

> I'd like to be using this code for a few other cases too (not just
> x86-specific). For example, for marking KASan binaries as needing a
> "legacy" memory layouts[1]. Others might be setting things like
> no_new_privs at exec time, etc.

If the item is a bit of GNU_PROPERTY_X86_FEATURE_1_AND, then this code would
work.  Has it been finalized?

Yu-cheng


WARNING: multiple messages have this Message-ID (diff)
From: Yu-cheng Yu <yu-cheng.yu@intel.com>
To: Kees Cook <keescook@chromium.org>, Andy Lutomirski <luto@amacapital.net>
Cc: X86 ML <x86@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>,
	"open list:DOCUMENTATION" <linux-doc@vger.kernel.org>,
	Linux-MM <linux-mm@kvack.org>,
	linux-arch <linux-arch@vger.kernel.org>,
	Linux API <linux-api@vger.kernel.org>,
	Arnd Bergmann <arnd@arndb.de>,
	Balbir Singh <bsingharora@gmail.com>,
	Cyrill Gorcunov <gorcunov@gmail.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Florian Weimer <fweimer@redhat.com>,
	"H.J. Lu" <hjl.tools@gmail.com>, Jann Horn <jannh@google.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Mike Kravetz <mike.kravetz@oracle.com>,
	Nadav Amit <nadav.amit@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>, Pavel Machek <pavel@ucw.cz>
Subject: Re: [RFC PATCH v4 21/27] x86/cet/shstk: ELF header parsing of Shadow Stack
Date: Tue, 16 Oct 2018 10:23:43 -0700	[thread overview]
Message-ID: <124c1c2805286c70a9b2cc8e4b0abad7ef997ed4.camel@intel.com> (raw)
In-Reply-To: <CAGXu5jKO5Ot5VAJBMHudgx40g4N2tqhLKHeCdS7rkFj1bPaHig@mail.gmail.com>

On Mon, 2018-10-15 at 16:40 -0700, Kees Cook wrote:
> On Fri, Sep 21, 2018 at 8:03 AM, Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
> > Look in .note.gnu.property of an ELF file and check if Shadow Stack needs
> > to be enabled for the task.

[...]

> > +/*
> > + * The .note.gnu.property layout:
> > + *
> > + *     struct elf_note {
> > + *             u32 n_namesz; --> sizeof(n_name[]); always (4)
> > + *             u32 n_ndescsz;--> sizeof(property[])
> > + *             u32 n_type;   --> always NT_GNU_PROPERTY_TYPE_0
> > + *     };
> > + *     char n_name[4]; --> always 'GNU\0'
> > + *
> > + *     struct {
> > + *             struct property_x86 {
> > + *                     u32 pr_type;
> > + *                     u32 pr_datasz;
> > + *             };
> > + *             u8 pr_data[pr_datasz];
> > + *     }[];
> > + */
> 
> Does NT_GNU_PROPERTY_TYPE_0 only ever contain property_x86 bytes? (I
> assume not, since there is a pr_type?)

There are other property types, but we only look for NT_GNU_PROPERTY_TYPE_0.

> > +
> > +#define BUF_SIZE (PAGE_SIZE / 4)
> > +
> > +struct property_x86 {
> > +       u32 pr_type;
> > +       u32 pr_datasz;
> > +};
> > +
> > +typedef bool (test_fn)(void *buf, u32 *arg);
> > +typedef void *(next_fn)(void *buf, u32 *arg);
> > +
> > +static inline bool test_note_type_0(void *buf, u32 *arg)
> > +{
> > +       struct elf_note *n = buf;
> > +
> > +       return ((n->n_namesz == 4) && (memcmp(n + 1, "GNU", 4) == 0) &&
> > +               (n->n_type == NT_GNU_PROPERTY_TYPE_0));
> 
> Cheaper to test n_type first...

Yes, Thanks!

> 
> > +}
> > +
> > +static inline void *next_note(void *buf, u32 *arg)
> > +{
> > +       struct elf_note *n = buf;
> > +       u32 align = *arg;
> > +       int size;
> > +
> > +       size = round_up(sizeof(*n) + n->n_namesz, align);
> 
> I think this could overflow: n_namesz can be u64 for elf64_note.
> 
> > +       size = round_up(size + n->n_descsz, align);
> 
> Same here. You may want to use check_add_overflow(), etc, an u64 types.

Note->n_namesz is always four-byte.  I should have used u32.

> 
> > +
> > +       if (buf + size < buf)
> > +               return NULL;
> 
> I don't understand this. You want to check size not exceeding the
> allocation, which isn't passed into this function. Checking for a full
> unsigned address wrap around is not sufficient to detect overflow.

Here we only detect the warp around.  After this returns we then check other
types of overflow in scan().

> 
> > +       else
> > +               return (buf + size);
> > +}
> > +
> > +static inline bool test_property_x86(void *buf, u32 *arg)
> > +{
> > +       struct property_x86 *pr = buf;
> > +       u32 max_type = *arg;
> > +
> > +       if (pr->pr_type > max_type)
> > +               *arg = pr->pr_type;
> 
> Why is *arg being updated? I don't see last_pr used outside of here --
> are properties required to be pr_type-ordered?

Yes, they need to be in ascending order.

> 
> > +
> > +       return (pr->pr_type == GNU_PROPERTY_X86_FEATURE_1_AND);
> > +}
> > +
> > +static inline void *next_property(void *buf, u32 *arg)
> > +{
> > +       struct property_x86 *pr = buf;
> > +       u32 max_type = *arg;
> > +
> > +       if ((buf + sizeof(*pr) +  pr->pr_datasz < buf) ||
> 
> Again, this "< buf" test doesn't look at all correct to me.
> 
> > +           (pr->pr_type > GNU_PROPERTY_X86_FEATURE_1_AND) ||
> > +           (pr->pr_type > max_type))
> > +               return NULL;
> > +       else
> > +               return (buf + sizeof(*pr) + pr->pr_datasz);
> > +}
> > +
> > +/*
> > + * Scan 'buf' for a pattern; return true if found.
> > + * *pos is the distance from the beginning of buf to where
> > + * the searched item or the next item is located.
> > + */
> > +static int scan(u8 *buf, u32 buf_size, int item_size,
> > +                test_fn test, next_fn next, u32 *arg, u32 *pos)
> 
> I'm not a fan of the short "scan", "test" and "next" names, and I
> really don't like an arg named "arg". Something slightly more
> descriptive for all of these would be nice, please.

I need to work on that :-)  What would you suggest?

> 
> > +{
> > +       int found = 0;
> > +       u8 *p, *max;
> > +
> > +       max = buf + buf_size;
> > +       if (max < buf)
> > +               return 0;
> > +
> > +       p = buf;
> > +
> > +       while ((p + item_size < max) && (p + item_size > buf)) {
> 
> These comparisons are safe due to the BUF_SIZE limit of buf_size and
> the only used size of item_size, but if this becomes more generic, it
> should be more defensive on the size calculations (e.g. make sure than
> "item_size < max" and then here "p < max - item_size", etc).
> 
> I'd kind of rather this code walked the base type and check each for
> the matching feature. What is the general specification for what
> NT_GNU_PROPERTY_TYPE_0 contains?

There are other property types, but the kernel does not look at most of them.
If the kernel needs to look at others, we need to rewrite this.

[...]

> > +
> > +/*
> > + * Search a PT_NOTE segment for the first NT_GNU_PROPERTY_TYPE_0.
> > + */
> > +static int find_note_type_0(struct file *file, unsigned long note_size,
> > +                           loff_t file_offset, u32 align, u32 *feature)
> > +{
> > +       u8 *buf;
> > +       u32 buf_pos;
> > +       unsigned long read_size;
> > +       unsigned long done;
> > +       int found = 0;
> > +       int ret = 0;
> > +
> > +       buf = kmalloc(BUF_SIZE, GFP_KERNEL);
> > +       if (!buf)
> > +               return -ENOMEM;
> 
> Why kmalloc over stack variable? (Or, does BUF_SIZE here really need
> to be 1024?)

BUF_SIZE can be smaller, for example 64.  If it is too small, we need to do
kernel_read() too often.

> 
> > +
> > +       *feature = 0;
> > +       buf_pos = 0;
> > +
> > +       for (done = 0; done < note_size; done += buf_pos) {
> > +               read_size = note_size - done;
> > +               if (read_size > BUF_SIZE)
> > +                       read_size = BUF_SIZE;
> > +
> > +               ret = kernel_read(file, buf, read_size, &file_offset);
> > +
> > +               if (ret != read_size) {
> > +                       ret = (ret < 0) ? ret : -EIO;
> > +                       kfree(buf);
> > +                       return ret;
> > +               }
> > +
> > +               /*
> > +                * item_size = sizeof(struct elf_note) + elf_note.n_namesz.
> > +                * n_namesz is 4 for the note type we look for.
> > +                */
> > +               ret = 0;
> > +               found += scan(buf, read_size, sizeof(struct elf_note) + 4,
> > +                             test_note_type_0, next_note,
> > +                             &align, &buf_pos);
> > +
> > +               file_offset += buf_pos - read_size;
> > +
> > +               if (found == 1) {
> > +                       struct elf_note *n =
> > +                               (struct elf_note *)(buf + buf_pos);
> > +                       u32 start = round_up(sizeof(*n) + n->n_namesz,
> > align);
> > +                       u32 total = round_up(start + n->n_descsz, align);
> 
> Same overflow notes from earlier...
> 
> > +
> > +                       ret = find_feature_x86(file, n->n_descsz,
> > +                                              file_offset + start,
> > +                                              buf, feature);
> > +                       file_offset += total;
> > +                       buf_pos += total;
> > +               } else if (!buf_pos) {
> > +                       *feature = 0;
> > +                       break;
> > +               }
> > +       }
> > +
> > +       kfree(buf);
> > +       return ret;
> > +}
> > +
> > +#ifdef CONFIG_COMPAT
> > +static int check_notes_32(struct file *file, struct elf32_phdr *phdr,
> > +                         int phnum, u32 *feature)
> > +{
> > +       int i;
> > +       int err = 0;
> > +
> > +       for (i = 0; i < phnum; i++, phdr++) {
> > +               if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 4))
> > +                       continue;
> > +
> > +               err = find_note_type_0(file, phdr->p_filesz, phdr->p_offset,
> > +                                      phdr->p_align, feature);
> > +               if (err)
> > +                       return err;
> > +       }
> > +
> > +       return 0;
> > +}
> > +#endif
> > +
> > +#ifdef CONFIG_X86_64
> > +static int check_notes_64(struct file *file, struct elf64_phdr *phdr,
> > +                         int phnum, u32 *feature)
> > +{
> > +       int i;
> > +       int err = 0;
> > +
> > +       for (i = 0; i < phnum; i++, phdr++) {
> > +               if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 8))
> > +                       continue;
> 
> Instead of a separate parser here, wouldn't it be a bit nicer to
> attach this to the existing binfmt_elf program header parsing loop:

We need to wait until SET_PERSONALITY2() is done.

[...]

> > +int arch_setup_features(void *ehdr_p, void *phdr_p,
> > +                       struct file *file, bool interp)
> > +{
> > +       int err = 0;
> > +       u32 feature = 0;
> > +
> > +       struct elf64_hdr *ehdr64 = ehdr_p;
> > +
> > +       if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
> > +               return 0;
> > +
> > +       if (ehdr64->e_ident[EI_CLASS] == ELFCLASS64) {
> > +               struct elf64_phdr *phdr64 = phdr_p;
> > +
> > +               err = check_notes_64(file, phdr64, ehdr64->e_phnum,
> > +                                    &feature);
> > +               if (err < 0)
> > +                       goto out;
> > +       } else {
> > +#ifdef CONFIG_COMPAT
> > +               struct elf32_hdr *ehdr32 = ehdr_p;
> > +
> > +               if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
> > +                       struct elf32_phdr *phdr32 = phdr_p;
> > +
> > +                       err = check_notes_32(file, phdr32, ehdr32->e_phnum,
> > +                                            &feature);
> > +                       if (err < 0)
> > +                               goto out;
> > +               }
> > +#endif
> 
> Should there be an #else error here?

Yes, thanks.

> I'd like to be using this code for a few other cases too (not just
> x86-specific). For example, for marking KASan binaries as needing a
> "legacy" memory layouts[1]. Others might be setting things like
> no_new_privs at exec time, etc.

If the item is a bit of GNU_PROPERTY_X86_FEATURE_1_AND, then this code would
work.  Has it been finalized?

Yu-cheng

  reply	other threads:[~2018-10-16 17:28 UTC|newest]

Thread overview: 145+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-21 15:03 [RFC PATCH v4 00/27] Control Flow Enforcement: Shadow Stack Yu-cheng Yu
2018-09-21 15:03 ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 01/27] x86/cpufeatures: Add CPUIDs for Control-flow Enforcement Technology (CET) Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-25 16:27   ` Peter Zijlstra
2018-09-25 16:27     ` Peter Zijlstra
2018-09-25 16:29     ` Yu-cheng Yu
2018-09-25 16:29       ` Yu-cheng Yu
2018-09-28 16:51   ` Borislav Petkov
2018-09-28 16:51     ` Borislav Petkov
2018-09-28 16:56     ` Yu-cheng Yu
2018-09-28 16:56       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 02/27] x86/fpu/xstate: Change some names to separate XSAVES system and user states Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-25 16:37   ` Peter Zijlstra
2018-09-25 16:37     ` Peter Zijlstra
2018-10-02 15:29   ` Borislav Petkov
2018-10-02 15:29     ` Borislav Petkov
2018-10-02 15:29     ` Borislav Petkov
2018-10-02 16:21     ` Yu-cheng Yu
2018-10-02 16:21       ` Yu-cheng Yu
2018-10-02 16:21       ` Yu-cheng Yu
2018-10-02 16:30       ` Dave Hansen
2018-10-02 16:30         ` Dave Hansen
2018-10-02 16:30         ` Dave Hansen
2018-10-02 16:37         ` Borislav Petkov
2018-10-02 16:37           ` Borislav Petkov
2018-10-02 16:39           ` Dave Hansen
2018-10-02 16:39             ` Dave Hansen
2018-10-02 16:43             ` Yu-cheng Yu
2018-10-02 16:43               ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 03/27] x86/fpu/xstate: Enable XSAVES system states Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-25 17:03   ` Peter Zijlstra
2018-09-25 17:03     ` Peter Zijlstra
2018-09-25 17:23     ` Yu-cheng Yu
2018-09-25 17:23       ` Yu-cheng Yu
2018-10-02 17:15   ` Borislav Petkov
2018-10-02 17:15     ` Borislav Petkov
2018-10-04 15:47     ` Yu-cheng Yu
2018-10-04 15:47       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 04/27] x86/fpu/xstate: Add XSAVES system states for shadow stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 05/27] Documentation/x86: Add CET description Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 06/27] x86/cet: Control protection exception handler Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 10:39   ` Eugene Syromiatnikov
2018-10-03 10:39     ` Eugene Syromiatnikov
2018-10-03 16:11     ` Yu-cheng Yu
2018-10-03 16:11       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 07/27] x86/cet/shstk: Add Kconfig option for user-mode shadow stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 08/27] mm: Introduce VM_SHSTK for shadow stack memory Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 09/27] x86/mm: Change _PAGE_DIRTY to _PAGE_DIRTY_HW Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 13:38   ` Matthew Wilcox
2018-10-03 13:38     ` Matthew Wilcox
2018-10-03 14:05     ` Dave Hansen
2018-10-03 14:05       ` Dave Hansen
2018-10-03 16:07     ` Yu-cheng Yu
2018-10-03 16:07       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 10/27] drm/i915/gvt: Update _PAGE_DIRTY to _PAGE_DIRTY_BITS Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 13:19   ` Eugene Syromiatnikov
2018-10-03 13:19     ` Eugene Syromiatnikov
2018-09-21 15:03 ` [RFC PATCH v4 11/27] x86/mm: Introduce _PAGE_DIRTY_SW Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 12/27] x86/mm: Modify ptep_set_wrprotect and pmdp_set_wrprotect for _PAGE_DIRTY_SW Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 13/27] x86/mm: Shadow stack page fault error checking Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 14/27] mm: Handle shadow stack page fault Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 15/27] mm: Handle THP/HugeTLB " Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 16/27] mm: Update can_follow_write_pte/pmd for shadow stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 17/27] mm: Introduce do_mmap_locked() Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 18/27] x86/cet/shstk: User-mode shadow stack support Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 15:08   ` Eugene Syromiatnikov
2018-10-03 15:08     ` Eugene Syromiatnikov
2018-10-03 15:12     ` Yu-cheng Yu
2018-10-03 15:12       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 19/27] x86/cet/shstk: Introduce WRUSS instruction Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03  4:15   ` Eugene Syromiatnikov
2018-10-03  4:15     ` Eugene Syromiatnikov
2018-09-21 15:03 ` [RFC PATCH v4 20/27] x86/cet/shstk: Signal handling for shadow stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 14:36   ` Eugene Syromiatnikov
2018-10-03 14:36     ` Eugene Syromiatnikov
2018-10-03 16:46   ` Jann Horn
2018-10-03 16:46     ` Jann Horn
2018-09-21 15:03 ` [RFC PATCH v4 21/27] x86/cet/shstk: ELF header parsing of Shadow Stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 23:27   ` Eugene Syromiatnikov
2018-10-03 23:27     ` Eugene Syromiatnikov
2018-10-09 21:15     ` Yu-cheng Yu
2018-10-09 21:15       ` Yu-cheng Yu
2018-10-15 23:40   ` Kees Cook
2018-10-15 23:40     ` Kees Cook
2018-10-16 17:23     ` Yu-cheng Yu [this message]
2018-10-16 17:23       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 22/27] x86/cet/shstk: Handle thread shadow stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 23/27] mm/map: Add Shadow stack pages to memory accounting Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 16:55   ` Randy Dunlap
2018-09-21 16:55     ` Randy Dunlap
2018-09-21 17:21     ` Yu-cheng Yu
2018-09-21 17:21       ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 24/27] mm/mmap: Create a guard area between VMAs Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03  4:56   ` Eugene Syromiatnikov
2018-10-03  4:56     ` Eugene Syromiatnikov
2018-10-03  5:36     ` Andy Lutomirski
2018-10-03  5:36       ` Andy Lutomirski
2018-10-03 16:00       ` Yu-cheng Yu
2018-10-03 16:00         ` Yu-cheng Yu
2018-10-03 16:18         ` Andy Lutomirski
2018-10-03 16:18           ` Andy Lutomirski
2018-10-03 16:32         ` Eugene Syromiatnikov
2018-10-03 16:32           ` Eugene Syromiatnikov
2018-10-03 16:40           ` Yu-cheng Yu
2018-10-03 16:40             ` Yu-cheng Yu
2018-10-03 16:52           ` Jann Horn
2018-10-03 16:52             ` Jann Horn
2018-10-03 21:21             ` Eugene Syromiatnikov
2018-10-03 21:21               ` Eugene Syromiatnikov
2018-09-21 15:03 ` [RFC PATCH v4 25/27] mm/mmap: Prevent Shadow Stack VMA merges Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 15:03 ` [RFC PATCH v4 26/27] x86/cet/shstk: Add arch_prctl functions for Shadow Stack Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-10-03 17:57   ` Eugene Syromiatnikov
2018-10-03 17:57     ` Eugene Syromiatnikov
2018-09-21 15:03 ` [RFC PATCH v4 27/27] x86/cet/shstk: Add Shadow Stack instructions to opcode map Yu-cheng Yu
2018-09-21 15:03   ` Yu-cheng Yu
2018-09-21 22:53 ` [RFC PATCH v4 00/27] Control Flow Enforcement: Shadow Stack Dave Hansen
2018-09-21 22:53   ` Dave Hansen
2018-09-24 15:25   ` Yu-cheng Yu
2018-09-24 15:25     ` Yu-cheng Yu

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=124c1c2805286c70a9b2cc8e4b0abad7ef997ed4.camel@intel.com \
    --to=yu-cheng.yu@intel.com \
    --cc=arnd@arndb.de \
    --cc=bsingharora@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=fweimer@redhat.com \
    --cc=gorcunov@gmail.com \
    --cc=hjl.tools@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jannh@google.com \
    --cc=keescook@chromium.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@amacapital.net \
    --cc=mike.kravetz@oracle.com \
    --cc=mingo@redhat.com \
    --cc=nadav.amit@gmail.com \
    --cc=oleg@redhat.com \
    --cc=pavel@ucw.cz \
    --cc=peterz@infradead.org \
    --cc=ravi.v.shankar@intel.com \
    --cc=rdunlap@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=vedvyas.shanbhogue@intel.com \
    --cc=x86@kernel.org \
    /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.