воскресенье, 31 марта 2024 г.

netfilter hooks

They can be used to run shell when received some magic packet: 1 2 3. As usually there is not tool to show installed netfilter hooks so I added dumping them (and at the same time netfilter loggers) to my lkcd
 
Lets check where this hooks live inside kernel. As starting point we can review source of main function for hooks installing nf_register_net_hooks which leads to nf_hook_entry_head. We can notice that there are lots of locations for hooks:
  1. field nf_hooks_ingress in net_dev (when CONFIG_NETFILTER_INGRESS enabled)
  2. on more new kernels also field nf_hooks_egress in net_dev (when CONFIG_NETFILTER_EGRESS enabled)
  3. lots of fields in struct netns_nf:
    • hooks_ipv4
    • hooks_ipv6
    • hooks_arp (CONFIG_NETFILTER_FAMILY_ARP)
    • hooks_bridge (CONFIG_NETFILTER_FAMILY_BRIDGE)
    • hooks_decnet (CONFIG_NETFILTER_FAMILY_DECNET)
    Also on old kernels (before 4.16) there was one array hooks in netns_nf
 
results
lkmem -c -n ../unpacked/101 /boot/System.map-5.15.0-101-generic
...
2 nf hooks:
   [0] type 02 IPV4 idx 0 0xffffffffa7b84dd0 - kernel!apparmor_ipv4_postroute
   [1] type 10 IPV6 idx 0 0xffffffffa7b84e10 - kernel!apparmor_ipv6_postroute

пятница, 8 марта 2024 г.

Profiling shared libraries on linux

Disclaimer: proposed approach uses dirty hacks & patches and tested on x86_64 only so use it at your own risk. Also no chatGPT or some another Artificial Idiots were used for this research

Lets assume that we have shared library (for example R extension or python module) and we want to know where and why it spending many hours and consuming megawatts of electricity. There is even semi-official way to do this:

  1. compile shared library with -pg option
  2. set envvar LD_PROFILE_OUTPUT to directory where you want to store profiling data
  3. set envvar LD_PROFILE to filename of library to profile
  4. run your program. Well, sounds that you need lots of things to do before this step and you can`t set up profiling dynamically
  5. run sprof on profiling log

Unfortunately this method just don`t work - sprof fails with cryptic message
Inconsistency detected by ld.so: dl-open.c: 890: _dl_open: Assertion `_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT' failed!

Seems that this long lived bug known since 2017 and still not fixed
Lets try to discover some more reliable way and start with inspection of code generated for profiling