How can I implement my own hook function with LSM? - linux-kernel

I'm learning something about access control.
And try to implement own hook function with LSM api.
But I found I have to code in the kernel source in Kernel version 3.1.4.
So , how can I get started?
Could someone give an example about it?
Thanks a lot.
PS: I have found some examples, but in kernel version 2.6.20. As LSM have been modified, those examples cannot work.

You can't load an LSM module since 2.6.35 (see c1e992b99603a84d7debb188542b64f2d9232c07 commit). So, it isn't a valid task to get LSM outside the kernel. But you always can try to disassemble the kernel at run time and find all the private symbols such as security_ops pointer.
For example, have a look at the exported security_sb_copy_data symbol:
int security_sb_copy_data(char *orig, char *copy)
{
return security_ops->sb_copy_data(orig, copy);
}
EXPORT_SYMBOL(security_sb_copy_data);
It dump may looks this (x86_64):
(gdb) x/7i security_sb_copy_data
0xffffffff811f61b0: push %rbp
0xffffffff811f61b1: mov %rsp,%rbp
0xffffffff811f61b4: data32 data32 data32 xchg %ax,%ax
0xffffffff811f61b9: mov 0x881690(%rip),%rax # 0xffffffff81a77850
0xffffffff811f61c0: callq *0x98(%rax)
0xffffffff811f61c6: pop %rbp
0xffffffff811f61c7: retq
So, the 0xffffffff81a77850 address is the exact security_ops pointer. Let's check it out with:
(gdb) x/s* 0xffffffff81a77850
0xffffffff81850fa0: "default"
OK, now we have valid security_ops pointer and can do anything with LSM outside the kernel.
P.S. There is a great Linux kernel security project - AKARI. It implements interesting methods of private symbols resolution without disassembly (see sources for details).

Related

implementation of .cfi_remember_state

I was wondering how exactly .cfi_remember_state is implemented. I know it is a pseudo-op, so I suppose it is converted into a couple of instructions when assembling. I am interested what exact instructions are used to implement it. I tried many ways to figure it out. Namely:
Read GAS source code. But failed to find anything useful enough.
Read GAS documentation. But the .cfi_remember_state entry is just a simple joke (literally).
Tried to find a gcc switch that would make gcc generate asm from C code with pseudo-ops "expanded". Failed to find such a switch for x86 / x86-64. (Would be nice if someone could point me to such a switch, assuming it exists, BTW.)
Google-fu && searching on SO did not yield anything useful.
The only other solution in my mind would be to read the binary of an assembled executable file and try to deduce the instructions. Yet I would like to avoid such a daunting task.
Could any of You, who knows, enlighten me, how exactly it is implemented on x86 and/or x86-64? Maybe along with sharing how / where that information was acquired, so I could check other pseudo-ops, if I ever have the need to?
This directive is a part of DWARF information (really all it does is emit DW_CFA_remember_state directive). Excerpt from DWARF3 standard:
The DW_CFA_remember_state instruction takes no operands. The required
action is to push the set of rules for every register onto an implicit
stack.
You may play with DWARF information using objdump. Lets begin with simple void assembler file:
.text
.globl main
.type main, #function
main:
.LFB0:
.cfi_startproc
#.cfi_remember_state
.cfi_endproc
.LFE0:
.size main, .-main
Compile it with gcc cfirem.s -c -o cfirem.o
Now disassemble generated DWARF section with objdump --dwarf cfirem.o
You will get:
00000018 00000014 0000001c FDE cie=00000000 pc=00000000..00000000
DW_CFA_nop
DW_CFA_nop
...
If you will uncomment .cfi_remember_state, you will see instead:
00000018 00000014 0000001c FDE cie=00000000 pc=00000000..00000000
DW_CFA_remember_state
DW_CFA_nop
DW_CFA_nop
...
So it is not really converting in assembler instructions (try objdump -d to see that there are no assembler instructions in our sample at all). It is converted in DWARF pseudo-instructions, that are used when debugger like GDB processes your variable locations, stack information and so on.

gcc, start symbol and push $0x00

So I've searched the interwebs for weeks and cannot find the answer to my questions.
I can see that the start symbol added by gcc sets up the initial two arguments (int argc, char *argv[]) and I believe the 3rd environment argument, but I have a couple questions about this. Why does it add all of this if the main() function is defined to have no arguments? Wouldn't it save space (and technically processing time) if it would just call _main without any arguments?
Second what does push $0x0 do? I have done tests and if you try to iterate through the command line arguments like what the default start symbol does then you need push $0x0 at the beginning, otherwise I have created misaligned stack errors if I do something like the following:
push $0x00
call _main
mov %eax, %edi
call _exit
also in my investigations I have found that the start symbol is added by the linker when you link to crt1.10.6.o
Any explanations or documentation would be greatly appreciated
The code for _start, as you have found, comes from an object file named crt1.o or similar. That object file normally comes from source code that's part of the C library. It is compiled in ignorance of how you have declared your main function, and so it has to assume you wish to make use of all three potential arguments. It does no harm to set up the arguments even if main won't use them (other than a trivial amount of space and time, as you mention).
I deduce from mov %eax,%edi that this is the x86-64 ELF ABI, which means that there are no frame pointers, so the push $0x00 is indeed just to keep the stack aligned to a 16-byte boundary, as you speculate. (In the x86-32 ELF ABI, it would also have served as the terminator for the linked list of frame pointers.)

