[Devel] [PATCH RHEL7 COMMIT] kasan: update reported bug types for not user nor kernel memory accesses

Vladimir Davydov vdavydov at virtuozzo.com
Tue Sep 8 08:30:57 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-229.7.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.6.8
------>
commit db82a1a67676d9e2a7cb677acf426a3a5686c1d5
Author: Andrey Konovalov <andreyknvl at google.com>
Date:   Tue Sep 8 19:30:57 2015 +0400

    kasan: update reported bug types for not user nor kernel memory accesses
    
    Each access with address lower than kasan_shadow_to_mem(KASAN_SHADOW_START)
    is reported as user-memory-access. This is not always true, the accessed
    address might not be in user space. Fix this by reporting such accesses as
    null-ptr-derefs or wild-memory-accesses.
    
    There's another reason for this change. For userspace ASan we have a bunch
    of systems that analyze error types for the purpose of classification
    and deduplication. Sooner of later we will write them to KASAN as well.
    Then clearly and explicitly stated error types will bring value.
    
    https://jira.sw.ru/browse/PSBM-39339
    
    Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
    Signed-off-by: Andrey Ryabinin <aryabinin at odin.com>
    Reviewed-by: Vladimir Davydov <vdavydov at parallels.com>
---
 mm/kasan/kasan.c  |  8 +-------
 mm/kasan/kasan.h  |  3 ---
 mm/kasan/report.c | 45 +++++++++++++++++++++++----------------------
 3 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index 6c513a63ea84..d6798bc8946b 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -236,18 +236,12 @@ static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size)
 static __always_inline void check_memory_region(unsigned long addr,
 						size_t size, bool write)
 {
-	struct kasan_access_info info;
-
 	if (unlikely(size == 0))
 		return;
 
 	if (unlikely((void *)addr <
 		kasan_shadow_to_mem((void *)KASAN_SHADOW_START))) {
-		info.access_addr = (void *)addr;
-		info.access_size = size;
-		info.is_write = write;
-		info.ip = _RET_IP_;
-		kasan_report_user_access(&info);
+		kasan_report(addr, size, write, _RET_IP_);
 		return;
 	}
 
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 4986b0acab21..14cdff32e02e 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -55,9 +55,6 @@ struct kasan_global {
 #endif
 };
 
-void kasan_report_error(struct kasan_access_info *info);
-void kasan_report_user_access(struct kasan_access_info *info);
-
 static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
 {
 	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 680ceedf810a..ad69bac8aa45 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -182,34 +182,34 @@ static void print_shadow_for_address(const void *addr)
 
 static DEFINE_SPINLOCK(report_lock);
 
-void kasan_report_error(struct kasan_access_info *info)
+static void kasan_report_error(struct kasan_access_info *info)
 {
 	unsigned long flags;
+	const char *bug_type;
 
 	spin_lock_irqsave(&report_lock, flags);
 	pr_err("================================="
 		"=================================\n");
-	print_error_description(info);
-	print_address_description(info);
-	print_shadow_for_address(info->first_bad_addr);
-	pr_err("================================="
-		"=================================\n");
-	spin_unlock_irqrestore(&report_lock, flags);
-}
-
-void kasan_report_user_access(struct kasan_access_info *info)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&report_lock, flags);
-	pr_err("================================="
-		"=================================\n");
-	pr_err("BUG: KASan: user-memory-access on address %p\n",
-		info->access_addr);
-	pr_err("%s of size %zu by task %s/%d\n",
-		info->is_write ? "Write" : "Read",
-		info->access_size, current->comm, task_pid_nr(current));
-	dump_stack();
+	if (info->access_addr <
+			kasan_shadow_to_mem((void *)KASAN_SHADOW_START)) {
+		if ((unsigned long)info->access_addr < PAGE_SIZE)
+			bug_type = "null-ptr-deref";
+		else if ((unsigned long)info->access_addr < TASK_SIZE)
+			bug_type = "user-memory-access";
+		else
+			bug_type = "wild-memory-access";
+		pr_err("BUG: KASan: %s on address %p\n",
+			bug_type, info->access_addr);
+		pr_err("%s of size %zu by task %s/%d\n",
+			info->is_write ? "Write" : "Read",
+			info->access_size, current->comm,
+			task_pid_nr(current));
+		dump_stack();
+	} else {
+		print_error_description(info);
+		print_address_description(info);
+		print_shadow_for_address(info->first_bad_addr);
+	}
 	pr_err("================================="
 		"=================================\n");
 	spin_unlock_irqrestore(&report_lock, flags);
@@ -227,6 +227,7 @@ void kasan_report(unsigned long addr, size_t size,
 	info.access_size = size;
 	info.is_write = is_write;
 	info.ip = ip;
+
 	kasan_report_error(&info);
 }
 



More information about the Devel mailing list