I've just compiled BPF examples from kernel tools/testing/selftests/bpf and tried to load as explained in http://cilium.readthedocs.io/en/v0.10/bpf/:
% tc filter add dev enp0s1 ingress bpf \
object-file ./net-next.git/tools/testing/selftests/bpf/sockmap_parse_prog.o \
section sk_skb1 verbose
Program section 'sk_skb1' not found in ELF file!
Error fetching program/map!
This happens on Ubuntu 16.04.3 LTS with kernel 4.4.0-98, llvm and clang of version 3.8 installed from packages, iproute2 is the latest from github.
I suspect I'm running into some toolchain/kernel version/features mismatch.
What am I doing wrong?
I do not know why tc complains. On my setup, with a similar command, the program loads. Still, here are some hints:
I think the problem might come, as you suggest, from some incompatibility between kernel headers version and iproute2, and that some relocation fails to occur, although on a quick investigation I did not find exactly why it refuses to load the section. On my side I'm using clang-3.8, latest iproute2, but also the latest kernel (some commit close to 4.14).
If you manage to load the section somehow, I believe you would still encounter problems when trying to attach the program in the kernel. The feature called “direct packet access” is only present on kernels 4.7 and higher. This is what makes you able to use skb->data and skb->data_end in your programs.
Then as a side note, this program sockmap_parse_prog.c is not meant to be used with tc. It is supposed to be attached directly to a socket (search for SOCKMAP_PARSE_PROG in file test_maps.c in the same directory to see how it is loaded there). Technically this does not prevent one to attach the program as a tc filter, but it will probably not work as expected. In particular, the value returned from the program will probably not have a meaning that tc classifier hook will understand.
So I would advise to try with a recent kernel, and to see if you have more success. Alternatively, try compiling and running the examples that you can find in your own kernel sources. Good luck!
Related
I need a debug version of glibc.I have some doubts regarding the installation of glibc-2.29 from source in kali linux.Based on the post https://www.tldp.org/HOWTO/html_single/Glibc-Install-HOWTO/,
To install glibc you need a system with nothing running on it, since many processes (for example sendmail) always try to use the library and therefore block the files from being replaced. Therefore we need a "naked" system, running nothing except the things we absolutely need. You can achieve this by passing the boot option
init=/bin/bash to your kernel.
it says that we need to install the glibc in a single usermode environment.In another post https://www.tldp.org/HOWTO/Glibc2-HOWTO-5.html
single usermode is not required for installation but backing up the old libraries.I dont know which one to follow.Can anyone help?
I found that we can use glibc without installing but building from source by adding '-g' flag in ./configure and setting LD_LIBRARY_PATH varible as follows after building
LD_LIBRARY_PATH=/path/to/the/build_directory gdb -q application
Note: this solution only works when the system GLIBC and the built-from-source GLIBC exactly match, as explained here.
I need a debug version of glibc.
Most distributions supply ready-made libc6-dbg packages that match your installed GLIBC. This is the best approach unless you are a GLIBC developer (or plan to become one).
I have some doubts regarding the installation of glibc-2.29 from source in kali linux.
Installing / replacing system libc is almost guaranteed to render your system unbootable if there are any mistakes. Recent example.
Before you begin, make sure you either know how to recover from such a mistake (have a rescue disk ready and know how to use it), or you have nothing of value on the system and can re-image it from installation media in the likely case that you do make a mistake.
The document you referenced talks about upgrading from libc5 to libc6. It was last updated on 22 June 1998, and is more than 20 years old. I suggest you find some more recent sources. Current documentation does suggest doing make install while in single-user mode.
I'm trying to do some debugging on a server on an issue that I suspect is related to a buffer overflow, so I tried to compile my code with -fsanitize=address to enable address sanitizing.
It compiled, and the resulting software runs. However, I'm trying to get a core dump when the address sanitizer detects an error since that is pretty much the only way I can get information out of the system due to the setup.
I am calling the software with ASAN_OPTIONS=abort_on_error=1 prepended on the command line (using a shell script to do that), and have checked that ulimit -c gives unlimited as result, but it just won't produce a core dump.
What am I missing?
This is on an ubuntu 14.04 server with gcc version 4.8.4
EDIT: sysctl kernel.core_pattern gives back kernel.core_pattern = |/usr/share/apport/apport %p %s %c %P. This probably means that apport is enabled (at least in some form). However, I have been able to get proper core files on this system from asserts and SIGFPEs in the software (that is where the suspicion of array overruns comes from).
Let me guess, is this x64 target? Coredumps are disabled there to avoid dumping 16 TB shadow memory (see docs for disable_coredump here for details).
Newer versions of GCC/Clang remove shadow from core by default so that one could do something like
export ASAN_OPTIONS=abort_on_error=1:disable_coredump=0
but I'm afraid 4.8 is too old for this.
As an alternative suggestion, why backtraces are not enough for you? You could use log_path or log_to_syslog to preserve them if you do not have access to programs stderr.
NB: I posted suggestion to enable coredumps on all platforms.
I am studying "Hacking: The Art of Exploitation". I am trying to follow the code examples, but for some reason the assembly codes simply does not match the one on my actual Linux (running on Virtual Box as Guest). I have made sure that I have installed 32 bit Linux OS. Is there any args that I can pass to gcc that lets me compile the code into an assembly that matches closely with the ones given in the book?
I would be fine reconciling the code differences between the book & what I see if they were minor, but the difference I see is stark. I somehow don't like to run the code from the "Preconfigured incubator environment" as this inhibits my skill development.
I've actually been in the same boat--for the last week or two I've tried a ton of ways to produce comparable assembly code in my normal development environment (LMDE), including chroot, compiling with the -m32 flag, installing an x86 ubuntu, etc, and nothing really worked. Today I found http://www.nostarch.com/hackingCD.htm and I followed the instructions and was able to get the livecd to boot in vmware workstation 10. Here's what I did:
Download the iso from the link above (though it should work with the
livecd as well)
Create a .vmx file and copy and paste the config from the link
I took out the section defining the cdrom device, since I was using an iso
Open the file with VmWare Workstation--if you are using the iso, go to "Edit VM Settings" and set up a cdrom device and point it to the iso
VM booted without any issues
I know this isn't as convenient as going through the examples in your main OS/system, and that you were trying to avoid using the LiveCD, but after doing a lot of research I've discovered that this is an extremely common issue and hopefully this answer helps someone. Using the LiveCD might not be ideal but it is still a heck of a lot better than dual booting.
for some reason the assembly codes simply does not match the one on my actual linux
The most likely reason is that the book was published in 2008, and used then-stable GCC (you can see GCC release history here).
GCC that you are using now is likely much newer, and so generates significantly different (and one hopes better) code.
Is there any args that I can pass to gcc that lets me compile the code into an assembly that matches closely with the ones given in the book?
No. You can try to compile and install a version from 2008, perhaps 4.2.3 or 4.3.0, and check whether that gives you closer output.
P.S. It looks like the first revision of the book is from 2003, and it's unlikely that the authors rebuilt all of their examples for the second edition in 2008, so perhaps try GCC 3.3 instead?
This is why the book comes with a LiveCD with a linux distro and all of the example source code from the book on there. All of the examples in the book match exactly with what will happen in the LiveCD.
Just run the included LiveCD using VirtualBox or VMware and follow along with the book using that. If you don't have the CD, it can be downloaded from a torrent provided by No Starch (linked from their website)
it doesn´t matter whether the output of gcc is different, the only thing it changes is the memory addresses; plus, you said u r using a VM to run it, meaning that the memory u will get is dummy memory, try booting the iso and run it directly, it will almost the same.
https://www.youtube.com/watch?v=pIN7oFkz5rM
I am trying to compile the kernel from downloaded source. I made the kernel image using sources from kernel.org.
I have successfully loaded it into grub, but when I try to run the loaded module it gives error message: "invalid magic number". I am not getting what I need to fix to get the things done.
Steps that I've followed:
make xconfig,
make bzImage
make modules
make modules_install
I also changed the name of image from bzImage (in /boot folder), then created initrd image from:
# dracut /boot/initramfs-3.1.6-1.fc16.x86_64.img 3.1.6-1.fc16.x86_64 (command copied from net)
Every time you compile a kernel, you must re-compile also the kernel module that you need to use within that kernel. For example, you cannot load a module compiled for kernel 2.6.39 on kernel 3.7. You must recompile it for kernel 3.7.
More details --> better answer
Actually I doubt this has anything to do with kernel modules. As it seems the kernel itself is being refered to as a module. It is possible the kernel got built incorrectly or is being loaded incorrectly possibly from the grub commandline.
http://forums.gentoo.org/viewtopic-t-932358-start-0.html try that.
It is possible that some file in the kernel build didn't get cleaned up properly an so has incorrect data in it since any changes you made in a previous attempt at building it.
Also do note that the x86 images will end up at arch/x86_64/boot/bzImage or arch/x86/boot/bzImage inside the kernel source make sure you actually have copied the kernel itself and not some other incorrect file.
If that fails try grub 1.x as its simpler to use than grub 2.x just note that alot of things are different and you should read tutorials for the correct version of grub. Often grub 1.x will be in a grub-legacy or similar package depending on the distro.
Edit: If you are building your kernel for your hardware only... do not use an initramfs its overkill. There are places you would want to do this is if your system is incapable of loading a kernel large enough for essential drivers (sparc for instance is very limited in kernel image size). another being booting over network possibly but by and large it isn't needed. If you must use an initramfs get your kernel build working without it first.
Also personally I build my kernel with essential drivers included (disk and filesystem basically) and build it with.
make mrproper (save/backup your .config first) ;
make menuconfig ;
make -j8 ;
make modules_install ;
cp arch/x86_64/boot/bzImage /boot/linux-3.7.1 ;
(modify grub to boot the new kernel) and im done and ready to reboot.
Any chance you could attach a screenshot of the failure?
I am not getting your question 100% clearly. Anyway, you downloaded some kernel tree from kernel.org and successfully booted with new Image.
Then you are trying to load a LKM i.e kernel module using insmod or modprobe.
so you are getting "Invalid magic number".
Solution
Need to re-compile the kernel module in new kernel, then try to insert.
I am using gdb attached to a serial port of a virtual machine to debug linux kernel.
I am wondering, if there is any patches/plugins which can make the gdb understand some of linux kernel's data structure and make it "thread aware"?
By that I mean under gdb I can see how many kernel threads are there, their status, and for each thread, their stack information.
libvmi
https://github.com/libvmi/libvmi
This project does "LibVMI: Simplified Virtual Machine Introspection" which sounds really close.
This project in particular https://github.com/Wenzel/pyvmidbg uses libvmi and features a demo video of debugging a Windows userland application form inside it, without memory conflicts.
As of May 2019, there are two limitations however as of May 2019, both of which could be overcome with some work: https://github.com/Wenzel/pyvmidbg/issues/24
Linux memory parsing is not yet complete
requires Xen
The developer of that project also answered further at: https://stackoverflow.com/a/56369454/895245
Implementing it with those libraries would be in my opinion the best way to achieve this goal today.
Linaro lkd-python
First, this Linaro page claims to have a working setup: https://wiki.linaro.org/LandingTeams/ST/GDB that allows you to do usual thread operations such as thread, bt, etc., but it relies on a GDB fork. I will test it out later. In 2016, https://youtu.be/pqn5hIrz3A8 says that the implementation was in C, not as Python scripts unfortunately, which would be better and avoid forking. The sketch for lkd-python can be found at: https://git.linaro.org/people/lee.jones/kieran.bingham/binutils-gdb.git/log/?h=lkd-python
Linux kernel in-tree GDB scripts + my brain
I then tried to see what I could do with the kernel in-tree Python scripts at v4.17 + some manual intervention as a prototype, but didn't quite get there yet.
I have tested using this highly automated QEMU + Buildroot setup.
First follow the procedure I described at: How to debug the Linux kernel with GDB and QEMU? to get GDB working.
Then, as described at: How to debug Linux kernel modules with QEMU? run GDB with:
gdb -ex add-auto-load-safe-path /full/path/to/linux/kernel
This loads the in-tree GDB Python scripts from scripts/gdb.
One of those scripts provides:
lx-ps
which lists all threads with format:
0xffff88000ed08000 1 init
0xffff88000ed08ac0 2 kthreadd
The first field is the address of the task_struct struct, so we can see the entire struct with:
p (struct task_struct)*0xffff88000ed08000
which should in theory allow us to get any information we want about the process.
Now I wanted to find the PC. For ARM, I've seen: Find program counter of process in kernel and I tried:
task_pt_regs((struct thread_info *)((struct task_struct)*0xffffffc00e8f8000))->uregs[ARM_pc]
but task_pt_regs is a #define and GDB cannot see defines without -ggdb3: How do I print a #defined constant in GDB? which are apparently not set?
I don't think GDB understands kernel data structures, that would make them version dependent. GDB uses ptrace for gathering information on any running process.
That's all I know :(
pyvmidbg developer here.
I will add some clarifications:
yes the goal of the project is indeed to have a cross-platform, guest-aware GDB stub.
Most of the implementation is already done for Windows, where we are aware of processes and their threads context.
It's possible to intercept a specific process (cmd.exe in the demo) and singlestep its execution (this is limited to 1 process with 1 thread for now), as well as attaching to a new process's entrypoint.
Regarding Linux, I looked at the internals and the resources that I could find, but I'm lacking the whole picture to figure out how I can:
- intercept a task when it's being scheduled (core/sched.c:switch_to() ?)
- read the task state (Windows's KTRAP_FRAME equivalent for Linux ?)
I asked a question on SO, but nobody answered :/
Linux context switch internals: how does a process goes back to userland after the switch?
If you can help with this, I can guide you through the implementation :)
Regarding the hypervisor support, only Xen is fully supported in the Libvmi interface at the moment.
I added a section in the README to describe where we are in terms of VMI APIs with other hypervisors.
Thanks !