All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dennis Zhou <dennisszhou@gmail.com>
To: Kees Cook <keescook@chromium.org>
Cc: Dmitry Vyukov <dvyukov@google.com>,
	Fengguang Wu <fengguang.wu@intel.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Linux-MM <linux-mm@kvack.org>, Tejun Heo <tj@kernel.org>,
	Christoph Lameter <cl@linux.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Josef Bacik <jbacik@fb.com>, LKML <linux-kernel@vger.kernel.org>,
	LKP <lkp@01.org>, Andrey Ryabinin <aryabinin@virtuozzo.com>,
	Mark Rutland <mark.rutland@arm.com>
Subject: Re: [pcpu] BUG: KASAN: use-after-scope in pcpu_setup_first_chunk+0x1e3b/0x29e2
Date: Thu, 30 Nov 2017 13:22:57 -0600	[thread overview]
Message-ID: <20171130192257.GB1529@localhost> (raw)
In-Reply-To: <CAGXu5jLOojG_Nc50KhdHsXDQQ27G+kOPp6-5kQz7Yh5Vpgucnw@mail.gmail.com>

Hi Dmitry and Kees,

On Thu, Nov 30, 2017 at 10:10:41AM -0800, Kees Cook wrote:
> > Are we sure that structleak plugin is not at fault? If yes, then we
> > need to report this to https://gcc.gnu.org/bugzilla/ with instructions
> > on how to build/use the plugin.

I believe this is an issue with the structleak plugin and not gcc. The
bug does not show up if you compile without
GCC_PLUGIN_STRUCTLEAK_BYREF_ALL.

It seems to be caused by the initializer not respecting the ASAN_MARK
calls. Therefore, if an inlined function gets called from a for loop,
the initializer code gets invoked bugging in the second iteration. Below
is the tree dump for the structleak plugin from the reproducer in the
previous email. In bb 2 of INIT_LIST_HEAD, the __u = {} is before the
unpoison call. This is inlined in bb 3 of main.

> 
> I thought from earlier in this thread that the bug just changed
> locations depending on the plugin. Does the issue still exist with the
> plugin disabled?
> 

The bug changing locations was me just verifying it was not an issue
with percpu memory. I manually unrolled the for loop to show that the
percpu bug disappears, but manifests later on. The issue does not exist
with the BY_REF_ALL config.

Thanks,
Dennis

----

;; Function __write_once_size (__write_once_size, funcdef_no=2, decl_uid=3117, cgraph_uid=2, symbol_order=2)

__attribute__((always_inline))
__write_once_size (volatile void * p, void * res, int size)
{
  unsigned char _1;
  short unsigned int _2;
  unsigned int _3;
  long unsigned int _4;
  long unsigned int _5;

  <bb 2> [0.00%]:
  switch (size_7(D)) <default: <L4> [0.00%], case 1: <L0> [0.00%], case 2: <L1> [0.00%], case 4: <L2> [0.00%], case 8: <L3> [0.00%]>

<L0> [0.00%]:
  _1 = MEM[(__u8 *)res_9(D)];
  MEM[(volatile __u8 *)p_10(D)] ={v} _1;
  goto <bb 8>; [0.00%]

<L1> [0.00%]:
  _2 = MEM[(__u16 *)res_9(D)];
  MEM[(volatile __u16 *)p_10(D)] ={v} _2;
  goto <bb 8>; [0.00%]

<L2> [0.00%]:
  _3 = MEM[(__u32 *)res_9(D)];
  MEM[(volatile __u32 *)p_10(D)] ={v} _3;
  goto <bb 8>; [0.00%]

<L3> [0.00%]:
  _4 = MEM[(__u64 *)res_9(D)];
  MEM[(volatile __u64 *)p_10(D)] ={v} _4;
  goto <bb 8>; [0.00%]

<L4> [0.00%]:
  _5 = (long unsigned int) size_7(D);
  __builtin_memcpy (p_10(D), res_9(D), _5);

  <bb 8> [0.00%]:
  return;

}



;; Function INIT_LIST_HEAD (INIT_LIST_HEAD, funcdef_no=3, decl_uid=3129, cgraph_uid=3, symbol_order=3)


Symbols to be put in SSA form
{ D.3149 }
Incremental SSA update started at block: 0
Number of blocks in CFG: 9
Number of blocks to update: 8 ( 89%)


