Re: [cfs_trace_lock_tcd] BUG: KASAN: null-ptr-deref in cfs_trace_lock_tcd+0x25/0xeb

2018-04-19 Thread Andrey Ryabinin


On 04/19/2018 04:35 PM, Andrey Ryabinin wrote:
> 
> 
> On 04/18/2018 09:37 PM, Linus Torvalds wrote:
>> Ugh, that lustre code is disgusting.
>>
>> I thought we were getting rid of it.
>>
>> Anyway, I started looking at why the stack trace is such an incredible
>> mess, with lots of stale entries.
>>
>> The reason (well, _one_ reason) seems to be "ksocknal_startup". It has
>> a 500-byte stack frame for some incomprehensible reason. I assume due
>> to excessive inlining, because the function itself doesn't seem to be
>> that bad.
>>
>> Similarly, LNetNIInit has a 300-byte stack frame. So it gets pretty deep.
>>
>> I'm getting the feeling that KASAN is making things worse because
>> probably it's disabling all the sane stack frame stuff (ie no merging
>> of stack slot entries, perhaps?).
>>
> 
> AFAIR no merging of stack slots policy enabled only if 
> -fsanitize-address-use-after-scope 
> is on (which is CONFIG_KASAN_EXTRA). This feature does cause sometimes 
> significant stack bloat,
> but hasn't been proven to be very useful, so I wouldn't mind disabling it 
> completely.
> 
> So far I know only about a single BUG - 
> https://lkml.kernel.org/r/<151238865557.4852.10258661301122491...@mail.alporthouse.com>
> it has found.

Actually, there is one more - 
https://syzkaller.appspot.com/bug?id=6a929b72a32ca0b1a6985126fa1bc77c03c12304
so two bugs.

> There are also a lot of other 

I didn't finish this sentence:

There are also a lot of other reports about use-after-scope, but seem all of 
them are false positives
caused by STRUCTLEAK plugin.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [cfs_trace_lock_tcd] BUG: KASAN: null-ptr-deref in cfs_trace_lock_tcd+0x25/0xeb

2018-04-19 Thread Andrey Ryabinin


On 04/18/2018 09:37 PM, Linus Torvalds wrote:
> Ugh, that lustre code is disgusting.
> 
> I thought we were getting rid of it.
> 
> Anyway, I started looking at why the stack trace is such an incredible
> mess, with lots of stale entries.
> 
> The reason (well, _one_ reason) seems to be "ksocknal_startup". It has
> a 500-byte stack frame for some incomprehensible reason. I assume due
> to excessive inlining, because the function itself doesn't seem to be
> that bad.
> 
> Similarly, LNetNIInit has a 300-byte stack frame. So it gets pretty deep.
> 
> I'm getting the feeling that KASAN is making things worse because
> probably it's disabling all the sane stack frame stuff (ie no merging
> of stack slot entries, perhaps?).
>

AFAIR no merging of stack slots policy enabled only if 
-fsanitize-address-use-after-scope 
is on (which is CONFIG_KASAN_EXTRA). This feature does cause sometimes 
significant stack bloat,
but hasn't been proven to be very useful, so I wouldn't mind disabling it 
completely.

So far I know only about a single BUG - 
https://lkml.kernel.org/r/<151238865557.4852.10258661301122491...@mail.alporthouse.com>
it has found.
There are also a lot of other 


> Without KASAN (but also without a lot of other things, so I might be
> blaming KASAN incorrectly), the stack usage of ksocknal_startup() is
> just under 100 bytes, so if it is KASAN, it's really a big difference.
>

Yes, it's because of KASAN:
CONFIG_KASAN=n
socklnd.c:2795:1:ksocknal_startup   144 static

CONFIG_KASAN=y
CONFIG_KASAN_OUTLINE=y
CONFIG_KASAN_EXTRA=n
socklnd.c:2795:1:ksocknal_startup   552 static

CONFIG_KASAN=y
CONFIG_KASAN_OUTLINE=y
CONFIG_KASAN_EXTRA=y
socklnd.c:2795:1:ksocknal_startup   624 static

It's expected that KASAN may cause sometimes significant stack usage growth.
This is needed to catch out-of-bounds accesses to stack data.
When compiler can't proof that access to stack variable is valid (e.g. 
reference to
stack variable passed to some external function), it will create redzones 
around such
stack variable.

E.g. ksocknal_enumerate_interfaces() which is called only from 
ksocknal_startup(), thus probably
inlined into ksocknal_startup() does this:


