Messages in this thread | | | From | Alexander Potapenko <> | Date | Wed, 11 Nov 2020 12:48:01 +0100 | Subject | Re: [PATCH v4 1/2] security: add fault injection capability |
| |
On Wed, Nov 11, 2020 at 11:45 AM Aleksandr Nogikh <a.nogikh@gmail.com> wrote: > > From: Aleksandr Nogikh <nogikh@google.com> > > Add a fault injection capability to call_int_hook macro. This will > facilitate testing of fault tolerance of the code that invokes > security hooks as well as the fault tolerance of the LSM > implementations themselves. > > Add a KConfig option (CONFIG_FAIL_LSM_HOOKS) that controls whether the > capability is enabled. In order to enable configuration from the user > space, add the standard debugfs entries for fault injection (if > CONFIG_FAULT_INJECTION_DEBUG_FS is enabled). > > Signed-off-by: Aleksandr Nogikh <nogikh@google.com> > Reviewed-by: Marco Elver <elver@google.com> > Reviewed-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> > Reviewed-by: Andrey Konovalov <andreyknvl@google.com> Reviewed-by: Alexander Potapenko <glider@google.com>
> --- > v4: > - Changed retval debugfs file type - now it keeps a signed integer. > - Made CONFIG_FAIL_LSM_HOOKS depend on CONFIG_SECURITY. > v2: > - Renamed should_fail_lsm_hook() to lsm_hooks_inject_fail(). > --- > lib/Kconfig.debug | 6 ++++ > security/security.c | 69 +++++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 72 insertions(+), 3 deletions(-) > > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug > index 6140413174be..5f4399816019 100644 > --- a/lib/Kconfig.debug > +++ b/lib/Kconfig.debug > @@ -1813,6 +1813,12 @@ config FAIL_MAKE_REQUEST > help > Provide fault-injection capability for disk IO. > > +config FAIL_LSM_HOOKS > + bool "Fault-injection capability for LSM hooks" > + depends on FAULT_INJECTION && SECURITY > + help > + Provide fault-injection capability for LSM hooks. > + > config FAIL_IO_TIMEOUT > bool "Fault-injection capability for faking disk interrupts" > depends on FAULT_INJECTION && BLOCK > diff --git a/security/security.c b/security/security.c > index 69ff6e2e2cd4..be3a3c7c6d6a 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -28,6 +28,7 @@ > #include <linux/backing-dev.h> > #include <linux/string.h> > #include <linux/msg.h> > +#include <linux/fault-inject.h> > #include <net/flow.h> > > #define MAX_LSM_EVM_XATTR 2 > @@ -669,6 +670,67 @@ static void __init lsm_early_task(struct task_struct *task) > panic("%s: Early task alloc failed.\n", __func__); > } > > + > +#ifdef CONFIG_FAIL_LSM_HOOKS > + > +static struct { > + struct fault_attr attr; > + int retval; > +} fail_lsm_hooks = { > + .attr = FAULT_ATTR_INITIALIZER, > + .retval = -EACCES > +}; > + > +static int __init setup_fail_lsm_hooks(char *str) > +{ > + return setup_fault_attr(&fail_lsm_hooks.attr, str); > +} > +__setup("fail_lsm_hooks=", setup_fail_lsm_hooks); > + > +static int lsm_hooks_inject_fail(void) > +{ > + return should_fail(&fail_lsm_hooks.attr, 1) ? fail_lsm_hooks.retval : 0; > +} > + > +#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS > + > +static int fail_lsm_retval_set(void *data, u64 val) > +{ > + fail_lsm_hooks.retval = (int)val; > + return 0; > +} > + > +static int fail_lsm_retval_get(void *data, u64 *val) > +{ > + *val = (u64)fail_lsm_hooks.retval; > + return 0; > +} > + > +DEFINE_DEBUGFS_ATTRIBUTE(fail_lsm_retval_ops, fail_lsm_retval_get, > + fail_lsm_retval_set, "%lld\n"); > + > +static int __init fail_lsm_hooks_debugfs(void) > +{ > + umode_t mode = S_IFREG | 0600; > + struct dentry *dir; > + > + dir = fault_create_debugfs_attr("fail_lsm_hooks", NULL, > + &fail_lsm_hooks.attr); > + debugfs_create_file("retval", mode, dir, NULL, > + &fail_lsm_retval_ops); > + return 0; > +} > + > +late_initcall(fail_lsm_hooks_debugfs); > + > +#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ > + > +#else > + > +static inline int lsm_hooks_inject_fail(void) { return 0; } > + > +#endif /* CONFIG_FAIL_LSM_HOOKS */ > + > /* > * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and > * can be accessed with: > @@ -707,16 +769,17 @@ static void __init lsm_early_task(struct task_struct *task) > } while (0) > > #define call_int_hook(FUNC, IRC, ...) ({ \ > - int RC = IRC; \ > - do { \ > + int RC = lsm_hooks_inject_fail(); \ > + if (RC == 0) { \ > struct security_hook_list *P; \ > + RC = IRC; \ > \ > hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ > RC = P->hook.FUNC(__VA_ARGS__); \ > if (RC != 0) \ > break; \ > } \ > - } while (0); \ > + } \ > RC; \ > }) > > -- > 2.29.2.222.g5d2a92d10f8-goog >
-- Alexander Potapenko Software Engineer
Google Germany GmbH Erika-Mann-Straße, 33 80636 München
Geschäftsführer: Paul Manicle, Halimah DeLaine Prado Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg
| |