__attribute__((always_inline))
INIT_LIST_HEAD (struct list_head * list)
{
  volatile void * p;
  void * res;
  int size;
  union 
  {
    struct list_head * __val;
    char __c[1];
  } __u;
  struct list_head * D.3135;
  struct list_head * * _1;
  struct list_head * _7;
  unsigned char _13;
  short unsigned int _14;
  unsigned int _15;
  long unsigned int _16;
  long unsigned int _17;

  <bb 2> [0.00%]:
  __u = {};
  ASAN_MARK (UNPOISON, &__u, 8);
  __u.__val = list_4(D);
  _1 = &list_4(D)->next;
  p_10 = _1;
  res_11 = &__u.__c;
  size_12 = 8;
  switch (size_12) <default: <L4> [0.00%], case 1: <L0> [0.00%], case 2: <L1> [0.00%], case 4: <L2> [0.00%], case 8: <L3> [0.00%]>

<L0> [0.00%]:
  _13 = MEM[(__u8 *)res_11];
  MEM[(volatile __u8 *)p_10] ={v} _13;
  goto <bb 8>; [0.00%]

<L1> [0.00%]:
  _14 = MEM[(__u16 *)res_11];
  MEM[(volatile __u16 *)p_10] ={v} _14;
  goto <bb 8>; [0.00%]

<L2> [0.00%]:
  _15 = MEM[(__u32 *)res_11];
  MEM[(volatile __u32 *)p_10] ={v} _15;
  goto <bb 8>; [0.00%]

<L3> [0.00%]:
  _16 = MEM[(__u64 *)res_11];
  MEM[(volatile __u64 *)p_10] ={v} _16;
  goto <bb 8>; [0.00%]

<L4> [0.00%]:
  _17 = (long unsigned int) size_12;
  __builtin_memcpy (p_10, res_11, _17);

  <bb 8> [0.00%]:
  _7 = __u.__val;
  ASAN_MARK (POISON, &__u, 8);
  list_4(D)->prev = list_4(D);
  return;

}



;; Function main (main, funcdef_no=4, decl_uid=3138, cgraph_uid=4, symbol_order=4)


Symbols to be put in SSA form
{ D.3150 }
Incremental SSA update started at block: 0
Number of blocks in CFG: 13
Number of blocks to update: 12 ( 92%)


main (int argc, char * * argv)
{
  struct list_head * D.3165;
  union 
  {
    struct list_head * __val;
    char __c[1];
  } __u;
  int size;
  void * res;
  volatile void * p;
  struct list_head * list;
  int i;
  struct list_head * p;
  int D.3146;
  long unsigned int _1;
  long unsigned int _2;
  struct list_head * _3;
  int _11;
  struct list_head * * _15;
  unsigned char _19;
  short unsigned int _20;
  unsigned int _21;
  long unsigned int _22;
  long unsigned int _23;
  struct list_head * _24;

  <bb 2> [0.00%]:
  __u = {};
  p_8 = malloc (160);
  i_9 = 0;
  goto <bb 10>; [0.00%]

  <bb 3> [0.00%]:
  _1 = (long unsigned int) i_4;
  _2 = _1 * 16;
  _3 = p_8 + _2;
  list_14 = _3;
  __u = {};
  ASAN_MARK (UNPOISON, &__u, 8);
  __u.__val = list_14;
  _15 = &list_14->next;
  p_16 = _15;
  res_17 = &__u.__c;
  size_18 = 8;
  switch (size_18) <default: <L8> [0.00%], case 1: <L4> [0.00%], case 2: <L5> [0.00%], case 4: <L6> [0.00%], case 8: <L7> [0.00%]>

<L4> [0.00%]:
  _19 = MEM[(__u8 *)res_17];
  MEM[(volatile __u8 *)p_16] ={v} _19;
  goto <bb 9>; [0.00%]

<L5> [0.00%]:
  _20 = MEM[(__u16 *)res_17];
  MEM[(volatile __u16 *)p_16] ={v} _20;
  goto <bb 9>; [0.00%]

<L6> [0.00%]:
  _21 = MEM[(__u32 *)res_17];
  MEM[(volatile __u32 *)p_16] ={v} _21;
  goto <bb 9>; [0.00%]

<L7> [0.00%]:
  _22 = MEM[(__u64 *)res_17];
  MEM[(volatile __u64 *)p_16] ={v} _22;
  goto <bb 9>; [0.00%]

<L8> [0.00%]:
  _23 = (long unsigned int) size_18;
  __builtin_memcpy (p_16, res_17, _23);

  <bb 9> [0.00%]:
  _24 = __u.__val;
  ASAN_MARK (POISON, &__u, 8);
  list_14->prev = list_14;
  i_13 = i_4 + 1;

  <bb 10> [0.00%]:
  # i_4 = PHI <i_9(2), i_13(9)>
  if (i_4 <= 9)
    goto <bb 3>; [0.00%]
  else
    goto <bb 11>; [0.00%]

  <bb 11> [0.00%]:
  free (p_8);
  _11 = 0;

<L3> [0.00%]:
  return _11;

}



