Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
363 views
in Technique[技术] by (71.8m points)

C - How can a pointer overwrite a local const block of memory but not the global const block of memory?

Last time I asked how can I generate segmentation fault in a program by bypassing the compiler's promise of not overwriting the const memory. User Marco Bonelli described the following way, which worked perfectly.

const static int global = 123;

int main(void) {
  int *ptr = (int *)&global;
  *ptr = 456;

  // or, equivalent
  const int *ptr2 = &global;
  *(int *)ptr2 = 456;
}

Either way I was able to generate segmentation fault.

  • int *ptr = (int *)&global;
    *ptr = 456;
    
  • const int *ptr2 = &global;
    *(int *)ptr2 = 456;
    

Now my question is what is it that is preventing the pointer from writing to a global const block of memory but not to the local const block of memory. For example, in the below code I was able to write to the const block of memory without any issue.

#include <stdio.h>

int main(void) {
  const int local = 123;
  
  int *ptr = (int *)&local;
  *ptr = 456;
  
  // how come this be possible?
  printf("%d
", local); // -> 456

  // or, equivalent
  const int *ptr2 = &local;
  *(int *)ptr2 = 512;

  // how come this be possible?
  printf("%d
", local); // -> 512
}

I'm curious about knowing how this happened. Please enlighten me.

If it matters, I'm using gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

after the termination of the program what exactly happens to that block?

What happens to the virtual memory of your process is decided by the operating system. When the program terminates, the operating system will wipe out any memory that was allocated for your program, regardless of what that memory was being used for. The concept of const has nothing to do with this.

Was the compiler able to remove that const qualifier from that particular block? Can I be able to overwrite that block of memory, if so how can I do that explicitly?

You cannot change how a variable was declared. It stays that way for its entire lifetime. You won't be able to do this, and even then, it's undefined behavior to try doing it.

What if I need to overwrite a const block of memory? Is there any way to do that?

If you need to do this, the logic of whatever program you are writing is flawed. You cannot, and should not do this. It is undefined behavior, and in the best scenario will kill your program with a segmentation fault.


Ok, if you really want to kill your program with a segmentation fault caused by writing to a const variable, assuming that your compiler puts global const variables in a read only section (e.g. .rodata), then the following should suffice:

const static int global = 123;

int main(void) {
    int *ptr = (int *)&global;
    *ptr = 456;

    // or, equivalent
    const int *ptr2 = &global;
    *(int *)ptr2 = 456;
}

You need to "cast away" the const qualifier in order for the compiler to not treat it as an error. Again, this only works if the compiler puts global into a read-only section (which is not required by the standard). If this does not cause a segmentation fault, then this means your compiler does not put all const variables in read-only sections.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...