debug bpf code on netlink messages - debugging

I am writing a bpf filter to prevent certain netlink messages. I am trying to debug the bpf code. Is there any debug tool that could help me?
I was initially thinking of using nlmon to capture netlink messages:
From https://jvns.ca/blog/2017/09/03/debugging-netlink-requests/
# create the network interface
sudo ip link add nlmon0 type nlmon
sudo ip link set dev nlmon0 up
sudo tcpdump -i nlmon0 -w netlink.pcap # capture your packets
Then use ./bpf_dbg (
https://github.com/cloudflare/bpftools/blob/master/linux_tools/bpf_dbg.c)
1) ./bpf_dbg to enter the shell (shell cmds denoted with '>'):
2) > load bpf 6,40 0 0 12,21 0 3 20... (this is the bpf code I intend to debug)
3) > load pcap netlink.pcap
4) > run /disassemble/dump/quit (self-explanatory)
5) > breakpoint 2 (sets bp at loaded BPF insns 2, do run then;
multiple bps can be set, of course, a call to breakpoint
w/o args shows currently loaded bps, breakpoint reset for
resetting all breakpoints)
6) > select 3 (run etc will start from the 3rd packet in the pcap)
7) > step [-, +] (performs single stepping through the BPF)
Did anyone try this before?
Also, I was not able to make nlmon module to load on my linux kernel(Is there a doc for this?)
I am running kernel version Linux version 4.10.0-40-generic
The nlmon module seems to be present in the kernel source:
https://elixir.free-electrons.com/linux/v4.10/source/drivers/net/nlmon.c#L41
But, when I search inside, /lib/modules/ for nlmon.ko I dont find anything.
instance-1:/lib/modules$ find . | grep -i nlmon
instance-1:/lib/modules$

Related

Limit on number of wireless "sta" stations in openwrt

I have openwrt implementation on a TPLink WR902AC (pocket router)
I have a /etc/network/wireless configuration file with 10 sta configurations for connecting to AP all of which are active (option disabled '0')
This is to ensure that openwrt connects to any one of the APs configured.
Only the first 4 configured are attempted to be connected and the rest are simply ignored.
(if first 4 configured are not available the 5th one is being ignored)
I tried to identify the bottleneck.
Only first 4 wpa_supplicant instances are called as evident from these files in /tmp/run
./tmp/run/wpa_supplicant/wifi3
./tmp/run/wpa_supplicant/wifi1
./tmp/run/wpa_supplicant/wifi2
./tmp/run/wpa_supplicant/wifi0
When I disable the first one, the fifth one gets connected on reconnect with "wifi"
I tried to check the source code. I lost the track after ubus being called from wifi script.
This I believe is similar question to https://forum.openwrt.org/t/limit-on-the-number-of-wifi-ssids/63141
iw list on openwrt show me the limit.
valid interface combinations:
* #{ IBSS } <= 1, #{ managed, AP, mesh point, P2P-client, P2P-GO } <= 4,
total <= 4, #channels <= 1, STA/AP BI must match
I tried to use wpa_supplicant directly instead of depending on scripts.
wpa_supplicant -c /root/wifi0.conf -i wifi0 -s -B
wpa_supplicant -c /root/wifi1.conf -i wifi1 -s -B
wpa_supplicant -c /root/wifi2.conf -i wifi2 -s -B
wpa_supplicant -c /root/wifi3.conf -i wifi3 -s -B
wpa_supplicant -c /root/wifi4.conf -i wifi4 -s -B
wpa_supplicant -c /root/wifi5.conf -i wifi5 -s -B
This failed with "interface wifi4" not available error.
Could someone point me to the source where this hard limit is set?
Is there any way around this?
Thanks in advance.
Update:-
mt7601u based usb WiFi dongle was added to wr902ac and configured (as radio2)
This time only one is connected. If I have AP configured, sta doesn't even get connected.
so number of slots is limited. (ap counts as one slot and each sta is one slot)
The built-in 2.4 GHZ has 4 slots & 5 GHz has 8 slots.
The mt7601u based wifi has only 1 slot.
Probably there exists a usb dongle that has 8 slots. Could someone point me to the theory behind all this?

How to trace dynamic instruction in spike (on RISC-V)