;; Function _GLOBAL__sub_I_00099_0_main (_GLOBAL__sub_I_00099_0_main, funcdef_no=5, decl_uid=3178, cgraph_uid=3, symbol_order=8)

_GLOBAL__sub_I_00099_0_main ()
{
  <bb 2> [0.00%]:
  __builtin___asan_init ();
  __builtin___asan_version_mismatch_check_v8 ();
  return;

}


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: Dennis Zhou <dennisszhou@gmail.com>
To: Kees Cook <keescook@chromium.org>
Cc: Dmitry Vyukov <dvyukov@google.com>,
	Fengguang Wu <fengguang.wu@intel.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Linux-MM <linux-mm@kvack.org>, Tejun Heo <tj@kernel.org>,
	Christoph Lameter <cl@linux.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Josef Bacik <jbacik@fb.com>, LKML <linux-kernel@vger.kernel.org>,
	LKP <lkp@01.org>, Andrey Ryabinin <aryabinin@virtuozzo.com>,
	Mark Rutland <mark.rutland@arm.com>
Subject: Re: [pcpu] BUG: KASAN: use-after-scope in pcpu_setup_first_chunk+0x1e3b/0x29e2
Date: Thu, 30 Nov 2017 13:22:57 -0600	[thread overview]
Message-ID: <20171130192257.GB1529@localhost> (raw)
In-Reply-To: <CAGXu5jLOojG_Nc50KhdHsXDQQ27G+kOPp6-5kQz7Yh5Vpgucnw@mail.gmail.com>

Hi Dmitry and Kees,

On Thu, Nov 30, 2017 at 10:10:41AM -0800, Kees Cook wrote:
> > Are we sure that structleak plugin is not at fault? If yes, then we
> > need to report this to https://gcc.gnu.org/bugzilla/ with instructions
> > on how to build/use the plugin.

I believe this is an issue with the structleak plugin and not gcc. The
bug does not show up if you compile without
GCC_PLUGIN_STRUCTLEAK_BYREF_ALL.

It seems to be caused by the initializer not respecting the ASAN_MARK
calls. Therefore, if an inlined function gets called from a for loop,
the initializer code gets invoked bugging in the second iteration. Below
is the tree dump for the structleak plugin from the reproducer in the
previous email. In bb 2 of INIT_LIST_HEAD, the __u = {} is before the
unpoison call. This is inlined in bb 3 of main.

> 
> I thought from earlier in this thread that the bug just changed
> locations depending on the plugin. Does the issue still exist with the
> plugin disabled?
> 

The bug changing locations was me just verifying it was not an issue
with percpu memory. I manually unrolled the for loop to show that the
percpu bug disappears, but manifests later on. The issue does not exist
with the BY_REF_ALL config.

Thanks,
Dennis

----

;; Function __write_once_size (__write_once_size, funcdef_no=2, decl_uid=3117, cgraph_uid=2, symbol_order=2)

