Pseudo-random stack pointer under Linux? - linux

I was playing around with some code when I noticed something strange:
[~] main% cat test.cc
#include <stdio.h>
void f()
{
int i;
fprintf(stderr, "&i = 0x%08X\n", (long)&i);
}
int main(int argc, char**argv)
{
f();
}
[~] main% g++ test.cc
[~] main% ./a.out
&i = 0xBFA27AB4
[~] main% ./a.out
&i = 0xBFAD7E24
[~] main% ./a.out
&i = 0xBFCA3464
[~] main% ./a.out
&i = 0xBF96C064
[~] main%
The odd thing to me is the variation in the address of the variable i.
My guess is that the kernel supplies different stack start addresses to try to thwart some kind of crack. What's the real reason?

Address space layout randomisation is used on several operating systems for precisely this reason. Your variation in stack pointer addresses may well be caused by this - very likely to be the case on recent versions of Linux and or *BSD. IIRC recent versions of Windows do this as well.

Related

Record instruction addresses of page faults with perf

I would like to get addresses of the instructions which leads to major page faults using perf.
I have a simple program:
#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
int main(int argc, char* argv[]) {
int fd = open("path to large file several Gb", O_RDONLY);
struct stat st;
fstat(fd, &st);
void* ptr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
const uint8_t* data = (const uint8_t*) ptr;
srand(time(NULL));
size_t i1 = ((double) rand() / RAND_MAX) * st.st_size;
size_t i2 = ((double) rand() / RAND_MAX) * st.st_size;
size_t i3 = ((double) rand() / RAND_MAX) * st.st_size;
printf("%x[%lu], %x[%lu], %x[%lu]\n", data[i1], i1, data[i2], i2, data[i3], i3);
munmap(ptr, st.st_size);
close(fd);
return 0;
}
I compile it using gcc -g -O0 main.c
and run perf record -e major-faults -g -d ./a.out
Next I open the resulting report using perf report -g
The report says that there are 3 major page faults (it's correct),
but I can't understand addresses of the instructions which leads to the page faults.
The report is below:
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 3 of event 'major-faults'
# Event count (approx.): 3
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................ ......................
#
100.00% 0.00% a.out libc-2.23.so [.] __libc_start_main
|
---__libc_start_main
main
100.00% 100.00% a.out a.out [.] main
|
---0x33e258d4c544155
__libc_start_main
main
100.00% 0.00% a.out [unknown] [.] 0x033e258d4c544155
|
---0x33e258d4c544155
__libc_start_main
main
a.out doesn't contain an address 0x33e258d4c544155 or something which ends with 155.
The question is how to get instruction addresses which leads to page faults?
For some reason I cannot reproduce your example, i.e. I'm not getting any samples with the major-faults event. But I can explain with a different example.
The pref report output is misleading, it doesn't the three events, it shows the three stack levels. It's much easier to understand by using perf script - which shows the actual events (including their stacks). The entries look like this (repeated for each sample):
a.out 22107 14721.378764: 10000000 cycles:u:
5653c1afb134 main+0x1b (/tmp/a.out)
7f58bb1eeee3 __libc_start_main+0xf3 (/usr/lib/libc-2.29.so)
49564100002cdb3d [unknown] ([unknown])
Now you see the function stack with the virtual instruction address, nearest symbol and offset from the symbol. If you want to fiddle with the addresses yourself, you can run perf script --show-mmap-events, which tells you:
a.out 22107 14721.372233: PERF_RECORD_MMAP2 22107/22107: [0x5653c1afb000(0x1000) # 0x1000 00:2b 463469 624179165]: r-xp /tmp/a.out
^ Base ^ size ^ offset ^ file
Then you can do the math for 0x5653c1afb134 by subtracting the base 0x5653c1afb000 and adding the offset 0x1000 - you get the address of the instruction or return address within the file.
You also see that 0x49564100002cdb3d is not mapped, could not be resolved - it's just garbage from the frame-pointer based stack unwinding. You can ignore it. You can also use --call-graph dwarf or --call-graph lbr which seem to show more sensible stack origins.

Computing memory address of the environment within a process

I got the following code from the lecture-slides of a security course.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
extern char shellcode;
#define VULN "./vuln"
int main(int argc, char **argv) {
void *addr = (char *) 0xc0000000 - 4
- (strlen(VULN) + 1)
- (strlen(&shellcode) + 1);
fprintf(stderr, "Using address: 0x%p\n", addr);
// some other stuff
char *params[] = { VULN, buf, NULL };
char *env[] = { &shellcode, NULL };
execve(VULN, params, env);
perror("execve");
}
This code calls a vulnerable program with the shellcode in its environment. The shellcode is some assembly code in an external file that opens a shell and VULN defines the name of the vulnerable program.
My question: how is the shellcode address is computed
The addr variable holds the address of the shellcode (which is part of the environment). Can anyone explain to me how this address is determined? So:
Where does the 0xc0000000 - 4 come from?
Why is the length of the shellcode and the programname substracted from it?
Note that both this code and the vulnerable program are compiled like this:
$ CFLAGS="-m32 -fno-stack-protector -z execstack -mpreferred-stack-boundary=2"
$ cc $CFLAGS -o vuln vuln.c
$ cc $CFLAGS -o exploit exploit.c shellcode.s
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
0
So address space randomization is turned off.
I understood that the stack is the first thing inside the process (highest memory address). And the stack contains, in this order:
The environment data.
argv
argc
the return address of main
the framepointer
local variables in main
...etc...
Constants and global data is not stored on the stack, that's why I also don' t understand why the length of the VULN constant influence the address at which the shellcode is placed.
Hope you can clear this up for me :-)
Note that we're working with a unix system on a intel x86 architecture

clang analyzer memory leaks

Why doesn't clang/clang-analyzer catch that I forgot to free a and have a memory leak? It's obvious. I looked at the man pages and i'm not sure what flags are required.
$ scan-build clang++ -std=c++11 a.cpp
scan-build: Using '/usr/bin/clang' for static analysis
scan-build: Removing directory '/tmp/scan-build-2013-10-02-2' because it contains no reports.
$ cat ./a.cpp
#include <iostream>
int main() {
int *a = new int;
*a = 8;
std::cout<< a << std::endl;
}

Why is there a difference using std::thread::hardware_concurrency() and boost::thread::hardware_concurrency()?

The description of the problem itself is pretty simple. I'm testing the differences of std::thread library in C++11 and boost::thread library.
The output of these:
#include <iostream>
#include <thread>
#include <boost/thread.hpp>
int main() {
std::cout << std::thread::hardware_concurrency() << std::endl;
std::cout << boost::thread::hardware_concurrency() << std::endl;
return 0;
}
gives me different results:
0
4
Why is that?
PS: The version of the gcc package is 4.6.2-1.fc16 (x86_64). I'm using
g++ test.cc -Wall -std=c++0x -lboost_thread-mt -lpthread
After reviewing /usr/include/c++/4.6.2/thread
it can be seen that the implementation is actually:
// Returns a value that hints at the number of hardware thread contexts.
static unsigned int
hardware_concurrency()
{ return 0; }
So problem solved. It's just another feature that hasn't been implemented in gcc 4.6.2
The method employed by your compiler installation of boost is supported for your target, whereas your installation of boost compiler does not support this feature for your target.
TFM says:
The number of hardware threads available on the current system (e.g. number of CPUs or cores or hyperthreading units), or 0 if this information is not available.
EDIT: scratch that, reverse it.
EDIT2: This feature is present on the trunk, but absent in 4.6.2:
~/tmp/gcc-4.6.2/libstdc++-v3/src> wc -l thread.cc
104 thread.cc
~/tmp/gcc-4.6.2/libstdc++-v3/src> grep concurrency thread.cc | wc -l
0
~/tmp/gcc-4.6.2/libstdc++-v3> grep -C 2 VERIFY testsuite/30_threads/thread/members/hardware_concurrency.cc
// Current implementation punts on this.
VERIFY( std::thread::hardware_concurrency() == 0 );
return 0;

Externally disabling signals for a Linux program

On Linux, is it possible to somehow disable signaling for programs externally... that is, without modifying their source code?
Context:
I'm calling a C (and also a Java) program from within a bash script on Linux. I don't want any interruptions for my bash script, and for the other programs that the script launches (as foreground processes).
While I can use a...
trap '' INT
... in my bash script to disable the Ctrl C signal, this works only when the program control happens to be in the bash code. That is, if I press Ctrl C while the C program is running, the C program gets interrupted and it exits! This C program is doing some critical operation because of which I don't want it be interrupted. I don't have access to the source code of this C program, so signal handling inside the C program is out of question.
#!/bin/bash
trap 'echo You pressed Ctrl C' INT
# A C program to emulate a real-world, long-running program,
# which I don't want to be interrupted, and for which I
# don't have the source code!
#
# File: y.c
# To build: gcc -o y y.c
#
# #include <stdio.h>
# int main(int argc, char *argv[]) {
# printf("Performing a critical operation...\n");
# for(;;); // Do nothing forever.
# printf("Performing a critical operation... done.\n");
# }
./y
Regards,
/HS
The process signal mask is inherited across exec, so you can simply write a small wrapper program that blocks SIGINT and executes the target:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGINT);
sigprocmask(SIG_BLOCK, &sigs, 0);
if (argc > 1) {
execvp(argv[1], argv + 1);
perror("execv");
} else {
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
}
return 1;
}
If you compile this program to noint, you would just execute ./noint ./y.
As ephemient notes in comments, the signal disposition is also inherited, so you can have the wrapper ignore the signal instead of blocking it:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
struct sigaction sa = { 0 };
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, 0);
if (argc > 1) {
execvp(argv[1], argv + 1);
perror("execv");
} else {
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
}
return 1;
}
(and of course for a belt-and-braces approach, you could do both).
The "trap" command is local to this process, never applies to children.
To really trap the signal, you have to hack it using a LD_PRELOAD hook. This is non-trival task (you have to compile a loadable with _init(), sigaction() inside), so I won't include the full code here. You can find an example for SIGSEGV on Phack Volume 0x0b, Issue 0x3a, Phile #0x03.
Alternativlly, try the nohup and tail trick.
nohup your_command &
tail -F nohup.out
I would suggest that your C (and Java) application needs rewriting so that it can handle an exception, what happens if it really does need to be interrupted, power fails, etc...
I that fails, J-16 is right on the money. Does the user need to interract with the process, or just see the output (do they even need to see the output?)
The solutions explained above are not working for me, even by chaining the both commands proposed by Caf.
However, I finally succeeded in getting the expected behavior this way :
#!/bin/zsh
setopt MONITOR
TRAPINT() { print AAA }
print 1
( ./child & ; wait)
print 2
If I press Ctrl-C while child is running, it will wait that it exits, then will print AAA and 2. child will not receive any signals.
The subshell is used to prevent the PID from being shown.
And sorry... this is for zsh though the question is for bash, but I do not know bash enough to provide an equivalent script.
This is example code of enabling signals like Ctrl+C for programs which block it.
fixControlC.c
#include <stdio.h>
#include <signal.h>
int sigaddset(sigset_t *set, int signo) {
printf("int sigaddset(sigset_t *set=%p, int signo=%d)\n", set, signo);
return 0;
}
Compile it:
gcc -fPIC -shared -o fixControlC.so fixControlC.c
Run it:
LD_LIBRARY_PATH=. LD_PRELOAD=fixControlC.so mysqld

Resources