5

It suddenly comes to me how easy it will be for a sudoer to crash the kernel, so I tried something like this:

#include<stdio.h>

int main(){
    printf("hello world");
    int a;
    printf("%p", &a);
    int *p = (int*)0xffff000000000000; //x86_64, somewhere in the kernel space
    printf("%p:%d", p,*p);
    *p = 1;
    printf("%p:%d", p,*p);
}

Understandably, without sudo, running the program turns out a segment fault. However, I got NOTHING when execute it via sudo ./a.out! Even the hello world in first line is suppressed without any error or warnings at all.

Can someone explain what's happening?

1
  • The system should prevent that behavior even from root I think.
    – Kiwy
    Commented Dec 18, 2013 at 9:19

2 Answers 2

12

Of course it won't crash the kernel, you're writing to the virtual memory space of your own program, not the real kernel memory space.

Learn more about virtual memory here

P.S:

Why printf doesn't print anything? By default standard output is line-buffered, and your hello world doesn't contain a line separator.

So if the program crashed, you will not observe that output (Try use puts or adding a \n in your message)

6
  • 3
    "you're writing to the virtual memory space of your own program" Wrong. This is a misinterpretation of virtual addressing. Writing involves real RAM. If the write were successful, it could be to a location where the kernel is stored, since it is an out-of-bounds address. However, the system does not allow such writes -- it sends SIGFAULT instead; in fact, it does it trying to read from or otherwise access such an address, e.g., at the declaration of the pointer, when the memory would have been still virtual. The act of writing maps a virtual address to a real one.
    – goldilocks
    Commented Dec 18, 2013 at 12:28
  • 1
    Sorry, it's called SIGSEGV, not SIGFAULT.
    – goldilocks
    Commented Dec 18, 2013 at 12:34
  • @goldilocks “you're writing to the virtual memory space of your own program” is a correct way to put it. A task is always writing to its own memory space (except early at boot time before turning on the MMU), even the kernel. What makes the kernel special (among other things) is that it's the only task that's allowed to modify its own memory mappings, so the kernel can choose to map any page corresponding to RAM or other devices, but applications have to use what the kernel gives them, which is mostly pages that the kernel has reserved for their exclusive use. Commented Dec 18, 2013 at 23:16
  • @Gilles : It's not a correct way to put it if you leverage it against "not the real kernel space" in this context. The kernel space part of that virtual space is the real kernel space, just you are not allowed to write to it. Those addresses do map to where the kernel is; that first sentence implies to me a sense of "even if you did write to that address, it wouldn't really be the kernel", which is false; specifics of the address aside, it is really be there.
    – goldilocks
    Commented Dec 19, 2013 at 8:12
  • @goldilocks If an application tries to access the kernel range of the address space, it comes out as unmapped. From the application's perspective, there's nothing there. Depending on the architecture, switching the CPU to a privileged mode might automatically bring in RAM and devices in this address range with no extra MMU operation, but that's an implementation detail that the MMU can't observe. Commented Dec 19, 2013 at 10:06
3

Understandably, without sudo, running the program turns out a segment fault. I got NOTHING when execute it via sudo ./a.out!

Are you sure it ran at all?

#include <stdio.h>

int main (void) {
    fprintf(stderr,"Attempting out-of-bounds access.\n");
    int *p = (int*)0xffff000000000000;
    fprintf(stderr,"%d\n", *p);
    *p = 666;
    fprintf(stderr,"%d\n", *p);
    return 0;
}        

This one uses stderr, since it is not buffered, to avoid the problems described by warl0ck.

me@home> ./a.out
Attempting out-of-bounds access.
Segmentation fault
me@home> su root
Password:
root@home> ./a.out
Attempting out-of-bounds access.
Segmentation fault  

Exactly what should happen. The system will never let anyone do this. This line:

int *p = (int*)0xffff000000000000;

When compiled and run gets a SIGSEGV, aka. a "segmentation fault".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .