0

I am a beginner in the field of Linux kernel programming. I was studying Linux Security Modules (LSM). The references which I have seen (recent ones) especially this video here, bakes the module written into the kernel itself, and then the entire compiled kernel is installed on say an Ubuntu machine.

I was thinking of writing a program, such that instead of making it into the kernel itself, I could load and unload it as per my need. (Especially to test the correctness of its functionality, easily).

The video which I have mentioned above makes use of security_add_hooks to bind our function to the security subsystem. But, using the mention of security_add_hooks and LSM_HOOK_INIT which in turn uses security_hook_heads struct, causes an issue when I try to make a .ko file for this module.

ERROR: modpost: "security_add_hooks" [security/my_test.ko] undefined!
ERROR: modpost: "security_hook_heads" [security/my_test.ko] undefined!

I can understand that security_add_hooks is a function and has not been exported for use by the modules. So, I tried to EXPORT_SYMBOL(security_add_hooks) so that my .ko file can use it.

But another issue arises. Regarding two struct definitions, security_hook_heads and security_hook_list. I simply don't know how to export them. I tried to write a statement EXPORT_SYMBOL(security_hook_heads); just after the corresponding struct definition as follows, in lsm_hooks.h:

struct security_hook_heads {
    #define LSM_HOOK(RET, DEFAULT, NAME, ...) struct hlist_head NAME;
    #include "lsm_hook_defs.h"
    #undef LSM_HOOK
} __randomize_layout;

EXPORT_SYMBOL(security_hook_heads);

Corresponding to this I get the following error:

./include/linux/lsm_hooks.h:1601:15: error: ‘security_hook_heads’ undeclared here (not in a function)
 1601 | EXPORT_SYMBOL(security_hook_heads);

I don't fully understand the meaning of the error, but I feel it is trying to point out that exporting a symbol from a header file is not possible.

So, I could not figure out how to work out this approach. Is there any other easy method available?

I was going through a few old YouTube videos and a few articles, where they make use of functions like register_security and unregister_security, but I guess these functions are no longer there in the latest Linux kernel (6.0.0). [As was mentioned in the thread of the following few questions: (1), see the comment to the answer for the previous question, (2)]

Abhishek Ghosh
  • 597
  • 7
  • 18
  • 1
    pretty sure AppArmor uses a loadable module. Check how it works. – stark Oct 24 '22 at 14:15
  • @stark, I looked into the `lsm.c` file in the AppArmor folder in the security subsystem. I am using kernel 6.0.0, there on line `1205` they define an array of `struct security_hook_list` and uses `LSM_HOOK_INIT` to initialize that array, and `LSM_HOOK_INIT` is a macro which uses `security_hook_head`. Also, in the `apparmor_init(void)` function, on line `1899` they make use of `security_add_hooks` function, which is not exported, so I guess, that issue remains, I am facing, as far as I can understand from my knowledge. Please could you guide me further? – Abhishek Ghosh Oct 24 '22 at 15:11

1 Answers1

2

You can't do this in a module.

  1. security_add_hooks is marked with __init.
  2. It is linked into a special linker section (e.g. .init.text).
  3. At a certain point in the kernel startup (see: kernel_init) it calls free_initmem.
  4. After that, the memory occupied by these functions is reclaimed and can be used as ordinary memory.

So, by the time your module is loaded, security_add_hooks et. al. are long gone.

If you have to modify security/security.c to add EXPORT_SYMBOL(security_add_hooks), then you are building a custom kernel. So, you might as well just bake your code into the kernel.

Craig Estey
  • 30,627
  • 4
  • 24
  • 48