I’m new for spike and RISC V. I’m trying to do some dynamic instruction trace with spike. These instructions are from a sample.c file. I have tried the following commands:
$ riscv64-unknown-elf-gcc simple.c -g -o simple.out
$ riscv64-unknown-elf-objdump -d --line-numbers -S simple.out
But these commands display the assembled instructions in an out file, which is not I want. I need to trace the dynamic executed instruction in runtime. I find only two relative commands in spike host option:
-g - track histogram of PCs
-l - generate a log of execution
I’m not sure if the result is what I expected as above.
Does anyone have an idea how to do the dynamic instruction trace in spike?
Thanks a lot!
Yes, you can call spike with -l to get a trace of all executed instructions.
Example:
$ spike -l --isa=RV64gc ~/riscv/pk/riscv64-unknown-elf/bin/pk ./hello 2> ins.log
Note that this trace also contains all instructions executed by the proxy-kernel - rather than just the trace of your user program.
The trace can still be useful, e.g. you can search for the start address of your code (i.e. look it up in the objdump output) and consume the trace from there.
Also, when your program invokes a syscall you see something like this in the trace:
[.. inside your program ..]
core 0: 0x0000000000010088 (0x00000073) ecall
core 0: exception trap_user_ecall, epc 0x0000000000010088
core 0: 0x0000000080001938 (0x14011173) csrrw sp, sscratch, sp
[.. inside the pk ..]
sret
[.. inside your program ..]
That means you can skip to the sycall instruction (that are executed in the pk) by searching for the next sret.
Alternatively, you can call spike with -d to enter debug mode. Then you can set a breakpoint on the first instruction of interest in your program (until pc 0 YOURADDRESS - look up the address in the objdump output) and single step from there (by hitting return multiple times). See also the help screen by entering h at the spike prompt.

How to make cpuset.cpu_exclusive function of cpuset work correctly

