How to disable stack canaries for specific functions? - c

With gcc, is it possible to compile with -fstack-protector, but omit for a specific function.
For example, say i have two functions.
void a() {
...
}
void b() {
...
}
Can I tell the compiler to compile a program that will use a canary before the saved return address of a, but no canary for b?

You'd have to test if it works (inspect the generated code at Godbolt) but it looks like you can do, for example:
__attribute__ ((no_stack_protector)) void foo () { ... }
no_sanitize looks like an intriguing option, I wonder who uses that.

Related

LLVM cannot see static function

I am trying to instrument the linux kernel code to insert a function call in every function right after a BitCast instruction.
So I modify the C code to #include <linux/my_header.h> where I have my printer function.
The header looks something like this.
#ifndef __header_ID
#define __header_ID
static inline void print_typecast(...){
printk(...);
}
#endif
Then I use Xclang to load my FunctionPass, which looks something like this.
// M is of type llvm::Module*
Function* f = M->getFunction("print_typecast");
if (f == nullptr) {
errs() << "Function not found in the module\n";
}
else {
// insert function in the code
}
However, my pass never finds the function in the module. When I remove the static it will find the function but then the linker in the final compilation step will complain of duplicate definition.
Anyone knows how to make LLVM "see" static imported/included functions?
Edit: I have also gone to the extreme where I have the same function directly written in every c file of the kernel code (the ones that #include <linux/kernel.h>)
static means that all calls to this function will be visible to this compiller now, and by implication that if the compiler sees no such calls, then it can skip compiling any output for the function, because you as programmer have promised that noone will want it.

changing extern function pointer to extern pointer using preprocessor

I am using library that I shouldn't change it files, that including my h file.
the code of the library looks somthing like like:
#include "my_file"
extern void (*some_func)();
void foo()
{
(some_func)();
}
my problem is that I want that some_func will be extern function and not extern pointer to function (I am implementing and linking some_func). and that how main will call it.
that way I will save little run time and code space, and no one in mistake will change this global.
is it possible?
I thought about adding in my_file.h somthing as
#define *some_func some_func
but it won't compile because asterisk is not allowed in #define.
EDIT
The file is not compiled already, so changes at my_file.h will effect the compilation.
First of all, you say that you can't change the source of the library. Well, this is bad, and some "betrayal" is necessary.
My approach is to let the declaration of the pointer some_func as is, a non-constant writable variable, but to implement it as constant non-writable variable, which will be initialized once for all with the wanted address.
Here comes the minimal, reproducible example.
The library is implemented as you show us:
// lib.c
#include "my_file"
extern void (*some_func)();
void foo()
{
(some_func)();
}
Since you have this include file in the library's source, I provide one. But it is empty.
// my_file
I use a header file that declares the public API of the library. This file still has the writable declaration of the pointer, so that offenders believe they can change it.
// lib.h
extern void (*some_func)();
void foo();
I separated an offending module to try the impossible. It has a header file and an implementation file. In the source the erroneous assignment is marked, already revealing what will happen.
// offender.h
void offend(void);
// offender.c
#include <stdio.h>
#include "lib.h"
#include "offender.h"
static void other_func()
{
puts("other_func");
}
void offend(void)
{
some_func = other_func; // the assignment gives a run-time error
}
The test program consists of this little source. To avoid compiler errors, the declaration has to be attributed as const. Here, where we are including the declarating header file, we can use some preprocessor magic.
// main.c
#include <stdio.h>
#define some_func const some_func
#include "lib.h"
#undef some_func
#include "offender.h"
static void my_func()
{
puts("my_func");
}
void (* const some_func)() = my_func;
int main(void)
{
foo();
offend();
foo();
return 0;
}
The trick is, that the compiler places the pointer variable in the read-only section of the executable. The const attribute is just used by the compiler and is not stored in the intermediate object files, and the linker happily resolves all references. Any write access to the variable will generate a runtime error.
Now all of this is compiled in an executable, I used GCC on Windows. I did not bother to create a separated library, because it doesn't make a difference for the effect.
gcc -Wall -Wextra -g main.c offender.c lib.c -o test.exe
If I run the executable in "cmd", it just prints "my_func". Apparently the second call of foo() is never executed. The ERRORLEVEL is -1073741819, which is 0xC0000005. Looking up this code gives the meaning "STATUS_ACCESS_VIOLATION", on other systems known as "segmentation fault".
Because I deliberately compiled with the debugging flag -g, I can use the debugger to examine more deeply.
d:\tmp\StackOverflow\103> gdb -q test.exe
Reading symbols from test.exe...done.
(gdb) r
Starting program: d:\tmp\StackOverflow\103\test.exe
[New Thread 12696.0x1f00]
[New Thread 12696.0x15d8]
my_func
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00000000004015c9 in offend () at offender.c:16
16 some_func = other_func;
Alright, as I intended, the assignment is blocked. However, the reaction of the system is quite harsh.
Unfortunately we cannot get a compile-time or link-time error. This is because of the design of the library, which is fixed, as you say.
You could look at the ifunc attribute if you are using GCC or related. It should patch a small trampoline at load time. So when calling the function, the trampoline is called with a known static address and then inside the trampoline there is a jump instruction that was patched with the real address. So when running, all jump locations are directly in the code, which should be efficient with the instruction cache. Note that it might even be more efficient than this, but at most as bad as calling the function pointer. Here is how you would implement it:
extern void (*some_func)(void); // defined in the header you do not have control about
void some_func_resolved(void) __attribute__((ifunc("resolve_some_func")));
static void (*resolve_some_func(void)) (void)
{
return some_func;
}
// call some_func_resolved instead now

How does gcc treat two functions with different optimizations, when one calls the other?

I searched for a while for an answer for this question, and if it already exists please point me to the right place.
I am investigating optimizing single functions in c compiled with gcc.
I have been able to optimize a single function outside of the general file optimization using:
void __attribute__((optimize("Os"))) Func( void )
{
...
}
But I am unsure of how gcc handles:
void __attribute__((optimize("Os"))) Func1( void )
{
...
}
void __attribute__((optimize("O3"))) Func2( void )
{
Func1();
...
}
Since Func1() is being compiled with -Os it shouldn't be inlined, and I was fairly sure that I would find that I ended up with a result where everything in Func2() optimized to -03, except for the call to Func1(). But the results I am seeing say otherwise. This leads me to believe that I am doing something wrong or don't understand the implementation of gcc correctly.
Does the -O3 optimization attribute on func2() get applied to everything inside Func2(), which would separately compile func1() with -03 for use of inlining inside the func2() call?

How to compile inline C function with literal attributes with GCC?

I have an inline function like this:
inline void func_1 (int a)
{
if(a==1)
{
other_func1();
}
else
{
other_func2();
}
}
and I use in the Main like this:
int main()
{
func1(1);
func1(42);
return 0;
}
I use GCC, I think, the compiled code look like this (in “source level”):
int main()
{
other_func1()
other_func2();
return 0;
}
Is it true or am I wrong?
Yes, in general gcc will optimise away dead code in inline functions when it can evaluate branches at compile-time. I use this construct a lot to allow optimised code to be generated for different use cases - somewhat like template instantiation in C++.

C code parser to track function calls and variable accesses within a project (emacs compatibility would be nice)

What I would like is a tool to be able to tell me which functions call a particular function A() (in a C project), and which functions call those functions etc so that I can have a list of functions which i know that when they are called, there is a possibility that function A() will be called.
For example we have the following functions scattered in a project:
void A()
{ /*does something*/ }
void B()
{
A();
/*and more stuff*/
}
void C()
{
if(unlikely_to_be_false)
A()
/* moar stoff */
}
void D()
{
/* code that does not refer to A() at all */
}
void E()
{
C()
}
When the awesome tool is run with parameter A, It will return somehow a the functions B C and E.
Close to this but not exactly i would like to accomplish this:
Given a variable somewhere in a project find all read/write operations(direct or indirect) to it.
For example:
void A()
{
char* c; // this is our little variable
B(c); // this is in the resulting list
}
void B(char* x)
{
printf("%c", x); // this is definately in the list
*x='d' // this is also in the list
C(x); // also in the list
}
void C(void* ptr)
{
ptr = something; // also in the list
}
If the above could play well with emacs i would be most delighted!
You could have a look on cscope tool (http://cscope.sourceforge.net/). It supports very large projects and a lot of different queries type :
Find this C symbol
Find this global definition
Find functions called by this function
Find functions calling this function
...
First, there is the issue of calls between different compilation units, e.g. foo.c defining function foo1 calling function bar2 defined in bar.c (and that bar2 might call a foobar defined in foo.c or in another file foofoo.c)
Then, you might consider perhaps developing a GCC plugin or a MELT extension to suit your needs.
You could also buy a costly static analyzer tool.
Emacs has cedet which might interest you.

Resources