Why does GCC add assembly commands to my inline assembly?

I'm using Apple's llvm-gcc to compile some code with inline assembly. I wrote what I want it to do, but it adds extraneous commands that keep writing variables to memory. Why is it doing this and how can I stop it?
Example:
__asm__{
mov r11, [rax]
and r11, 0xff
cmp r11, '\0'
}
becomes (in the "assembly" assistant view):
mov 0(%rax), %r11 // correct
movq %r11, -104(%rbp) // no, GCC, obviously wrong
and $255, %r11
movq %r11, -104(%rbp)
cmp $0, %r11
Cheers.
You need to use GCC's extended asm syntax to tell it which registers you're using as input and output and which registers get clobbered. If you don't do that, it has no idea what you're doing, and the assembly it generates can easily interfere with your code.
By informing it about what your code is doing, it changes how it does register allocation and optimization and avoids breaking your code.
it's because gcc tries to optimize your code. you can prevent optimizations by adding -O0 to command-line.
Try adding volatile after __asm__ if you don't want that. That additional commands are probably part previous/next C instructions. Without volatile compiler is allowed to do this (as it probably executes faster this way - not your code, the whole routine).

Why does a printf() stop a crash from occuring?

I have been looking all over the Internet for an answer to this question (see subject of post). I have been asked this exact question twice. Once at an interview for company and once by a friend and I cannot find the answer for the life of me.
I have actually experienced this error on multiple occasions when debugging without a debugger, and just using print statements to isolate the error. I cannot recall any exact situations, though I am positive I have experienced it. If anyone can provide a link or a reference or point me to something in printf() source that might cause an error to stop occurring when using print statements to debug code I would greatly appreciate the good read.
Thank you,
Matthew Hoggan
I am currently reading the link provided but for further conversation I have posted some of my weak attempts to investigate:
Okay, so i have started to play around myself to try and answer my own question but things are still not 100% clear to me. Below is the output from the g++ compiler using the -S option to output the assembly instead of the executable. The equivalent C++ code is also posted below. My goal is to try and recreate a simple scenario and then try and detect based on the instructions what might be happening at the processor levels. So lets say right after the "call printf" assembly code, which I am assuming is linked from the library files stored in /usr/lib or another lib directory, I tried to access a NULL pointer (not in code), or some other form of operation that would traditionally crash the program. I am assuming that I would have to find out what printf is doing instruction wise to get a deeper look into this?
.file "assembly_test_printf.cpp"
.section .rodata
.LC0:
.string "Hello World"
.text
.globl main
.type main, #function
main:
.LFB0:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $0, 28(%esp)
movl $.LC0, (%esp)
call printf
movl 28(%esp), %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",#progbits
Equivalent C++ code:
#include <stdio.h>
int main ( int argc, char** argv ) {
int x = 0;
printf ("Hello World");
return x;
}
There are several reasons adding a printf() can change the behavior of a bug. Some of the more common ones might be:
changing the timing of execution (particularly for threading bugs)
changing memory use patterns (the compiler might change how the stack is used)
changing how registers are used
For example, an uninitialized local variable might be allocated to a register. Before adding the printf() the uninitialized variable is used and gets come garbage value that's in the register (maybe the result of a previous call to rand(), so it really is indeterminate). Adding the printf() causes the register to be used in printf() and printf() always happens to leave that register set to 0 (or whatever). Now your buggy program is still bugy, but with different behavior. And maybe that behavior happens to be benign.
I've seen it before, for example in Java, in cases where initialization code isn't complete when another thread attempts to access an object assumed to have already been created. The System.out.println() slows down the other thread enough for the initialization to complete.

cedecl calling convention -- compiled asm instructions cause crash