I'm trying to use the kernel's cpuset to isolate my process. To obtain this, I follow the instructions(2.1 Basic Usage) from kernel doc cpusets, however, it didn't work in my environment.
I have tried in both my centos7 server and my ubuntu16.04 work pc, but neither did work.
centos kernel version:
[root#node ~]# uname -r
3.10.0-327.el7.x86_64
ubuntu kernel version:
4.15.0-46-generic
What I have tried is as follows.
root#Latitude:/sys/fs/cgroup/cpuset# pwd
/sys/fs/cgroup/cpuset
root#Latitude:/sys/fs/cgroup/cpuset# cat cpuset.cpus
0-3
root#Latitude:/sys/fs/cgroup/cpuset# cat cpuset.mems
0
root#Latitude:/sys/fs/cgroup/cpuset# cat cpuset.cpu_exclusive
1
root#Latitude:/sys/fs/cgroup/cpuset# cat cpuset.mem_exclusive
1
root#Latitude:/sys/fs/cgroup/cpuset# find . -name cpuset.cpu_excl
usive | xargs cat
0
0
0
0
0
1
root#Latitude:/sys/fs/cgroup/cpuset# mkdir my_cpuset
root#Latitude:/sys/fs/cgroup/cpuset# echo 1 > my_cpuset/cpuset.cpus
root#Latitude:/sys/fs/cgroup/cpuset# echo 0 > my_cpuset/cpuset.mems
root#Latitude:/sys/fs/cgroup/cpuset# echo 1 > my_cpuset/cpuset.cpu_exclusive
bash: echo: write error: Invalid argument
root#Latitude:/sys/fs/cgroup/cpuset#
It just printed the error bash: echo: write error: Invalid argument.
Google it, however, I can't get the correct answers.
As I pasted above, before my operation, I confirmed that the cpuset root path have enabled the cpu_exclusive function and all the cpus are not been excluded by other sub-cpuset.
By using ps -o pid,psr,comm -p $PID, I can confirm that the cpus can be assigned to some process if I don't care cpu_exclusive. But I have also proved that if cpu_exclusive is not set, the same cpus can also be assigned to another processes.
I don't know if it is because some pre-setting are missed.
What I expected is "using cpuset to obtain exclusive use of cpus". Can anyboy give any clues?
Thanks very much.
i believe it is a mis-understanding of cpu_exclusive flag, as i did. Here is the doc https://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt, quoting:
If a cpuset is cpu or mem exclusive, no other cpuset, other than
a direct ancestor or descendant, may share any of the same CPUs or
Memory Nodes.
so one possible reason you have bash: echo: write error: Invalid argument, is that you have some other cgroup cpuset enabled, and it conflicts with your operations of echo 1 > my_cpuset/cpuset.cpu_exclusive
please run find . -name cpuset.cpus | xargs cat to list all your cgroup's target cpus.
assume you have 12 cpus, if you want to set cpu_exclusive of my_cpuset, you need to carefully modify all the other cgroups to use cpus, eg. 0-7, then set cpus of my_cpuset to be 8-11. After all these cpus configurations , you can set cpu_exclusive to be 1.
But still, other process can still use cpu 8-11. Only the tasks that belongs to the other cgroups will not use cpu 8-11
for me, i had some docker container running, which prevents me from setting my cpuset cpu_exclusive
with kernel doc, i do not think it is possible to use cpus exclusively by cgroup itself. One approach (i know this approach is running on production) is that we isolate cpus, and manage the cpu affinity/cpuset by ourselves

debugging postgres (and external .so libraries) with kdbg (KDE Debugger in Lilnux)

I would like to debug a user defined function (called prepareTheOutputRecord implemented in C/C++ that is a part of user defined function in postgres. Here's how I achieve this with gdb:
The function prepareTheOutputRecord resides in libMyExtenstion.so file in the lib directory of postgresql server
I start the psql shell, retrieve the pid of the process
postgres=# SELECT pg_backend_pid();
pg_backend_pid
- - - - - - - - - - - - - -
4120
(1 row)
Run the gdb with the attached pid:
gdb -p 4120
Search now the .so file, how the function is exactly called:
nm -as libMyExtenstion.so | grep prepareTheOputRecord
00000000002633fe t _ZN6libafd6LIBAFD22prepareTheOutputRecordEP20FunctionCallInfoData
Set a breakpoint in gdb and run the program:
(gdb) b _ZN6libafd6LIBAFD22prepareTheOutputRecordEP20FunctionCallInfoData
Function "_ZN6libafd6LIBAFD22prepareTheOutputRecordEP20FunctionCallInfoData" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (_ZN6libafd6LIBAFD22prepareTheOutputRecordEP20FunctionCallInfoData) pending.
(gdb) c
Execute the SQL in psql. At a certain point the breakpoint is hit in gdb:
Breakpoint 1, prepareTheOutputRecord (this=0x1116410, fcinfo=0x7fff3a41e150)
at ../Dir/file.cpp:1736
1736 funcctx = SRF_PERCALL_SETUP();
(gdb)
Continue debugging the code.
I want to do exactly the same in kdbg. For that I loaded the postgres executable, attached to the process, loaded the cpp file, set the breakpoint with the mouse at the function, continued the execution of the postgres process, but the breakpoint was never hit :( I repeated the same with .so file (instead of postgres executable) without any success. I even tried to set the breakpoint to _ZN6libafd6LIBAFD22prepareTheOutputRecordEP20FunctionCallInfoData (without the mouse clicks) but the program does not stop in kdbg :(
I believe the problem was that the kdb was not run as the root (or postgres). Due to wrong permissions the symbols were not loaded and therefore no breakpoint was shown (nor allowed to be placed at a function)

How to view the GDTR's value?

In the book "Rootkit Arsenal" page 84 (Chapter 3) mentions:
..., we can view the contents of the
target machine's descriptor registers
using the command with the 0x100 mask:
kd> rM 0x100
and a paragraph below:
Note that the same task can be
accomplished by specifying the GDTR
components explicitly: kd> r gdtr ....
I run Windbg on my Win XP (inside VMWare) and choose the Kernel Debug -> Local.
My problem is in case of first command, windbg errors with:
lkd> rM 0x100
^ Operation not supported in current debug session 'rM 0x100'
and in the second command:
lkd> r gdtr
^ Bad register error in 'r gdtr'
Can anyone guide me ?
Right, you can't look at registers in a local kernel debug session. LiveKD works and you can also get the address indirectly through the PCR (!pcr).
-scott
I think I've found the solution:
Use two computers for kernel debugging instead of Local Kernel Debug.
(I used VMWare and am debugging through the COM port/named pipe)
I am thinking why this facility/feature (Local Kernel Debugging) is there if it's not complete ?

Resources