[PATCH] dbg: allow override any function with bpf_error_injection

From: Huang Ying
Date: Mon Sep 19 2022 - 21:08:25 EST


---
lib/error-inject.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/lib/error-inject.c b/lib/error-inject.c
index 1afca1b1cdea..82a402e0f15c 100644
--- a/lib/error-inject.c
+++ b/lib/error-inject.c
@@ -21,6 +21,7 @@ struct ei_entry {
void *priv;
};

+#if 0
bool within_error_injection_list(unsigned long addr)
{
struct ei_entry *ent;
@@ -36,6 +37,12 @@ bool within_error_injection_list(unsigned long addr)
mutex_unlock(&ei_mutex);
return ret;
}
+#else
+bool within_error_injection_list(unsigned long addr)
+{
+ return true;
+}
+#endif

int get_injectable_error_type(unsigned long addr)
{
--
2.35.1
----------------------------------------------------------

With this debug patch, most error path can be tested. For example,

--------------------ENOSYS THP + EAGAIN----------
#include <linux/mm.h>
kprobe:migrate_pages { @in_migrate_pages++; }
kretprobe:migrate_pages { @in_migrate_pages--; }
kprobe:unmap_and_move / @in_migrate_pages > 0 / {
if (((struct page *)arg3)->flags & (1 << PG_head)) {
override(-38);
} else {
override(-11);
}
}
-------------------------------------------------

With this, unmap_and_move() will return -ENOSYS (-38) for THP, and
-EAGAIN (-11) for normal page. This can be used to test the
corresponding error path in migrate_pages().

I think that it's quite common for developers to inject error for
arbitrary function to test the error path. Is it a good idea to turn on
the arbitrary error injection if a special kernel configuration
(e.g. CONFIG_BPF_KPROBE_OVERRIDE_ANY_FUNCTION) is enabled for debugging
purpose only?

Some hacks are still necessary for complete coverage
====================================================

Even if we can override the return value of any function. Some hacks
are still necessary for complete coverage. For example, some functions
may be inlined, if we want to override its return value, we need to mark
it with "noinline". And some error cannot be injected with return value
overridden directly. For example, if we want to test when THP split
isn't allowed condition in migrate_pages(). Then, some hack patch need
to be used to do that. For example, the below patch can do that.

-----------------------8<---------------------------------