for (i = j = 0; i < n; i++) {
int up;
__u32 ip;
__u32 mask;

if (!strcmp(names[i], "lo")) /* skip the loopback IF */
continue;

rc = lnet_ipif_query(names[i], &up, &ip, &mask);


With KASAN stack might look something like this:
  [32-byte left redzone of the stack frame] [up (4 bytes)] [28-bytes 
redzone][ip (4 bytes)] [28-bytes redzone][mask (4 bytes)] [28-bytes 
redzone][32-byte right redzone of the stack frame]

GCC always use 32-bytes redzones. AFAIK clang is more smart about this, it has 
adaptive redzone policy - smaller redzones for small variables, and bigger for 
big.

In this particular case, the best way to reduce stack usage is to refactor the 
code.
1) Drop 'int *up' argument from lnet_ipif_query(). When interface is down 
lnet_ipif_query() sets up to zero and doesn't return error.
   But all callers treat up == 0 as error. So instead, lnet_ipif_query() should 
simply return error code, and 'up' won't be needed.
This will simplify the code, and should drop the stack usage with KASAN and 
without KASAN.

2) Instead of using local ip, mask variables, pass pointers 
'&net->ksnn_interfaces[j].ksni_ipaddr', '&net->ksnn_interfaces[j].ksni_netmask'.
As in 1) this should alst drop the stack usage both with KASAN and without 
KASAN




___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2] android: binder: fix binder mmap failures

2015-02-27 Thread Andrey Ryabinin
binder_update_page_range() initializes only addr and size
fields in 'struct vm_struct tmp_area;' and passes it to
map_vm_area().

Before 71394fe50146 ("mm: vmalloc: add flag preventing guard hole allocation")
this was because map_vm_area() didn't use any other fields
in vm_struct except addr and size.

Now get_vm_area_size() (used in map_vm_area()) reads vm_struct's
flags to determine whether vm area has guard hole or not.

binder_update_page_range() don't initialize flags field, so
this causes following binder mmap failures:
---[ cut here ]
WARNING: CPU: 0 PID: 1971 at mm/vmalloc.c:130
vmap_page_range_noflush+0x119/0x144()
CPU: 0 PID: 1971 Comm: healthd Not tainted 4.0.0-rc1-00399-g7da3fdc-dirty #157
Hardware name: ARM-Versatile Express
[] (unwind_backtrace) from [] (show_stack+0x11/0x14)
[] (show_stack) from [] (dump_stack+0x59/0x7c)
[] (dump_stack) from [] (warn_slowpath_common+0x55/0x84)
[] (warn_slowpath_common) from []
(warn_slowpath_null+0x17/0x1c)
[] (warn_slowpath_null) from []
(vmap_page_range_noflush+0x119/0x144)
[] (vmap_page_range_noflush) from [] (map_vm_area+0x27/0x48)
[] (map_vm_area) from []
(binder_update_page_range+0x12f/0x27c)
[] (binder_update_page_range) from []
(binder_mmap+0xbf/0x1ac)
[] (binder_mmap) from [] (mmap_region+0x2eb/0x4d4)
[] (mmap_region) from [] (do_mmap_pgoff+0x1e7/0x250)
[] (do_mmap_pgoff) from [] (vm_mmap_pgoff+0x45/0x60)
[] (vm_mmap_pgoff) from [] (SyS_mmap_pgoff+0x5d/0x80)
[] (SyS_mmap_pgoff) from [] (ret_fast_syscall+0x1/0x5c)
---[ end trace 48c2c4b9a1349e54 ]---
binder: 1982: binder_alloc_buf failed to map page at f0e0 in kernel
binder: binder_mmap: 1982 b6bde000-b6cdc000 alloc small buf failed -12

Use map_kernel_range_noflush() instead of map_vm_area() as this is better
API for binder's purposes and it allows to get rid of 'vm_struct tmp_area' at 
all.

