Not all processes on a computer share the same memory space for security reasons. What do I mean when I talk about different spaces of memory? Consider the following 2 programs:
//program 1 int main(int argc, char** argv){ printf("%02x", *((uint8_t*)0xf00fba11)); return 0; } //program 2 int main(int argc, char** argv){ printf("%02x", *((uint8_t*)0xf00fba11)); return 0; }
If these programs should run simultaneously (and assuming they are not segfault (which they will almost certainly be)), they will print different values. How can it be?? They both access memory location 0xf00fba11! ... or are they?
To understand what is happening here, we first need to understand what happens when the processor loads a value from memory. To load a value from memory, the processor sends a request to RAM, for example:
cpu |-------------| |---------| | read |-------address out to RAM (0xf00fba11)---->| RAM | | | | | | *0xf00fba11 |<---------data coming back to CPU----------| | |-------------| |---------|
There is special hardware between the processor and the operator that translates addresses from "virtual addresses" to "physical addresses"; it is called a memory management unit ( MMU for short). If the program requests a value at address 0x1000, the MMU can "reassign" 0x1000 to 0x8000. If the address 0x1000 is always replaced by 0x8000 before it reaches RAM for all reads and writes, this may seem pointless. The program still works the exact same way ... so is this a significant deal?
The big deal is that now programs 1 and 2 cannot access other data. The MMU can be configured so that there is no address that program 1 can read from which it contains one of the variables of program 2. This “mapping” is unique to each process (basically) and is configured by the operating system.
Here is an example of how the MMU can affect our example "f00fba11".
Process 1 cpu |-------------| |---------| | read |---0xf00fba11---| MMU |--0x1000ba11------->| RAM | | | | | | *0xf00fba11 |<---------data coming back to CPU----------| | |-------------| |---------| Process 2 cpu |-------------| |---------| | read |---0xf00fba11---| MMU |--0x7000ba11------->| RAM | | | | | | *0xf00fba11 |<---------data coming back to CPU----------| | |-------------| |---------|
Both process 1 and process 2 requested data stored at memory address 0xf00fba11, but they were given 2 completely different memory cells! This brilliant invention is called "virtual memory." We say that 2 processes have different “address spaces” if the MMU displays its memories in different ways. The operating system solves these mappings and configures the MMU to comply, thereby "isolating" the processes from each other. Consider 2 processes and memory addresses that they can access.
Process 1 asks for | gets physical address ------------------------------------ 0x0000 - 0x0fff | ERROR SEGFAULT 0x1000 - 0x1fff | 0x70000 - 0x70fff 0x2000 - 0x2fff | 0x30000 - 0x30fff 0x3000 - 0x3fff | 0xa7000 - 0xa7fff etc.... | etc..... Process 2 asks for | gets physical address ------------------------------------ 0x0000 - 0x0fff | ERROR SEGFAULT 0x1000 - 0x1fff | 0xb1000 - 0xb1fff 0x2000 - 0x2fff | 0x40000 - 0x40fff 0x3000 - 0x3fff | 0x1c000 - 0x1cfff etc.... | etc.....
So, if the envrionment variable is loaded at memory address 0x7ffe2a673d84 in process 1, it can translate to the physical address 0x63002a673d84. Moreover, when process 2 tries to access * 0x7ff32a673d84, it will be mapped to a completely different address, or in your case it may be REQUIRED for process 2, which will lead to SEGFAULT.
So the bad news: I don’t think you can fix this problem with your code. Doing what you are trying to do will either give you segfault or random useless data. To get the data you are interested in, you need to look at the MMU configuration settings and change them, which you are not allowed to do if you are not working at an elevated privilege level.
Before we part, it is worth noting that there can be several common addresses between processes in order to transfer data between two processes or to access shared software libraries. That is, 0x1000 will translate to 0x5000 for several different processes.
Or maybe I have no idea what you're talking about. I really did not follow the line about ./getenv PATH ./fmt_vuln