Treat this more as pseudocode than anything. If there's some macro or other element that you feel should be included, let me know.
I'm rather new to assembly. I programmed on a pic processor back in college, but nothing since.
The problem here (segmentation fault) is the first instruction after "Compile function entrance, setup stack frame." or "push %ebp". Here's what I found out about those two instructions:
http://unixwiz.net/techtips/win32-callconv-asm.html
Save and update the %ebp :
Now that we're in the new function, we need a new local stack frame pointed to by %ebp, so this is done by saving the current %ebp (which belongs to the previous function's frame) and making it point to the top of the stack.
push ebp
mov ebp, esp // ebp « esp
Once %ebp has been changed, it can now refer directly to the function's arguments as 8(%ebp), 12(%ebp). Note that 0(%ebp) is the old base pointer and 4(%ebp) is the old instruction pointer.
Here's the code. This is from a JIT compiler for a project I'm working on. I'm doing this more for the learning experience than anything.
IL_CORE_COMPILE(avs_x86_compiler_compile)
{
X86GlobalData *gd = X86_GLOBALDATA(ctx);
ILInstruction *insn;
avs_debug(print("X86: Compiling started..."));
/* Initialize X86 Assembler opcode context */
x86_context_init(&gd->ctx, 4096, 1024*1024);
/* Compile function entrance, setup stack frame*/
x86_emit1(&gd->ctx, pushl, ebp);
x86_emit2(&gd->ctx, movl, esp, ebp);
/* Setup floating point rounding mode to integer truncation */
x86_emit2(&gd->ctx, subl, imm(8), esp);
x86_emit1(&gd->ctx, fstcw, disp(0, esp));
x86_emit2(&gd->ctx, movl, disp(0, esp), eax);
x86_emit2(&gd->ctx, orl, imm(0xc00), eax);
x86_emit2(&gd->ctx, movl, eax, disp(4, esp));
x86_emit1(&gd->ctx, fldcw, disp(4, esp));
for (insn=avs_il_tree_base(tree); insn != NULL; insn = insn->next) {
avs_debug(print("X86: Compiling instruction: %p", insn));
compile_opcode(gd, obj, insn);
}
/* Restore floating point rounding mode */
x86_emit1(&gd->ctx, fldcw, disp(0, esp));
x86_emit2(&gd->ctx, addl, imm(8), esp);
/* Cleanup stack frame */
x86_emit0(&gd->ctx, emms);
x86_emit0(&gd->ctx, leave);
x86_emit0(&gd->ctx, ret);
/* Link machine */
obj->run = (AvsRunnableExecuteCall) gd->ctx.buf;
return 0;
}
And when obj->run is called, it's called with obj as its only argument:
obj->run(obj);
If it helps, here are the instructions for the entire function call. It's basically an assignment operation: foo=3*0.2;. foo is pointing to a float in C.
0x8067990: push %ebp
0x8067991: mov %esp,%ebp
0x8067993: sub $0x8,%esp
0x8067999: fnstcw (%esp)
0x806799c: mov (%esp),%eax
0x806799f: or $0xc00,%eax
0x80679a4: mov %eax,0x4(%esp)
0x80679a8: fldcw 0x4(%esp)
0x80679ac: flds 0x806793c
0x80679b2: fsts 0x805f014
0x80679b8: fstps 0x8067954
0x80679be: fldcw (%esp)
0x80679c1: add $0x8,%esp
0x80679c7: emms
0x80679c9: leave
0x80679ca: ret
Edit: Like I said above, in the first instruction in this function, %ebp is void. This is also the instruction that causes the segmentation fault. Is that because it's void, or am I looking for something else?
Edit: Scratch that. I keep typing edp instead of ebp. Here are the values of ebp and esp.
(gdb) print $esp
$1 = (void *) 0xbffff14c
(gdb) print $ebp
$3 = (void *) 0xbffff168
Edit: Those values above are wrong. I should have used the 'x' command, like below:
(gdb) x/x $ebp
0xbffff168: 0xbffff188
(gdb) x/x $esp
0xbffff14c: 0x0804e481
Here's a reply from someone on a mailing list regarding this. Anyone care to illuminate what he means a bit? How do I check to see how the stack is set up?
An immediate problem I see is that the
stack pointer is not properly aligned.
This is 32-bit code, and the Intel
manual says that the stack should be
aligned at 32-bit addresses. That is,
the least significant digit in esp
should be 0, 4, 8, or c.
I also note that the values in ebp and
esp are very far apart. Typically,
they contain similar values --
addresses somewhere in the stack.
I would look at how the stack was set
up in this program.
He replied with corrections to the above comments. He was unable to see any problems after further input.
Another edit: Someone replied that the code page may not be marked executable. How can I insure it is marked as such?
The problem had nothing to do with the code. Adding -z execstack to the linker fixed the problem.
If push %ebp is causing a segfault, then your stack pointer isn't pointing at valid stack. How does control reach that point? What platform are you on, and is there anything odd about the runtime environment? At the entry to the function, %esp should point to the return address in the caller on the stack. Does it?
Aside from that, the whole function is pretty weird. You go out of your way to set the rounding bits in the fp control word, and then don't perform any operations that are affected by rounding. All the function does is copy some data, but uses floating-point registers to do it when you could use the integer registers just as well. And then there's the spurious emms, which you need after using MMX instructions, not after doing x87 computations.
Edit See Scott's (the original questioner) answer for the actual reason for the crash.

Resources