__attribute__((always_inline))
__write_once_size (volatile void * p, void * res, int size)
{
  unsigned char _1;
  short unsigned int _2;
  unsigned int _3;
  long unsigned int _4;
  long unsigned int _5;

  <bb 2> [0.00%]:
  switch (size_7(D)) <default: <L4> [0.00%], case 1: <L0> [0.00%], case 2: <L1> [0.00%], case 4: <L2> [0.00%], case 8: <L3> [0.00%]>

<L0> [0.00%]:
  _1 = MEM[(__u8 *)res_9(D)];
  MEM[(volatile __u8 *)p_10(D)] ={v} _1;
  goto <bb 8>; [0.00%]

<L1> [0.00%]:
  _2 = MEM[(__u16 *)res_9(D)];
  MEM[(volatile __u16 *)p_10(D)] ={v} _2;
  goto <bb 8>; [0.00%]

<L2> [0.00%]:
  _3 = MEM[(__u32 *)res_9(D)];
  MEM[(volatile __u32 *)p_10(D)] ={v} _3;
  goto <bb 8>; [0.00%]

<L3> [0.00%]:
  _4 = MEM[(__u64 *)res_9(D)];
  MEM[(volatile __u64 *)p_10(D)] ={v} _4;
  goto <bb 8>; [0.00%]

<L4> [0.00%]:
  _5 = (long unsigned int) size_7(D);
  __builtin_memcpy (p_10(D), res_9(D), _5);

  <bb 8> [0.00%]:
  return;

}



;; Function INIT_LIST_HEAD (INIT_LIST_HEAD, funcdef_no=3, decl_uid=3129, cgraph_uid=3, symbol_order=3)


Symbols to be put in SSA form
{ D.3149 }
Incremental SSA update started at block: 0
Number of blocks in CFG: 9
Number of blocks to update: 8 ( 89%)


__attribute__((always_inline))
INIT_LIST_HEAD (struct list_head * list)
{
  volatile void * p;
  void * res;
  int size;
  union 
  {
    struct list_head * __val;
    char __c[1];
  } __u;
  struct list_head * D.3135;
  struct list_head * * _1;
  struct list_head * _7;
  unsigned char _13;
  short unsigned int _14;
  unsigned int _15;
  long unsigned int _16;
  long unsigned int _17;

  <bb 2> [0.00%]:
  __u = {};
  ASAN_MARK (UNPOISON, &__u, 8);
  __u.__val = list_4(D);
  _1 = &list_4(D)->next;
  p_10 = _1;
  res_11 = &__u.__c;
  size_12 = 8;
  switch (size_12) <default: <L4> [0.00%], case 1: <L0> [0.00%], case 2: <L1> [0.00%], case 4: <L2> [0.00%], case 8: <L3> [0.00%]>

<L0> [0.00%]:
  _13 = MEM[(__u8 *)res_11];
  MEM[(volatile __u8 *)p_10] ={v} _13;
  goto <bb 8>; [0.00%]

<L1> [0.00%]:
  _14 = MEM[(__u16 *)res_11];
  MEM[(volatile __u16 *)p_10] ={v} _14;
  goto <bb 8>; [0.00%]

<L2> [0.00%]:
  _15 = MEM[(__u32 *)res_11];
  MEM[(volatile __u32 *)p_10] ={v} _15;
  goto <bb 8>; [0.00%]

<L3> [0.00%]:
  _16 = MEM[(__u64 *)res_11];
  MEM[(volatile __u64 *)p_10] ={v} _16;
  goto <bb 8>; [0.00%]

<L4> [0.00%]:
  _17 = (long unsigned int) size_12;
  __builtin_memcpy (p_10, res_11, _17);

  <bb 8> [0.00%]:
  _7 = __u.__val;
  ASAN_MARK (POISON, &__u, 8);
  list_4(D)->prev = list_4(D);
  return;

}



;; Function main (main, funcdef_no=4, decl_uid=3138, cgraph_uid=4, symbol_order=4)


Symbols to be put in SSA form
{ D.3150 }
Incremental SSA update started at block: 0
Number of blocks in CFG: 13
Number of blocks to update: 12 ( 92%)