Fixes: 71394fe50146 ("mm: vmalloc: add flag preventing guard hole allocation")
Signed-off-by: Andrey Ryabinin 
Reported-by: Amit Pundir 
---
 Changes since v1:
   - fixed ret check after map_kernel_ranges_noflush().

 drivers/android/binder.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 33b09b6..6607f3c 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -551,7 +551,6 @@ static int binder_update_page_range(struct binder_proc 
*proc, int allocate,
 {
void *page_addr;
unsigned long user_page_addr;
-   struct vm_struct tmp_area;
struct page **page;
struct mm_struct *mm;
 
@@ -600,10 +599,11 @@ static int binder_update_page_range(struct binder_proc 
*proc, int allocate,
proc->pid, page_addr);
goto err_alloc_page_failed;
}
-   tmp_area.addr = page_addr;
-   tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;
-   ret = map_vm_area(&tmp_area, PAGE_KERNEL, page);
-   if (ret) {
+   ret = map_kernel_range_noflush((unsigned long)page_addr,
+   PAGE_SIZE, PAGE_KERNEL, page);
+   flush_cache_vmap((unsigned long)page_addr,
+   (unsigned long)page_addr + PAGE_SIZE);
+   if (ret != 1) {
pr_err("%d: binder_alloc_buf failed to map page at %p 
in kernel\n",
   proc->pid, page_addr);
goto err_map_kernel_failed;
-- 
2.3.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] android: binder: fix binder mmap failures

2015-02-27 Thread Andrey Ryabinin
On 02/27/2015 08:26 PM, John Stultz wrote:
> On Fri, Feb 27, 2015 at 8:30 AM, Andrey Ryabinin  
> wrote:
>> binder_update_page_range() initializes only addr and size
>> fields in 'struct vm_struct tmp_area;' and passes it to
>> map_vm_area().
>>
>> Before 71394fe50146 ("mm: vmalloc: add flag preventing guard hole 
>> allocation")
>> this was because map_vm_area() didn't use any other fields
>> in vm_struct except addr and size.
>>
>> Now get_vm_area_size() (used in map_vm_area()) reads vm_struct's
>> flags to determine whether vm area has guard hole or not.
>>
>> binder_update_page_range() don't initialize flags field, so
>> this causes following binder mmap failures:
>> ---[ cut here ]
>> WARNING: CPU: 0 PID: 1971 at mm/vmalloc.c:130
>> vmap_page_range_noflush+0x119/0x144()
>> CPU: 0 PID: 1971 Comm: healthd Not tainted 4.0.0-rc1-00399-g7da3fdc-dirty 
>> #157
>> Hardware name: ARM-Versatile Express
>> [] (unwind_backtrace) from [] (show_stack+0x11/0x14)
>> [] (show_stack) from [] (dump_stack+0x59/0x7c)
>> [] (dump_stack) from [] (warn_slowpath_common+0x55/0x84)
>> [] (warn_slowpath_common) from []
>> (warn_slowpath_null+0x17/0x1c)
>> [] (warn_slowpath_null) from []
>> (vmap_page_range_noflush+0x119/0x144)
>> [] (vmap_page_range_noflush) from [] 
>> (map_vm_area+0x27/0x48)
>> [] (map_vm_area) from []
>> (binder_update_page_range+0x12f/0x27c)
>> [] (binder_update_page_range) from []
>> (binder_mmap+0xbf/0x1ac)
>> [] (binder_mmap) from [] (mmap_region+0x2eb/0x4d4)
>> [] (mmap_region) from [] (do_mmap_pgoff+0x1e7/0x250)
>> [] (do_mmap_pgoff) from [] (vm_mmap_pgoff+0x45/0x60)
>> [] (vm_mmap_pgoff) from [] (SyS_mmap_pgoff+0x5d/0x80)
>> [] (SyS_mmap_pgoff) from [] (ret_fast_syscall+0x1/0x5c)
>> ---[ end trace 48c2c4b9a1349e54 ]---
>> binder: 1982: binder_alloc_buf failed to map page at f0e0 in kernel
>> binder: binder_mmap: 1982 b6bde000-b6cdc000 alloc small buf failed -12
>>
>> Use map_kernel_range_noflush() instead of map_vm_area() as this is better
>> API for binder's purposes and it allows to get rid of 'vm_struct tmp_area' 
>> at all.
>>
>> Fixes: 71394fe50146 ("mm: vmalloc: add flag preventing guard hole 
>> allocation")
>> Signed-off-by: Andrey Ryabinin 
>> Reported-by: Amit Pundir 
>> ---
>>  drivers/android/binder.c | 8 
>>  1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/android/binder.c b/drivers/android/binder.c
>> index 33b09b6..a984fbb 100644
>> --- a/drivers/android/binder.c
>> +++ b/drivers/android/binder.c
>> @@ -551,7 +551,6 @@ static int binder_update_page_range(struct binder_proc 
>> *proc, int allocate,
>>  {
>> void *page_addr;
>> unsigned long user_page_addr;
>> -   struct vm_struct tmp_area;
>> struct page **page;
>> struct mm_struct *mm;
>>
>> @@ -600,9 +599,10 @@ static int binder_update_page_range(struct binder_proc 
>> *proc, int allocate,
>> proc->pid, page_addr);
>> goto err_alloc_page_failed;
>> }
>> -   tmp_area.addr = page_addr;
>> -   tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;
>> -   ret = map_vm_area(&tmp_area, PAGE_KERNEL, page);
>> +   ret = map_kernel_range_noflush((unsigned long)page_addr,
>> +   PAGE_SIZE, PAGE_KERNEL, page);
>> +   flush_cache_vmap((unsigned long)page_addr,
>> +   (unsigned long)page_addr + PAGE_SIZE);
>> if (ret) {
>> pr_err("%d: binder_alloc_buf failed to map page at 
>> %p in kernel\n",
>>proc->pid, page_addr);
> 
> So with this patch I don't see the warnings, but I'm still seeing:
> [   11.154283] binder: 1956: binder_alloc_buf failed to map page at
> f034 in kernel
> [   11.154916] binder: binder_mmap: 1956 b6ce-b6d0 alloc small
> buf failed -12
> 
> over and over.  So I don't think this patch is quite right.
> 

Thanks.

Seems that error check is wrong now.
map_vm_area() returns 0 on success, map_kernel_range_noflush() number of mapped 
pages.

> thanks
> -john
> 

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] android: binder: fix binder mmap failures

2015-02-27 Thread Andrey Ryabinin
binder_update_page_range() initializes only addr and size
fields in 'struct vm_struct tmp_area;' and passes it to
map_vm_area().

Before 71394fe50146 ("mm: vmalloc: add flag preventing guard hole allocation")
this was because map_vm_area() didn't use any other fields
in vm_struct except addr and size.

Now get_vm_area_size() (used in map_vm_area()) reads vm_struct's
flags to determine whether vm area has guard hole or not.

binder_update_page_range() don't initialize flags field, so
this causes following binder mmap failures:
---[ cut here ]
WARNING: CPU: 0 PID: 1971 at mm/vmalloc.c:130
vmap_page_range_noflush+0x119/0x144()
CPU: 0 PID: 1971 Comm: healthd Not tainted 4.0.0-rc1-00399-g7da3fdc-dirty #157
Hardware name: ARM-Versatile Express
[] (unwind_backtrace) from [] (show_stack+0x11/0x14)
[] (show_stack) from [] (dump_stack+0x59/0x7c)
[] (dump_stack) from [] (warn_slowpath_common+0x55/0x84)
[] (warn_slowpath_common) from []
(warn_slowpath_null+0x17/0x1c)
[] (warn_slowpath_null) from []
(vmap_page_range_noflush+0x119/0x144)
[] (vmap_page_range_noflush) from [] (map_vm_area+0x27/0x48)
[] (map_vm_area) from []
(binder_update_page_range+0x12f/0x27c)
[] (binder_update_page_range) from []
(binder_mmap+0xbf/0x1ac)
[] (binder_mmap) from [] (mmap_region+0x2eb/0x4d4)
[] (mmap_region) from [] (do_mmap_pgoff+0x1e7/0x250)
[] (do_mmap_pgoff) from [] (vm_mmap_pgoff+0x45/0x60)
[] (vm_mmap_pgoff) from [] (SyS_mmap_pgoff+0x5d/0x80)
[] (SyS_mmap_pgoff) from [] (ret_fast_syscall+0x1/0x5c)
---[ end trace 48c2c4b9a1349e54 ]---
binder: 1982: binder_alloc_buf failed to map page at f0e0 in kernel
binder: binder_mmap: 1982 b6bde000-b6cdc000 alloc small buf failed -12

Use map_kernel_range_noflush() instead of map_vm_area() as this is better
API for binder's purposes and it allows to get rid of 'vm_struct tmp_area' at 
all.

Fixes: 71394fe50146 ("mm: vmalloc: add flag preventing guard hole allocation")
Signed-off-by: Andrey Ryabinin 
Reported-by: Amit Pundir 
---
 drivers/android/binder.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 33b09b6..a984fbb 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -551,7 +551,6 @@ static int binder_update_page_range(struct binder_proc 
*proc, int allocate,
 {
void *page_addr;
unsigned long user_page_addr;
-   struct vm_struct tmp_area;
struct page **page;
struct mm_struct *mm;
 
@@ -600,9 +599,10 @@ static int binder_update_page_range(struct binder_proc 
*proc, int allocate,
proc->pid, page_addr);
goto err_alloc_page_failed;
}
-   tmp_area.addr = page_addr;
-   tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;
-   ret = map_vm_area(&tmp_area, PAGE_KERNEL, page);
+   ret = map_kernel_range_noflush((unsigned long)page_addr,
+   PAGE_SIZE, PAGE_KERNEL, page);
+   flush_cache_vmap((unsigned long)page_addr,
+   (unsigned long)page_addr + PAGE_SIZE);
if (ret) {
pr_err("%d: binder_alloc_buf failed to map page at %p 
in kernel\n",
   proc->pid, page_addr);
-- 
2.3.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel