Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
    
The system should prevent that behavior even from root I think. –  Kiwy Dec 18 '13 at 9:19

2 Answers 2

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)

share|improve this answer
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 Dec 18 '13 at 12:28
1  
Sorry, it's called SIGSEGV, not SIGFAULT. –  goldilocks Dec 18 '13 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. –  Gilles Dec 18 '13 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 Dec 19 '13 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. –  Gilles Dec 19 '13 at 10:06

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".

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.