Changing linux kernel system call number - linux-kernel

I wanted to build my own custom kernel with a different syscall table. (same syscalls but in different position/numbers)
I was working on kernel 3.2.29.
Changing the kernel was quite easy:
1) changing the syscall position in ‫‪arch/x86/kernel/syscall_table_32.S‬‬
2) changing the syscall macro number in arch/x86/include/asm/unistd_32.h
3) compiling and installing the new kernel
I switched the syscalls around: sys_open took the place and number of sys_read, and vice versa.
I figured that if I compile glibc with the modified kernel headers, I could have a running system, but unfortunately, it wasn't enough and my system won't boot.
Am I missing something? What else do I need to do in order to have a running system?
The steps I have taken are:
1) building and installing the kernel as described in my question
2) extracting the new kernel headers using make headers_install INSTALL_HDR_PATH=[path]
3) building glibc with the parameter --with-headers=[path/include]
4) I used a live cd to access the file system externally in order to install the new glibc, using the make install install_root=[the original file system] (so the system won't break during the install)
I hope that the new glibc was built properly, but I am not sure.
After that, when booting the system, the boot stops in the (initrafms) shell screen:
I guess I need to rebuild the initrd, but how do I compile it according to the new syscall table?

You will have to rebuild everything. Even if all your binaries are dynamically linked, it is possible that the old syscalls were inlined into the binary because many of the C functions are just return syscall(__NR_somecall,...).
You could do this manually, but it could be difficult to keep the toolchains straight unless you use a cross compilable toolchain like buildroot, aboriginal or similar. Pick whichever best suits you (I prefer Rob Landley's aboriginal - http://landley.net/aboriginal/ )
Then to make your initrd just expand the old one using {z,bz,xz}cat oldinit.rd |cpio -id; rm oldinit.rd. Replace the old kernel modules, libs and binaries with the new and cpio and compress it back (cpio needs the -H newc option) ... or now you can rebuild your kernel and point the initramfs to that directory, but wouldn't recommend that if your initrd may need changed frequently such as if for instance you were testing out a whole new syscall structure and having to debug a lot.

Scrambling the system call numbers is really going to hurt. You'll at least need to rebuild all of the statically linked binaries on your system and your initrd (if you use one).

You haven't said at what point the boot fails, but even if the kernel comes up it is likely that the critical programs contained in the initrd compressed ramdisk would fail because they have the original syscall numbers hard-coded. You will need to rebuild and repackage those as well.
You might consider first replacing init with a static hello-world type of program to verify that your kernel can support a userspace at all; then look into the details of making all the complexity of a modern linux userspace match.

you had to learn to reading the messsage of pansic dump and show us what kenrel panic. Without this information, people can hardly help you or provide you useful suggestion.

Related

fail to attach eBPF blob

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!

In Linux how to forbid code execute in heap

Image this way to invade Linux: 1. malloc a space. 2. write binary code to this region. 3. jump to this code.
I want to forbid this way to run code. Only run code in .text section. What should I do to the Linux kernel? Thank you!
The PaX security patch to linux address this concern by ensuring that no memory in RAM is both writeable and executable. This ensures that one can not allocate memory into RAM, write code to it, and then execute it (which seems exactly what you are trying to prevent).
https://en.wikipedia.org/wiki/PaX#Executable_space_protections
Note that you may have to compile a custom kernel to install this patch. Alternatively, try seeing if your distribution offers a linux kernel with the patch installed. (Search for linux-grsec or linux-pax).

Boot linux kernel to terminal

I have a project in mind and for that I require the kernel to boot up and bring me to a console window so that I can start working. [later I'll automate the process].
How do I accomplish it?
Well, I have downloaded the latest stable kernel source from kernel.org and I have tried editing the init/main.c file. But I have no idea what in the world was going on in that file [noob ^n].
Hence, I post this question for an answer.
I require the kernel to boot up and bring me to a console window so that I can start working.
The kernel doesn't do much by itself. In fact, it's unlikely you want to alter "main" in the kernel.
If you want to "run" the kernel, you'll also need a root filesystem and some user-space programs. If you want a minimal userland, you can use "busybox". Even better, buildroot will help you create a minimal userland + kernel.
You can even combine your root filesystem plus the kernel into a single binary. At runtime, it will uncompress userland into a ramdisk and run entirely from RAM. See initramfs. This is super-helpful for embedded systems. A minimal kernel+root filesystem can be around 1MB.
Go through below link
http://balau82.wordpress.com/2010/03/27/busybox-for-arm-on-qemu/
Just black screen after running Qemu

Kernel compilation error (invalid magic number)

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.

Creating ELF image

I need to create an ELF image file from shared objects (.so files) and write it to another partition in Windows. Then open this partition in Linux and load the shared objects.
Does anybody know how to create an ELF image (a bundle of many shared objects) in Windows?
You can use Cygwin and try a suitable GCC cross-toolchain. Perhaps you'll have to build it yourself first (which is troublesome), but there it goes...
EDIT:
Okay, here you are:
A simplified one:
Building GCC cross compiler (from "Linux" to "Windows") -- the basic steps are the same as described there. You'll just need to ./configure it with relevant --host=... and --target=.... And oh! Don't forget to set the build root, since building "in the source tree" is not supported -- you'll just get stuck in errors if you try (I did...)
A killer one:
http://cygwin.wikia.com/wiki/How_to_install_a_newer_version_of_GCC#Build_and_Install_GCC -- a complete guide.
Nowadays Linux understands NTFS. At least, it should be able to read off it.
You can also use a flash stick formatted as FAT32 or NTFS as the shared storage.
You can also run Linux in a VM and set up FTP server on it and exchange files through it.
There're many ways of sharing data between different OSes.

Resources