main (int argc, char * * argv)
{
  struct list_head * D.3165;
  union 
  {
    struct list_head * __val;
    char __c[1];
  } __u;
  int size;
  void * res;
  volatile void * p;
  struct list_head * list;
  int i;
  struct list_head * p;
  int D.3146;
  long unsigned int _1;
  long unsigned int _2;
  struct list_head * _3;
  int _11;
  struct list_head * * _15;
  unsigned char _19;
  short unsigned int _20;
  unsigned int _21;
  long unsigned int _22;
  long unsigned int _23;
  struct list_head * _24;

  <bb 2> [0.00%]:
  __u = {};
  p_8 = malloc (160);
  i_9 = 0;
  goto <bb 10>; [0.00%]

  <bb 3> [0.00%]:
  _1 = (long unsigned int) i_4;
  _2 = _1 * 16;
  _3 = p_8 + _2;
  list_14 = _3;
  __u = {};
  ASAN_MARK (UNPOISON, &__u, 8);
  __u.__val = list_14;
  _15 = &list_14->next;
  p_16 = _15;
  res_17 = &__u.__c;
  size_18 = 8;
  switch (size_18) <default: <L8> [0.00%], case 1: <L4> [0.00%], case 2: <L5> [0.00%], case 4: <L6> [0.00%], case 8: <L7> [0.00%]>

<L4> [0.00%]:
  _19 = MEM[(__u8 *)res_17];
  MEM[(volatile __u8 *)p_16] ={v} _19;
  goto <bb 9>; [0.00%]

<L5> [0.00%]:
  _20 = MEM[(__u16 *)res_17];
  MEM[(volatile __u16 *)p_16] ={v} _20;
  goto <bb 9>; [0.00%]

<L6> [0.00%]:
  _21 = MEM[(__u32 *)res_17];
  MEM[(volatile __u32 *)p_16] ={v} _21;
  goto <bb 9>; [0.00%]

<L7> [0.00%]:
  _22 = MEM[(__u64 *)res_17];
  MEM[(volatile __u64 *)p_16] ={v} _22;
  goto <bb 9>; [0.00%]

<L8> [0.00%]:
  _23 = (long unsigned int) size_18;
  __builtin_memcpy (p_16, res_17, _23);

  <bb 9> [0.00%]:
  _24 = __u.__val;
  ASAN_MARK (POISON, &__u, 8);
  list_14->prev = list_14;
  i_13 = i_4 + 1;

  <bb 10> [0.00%]:
  # i_4 = PHI <i_9(2), i_13(9)>
  if (i_4 <= 9)
    goto <bb 3>; [0.00%]
  else
    goto <bb 11>; [0.00%]

  <bb 11> [0.00%]:
  free (p_8);
  _11 = 0;

<L3> [0.00%]:
  return _11;

}



;; Function _GLOBAL__sub_I_00099_0_main (_GLOBAL__sub_I_00099_0_main, funcdef_no=5, decl_uid=3178, cgraph_uid=3, symbol_order=8)

_GLOBAL__sub_I_00099_0_main ()
{
  <bb 2> [0.00%]:
  __builtin___asan_init ();
  __builtin___asan_version_mismatch_check_v8 ();
  return;

}

  reply	other threads:[~2017-11-30 19:23 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-26  6:31 [pcpu] BUG: KASAN: use-after-scope in pcpu_setup_first_chunk+0x1e3b/0x29e2 Fengguang Wu
2017-11-26  6:31 ` Fengguang Wu
2017-11-27 21:03 ` Dennis Zhou
2017-11-27 21:03   ` Dennis Zhou
2017-11-28 12:45   ` Fengguang Wu
2017-11-28 12:45     ` Fengguang Wu
2017-11-28 12:45     ` Fengguang Wu
2017-11-29 17:54     ` Dennis Zhou
2017-11-29 17:54       ` Dennis Zhou
2017-11-30  9:59       ` Dmitry Vyukov
2017-11-30  9:59         ` Dmitry Vyukov
2017-11-30  9:59         ` Dmitry Vyukov
2017-11-30 18:10         ` Kees Cook
2017-11-30 18:10           ` Kees Cook
2017-11-30 18:10           ` Kees Cook
2017-11-30 19:22           ` Dennis Zhou [this message]
2017-11-30 19:22             ` Dennis Zhou
2017-11-30 19:56             ` Kees Cook
2017-11-30 19:56               ` Kees Cook
2017-11-30 19:56               ` Kees Cook
2017-11-30 19:58               ` Ard Biesheuvel
2017-11-30 19:58                 ` Ard Biesheuvel
2017-11-30 19:58                 ` Ard Biesheuvel

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=20171130192257.GB1529@localhost \
    --to=dennisszhou@gmail.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=aryabinin@virtuozzo.com \
    --cc=cl@linux.com \
    --cc=dvyukov@google.com \
    --cc=fengguang.wu@intel.com \
    --cc=jbacik@fb.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lkp@01.org \
    --cc=mark.rutland@arm.com \
    --cc=tj@kernel.org \
    --cc=torvalds@linux-foundation.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.