Why doesn't free() zero out the memory prior t

2019-02-18 12:52发布

问题:

When we free() memory in C, why is that memory not filled with zero? Is there a good way to ensure this happens as a matter of course when calling free()?

I'd rather not risk leaving sensitive data in memory released back to the operating system...

回答1:

Zeroing out the memory block when freeing it will require extra time. Since most of time there's actually no need in it it is not done by default.

If you really need (say you used memory for storing a password or a cryptographic key) - call memset() before freeing the block. Writing an utility function that chains memset() and free() is not a problem either.



回答2:

C why is the memory not explictly set to zero in the free implementation .

Because of speed.

Because after we free the memory any how we set it to zero after freeing.

Eh?



回答3:

If you want the memory to be set to 0 when you free it, you'll have to do it yourself before you free() it. If you try after you free() it there are no guarantees that it hasn't been allocated again. For instance you can use memset() for that.

free() doesn't guarantee that the memory will be cleared because C doesn't guarantee that malloc() will return initialized memory. Either way you have to initialize it yourself after it's been allocated, so there's no point in clearing it when it's free()'d



回答4:

The original C philosophy was to have keep implicit effects to an absolute minimum. If a programmer wants a pointer zeroed after the memory pointed to is freed, that's what the programmer should write. Those of us who do often use a macro like this one:

#define FREE(P) ((void)(free((P)), (P) = NULL))

Of course if the expression passed to FREE has side effects, one has just opened a large can of worms...



回答5:

free() doesn't release memory back to the OS - it releases back to the process's heap manager. For efficiency reasons, it is not zero'd out.

When a process allocates virtual memory, most OS's will hand it a zero'd page. This prevents memory from "leaking" from one process to the other and causing a security issue like you mention.

If you have data in your process that you don't want to keep in memory (for example, a user's password), you are responsible for zeroing it out. Windows provides the SecureZeroMemory API for this.



回答6:

[Edit: this is an attempt to answer the original poster's question. The question may or may not have been changed by shog9's edit - it's hard to say since the original was unclear...]

If you mean, as others have assumed, setting 0 for every byte of the memory block being freed, then you cannot do that after freeing the block. Attempting to do it yields undefined behaviour. So if you're doing that, then you have badly misunderstood memory allocation.

But I'm guessing when you say "we set it to zero after freeing", you're maybe talking about code like this:

free(ptr);
ptr = NULL;

If so, then the reason free can't set ptr to NULL, is that free only receives the value from the variable ptr. It has no way of modifying ptr, because you aren't passing the variable ptr itself into free. You're just passing the address currently stored in it. This is part of the design of the C language - when you call a function passing a value, then the callee cannot tell how that value was computed, or what variable might contain it in the caller's code. Making an exception to this language rule just for free would be crazy, even if it were possible.

In any case, not everyone zeroes out pointers after freeing them. Some people think it's a good safety measure, other people think it is not. Whatever you think of it, though, the code doesn't zero the memory, it only zeros the pointer to the memory. If you want to write a function which clears the pointer for you, then you can:

void free_and_clear(void **pptr) {
    free(*pptr);
    *pptr = NULL;
}

Then use it like this:

free_and_clear(&ptr);

Note that this passes a pointer to the variable ptr, instead of the value of ptr. So free_and_clear can modify ptr. But this puts some restrictions on how you can use it which don't apply to free - you need a pointer to a modifiable value, rather than just a value.



回答7:

memset(ptr, 0, size);
free(ptr);

i think you want this...



回答8:

C was originally designed as a system implementation language, and so C operations are generally as fast and as close to the metal as is practical. One key point in the design philosophy is that you can take several fast operations and make them into one slower and safer operation, but you can't take slower and safer operations and make a faster one.

If you want a zero-and-free function, you can write one, and use it instead of free(). If you're concerned with security, I'd recommend it.



回答9:

A very specific answer to the question "Why is the memory not set to 0 after freeing it?" is "Because the language specification does not define that behavior.

From the draft ANSI C spec: "The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation."



回答10:

Setting the result of a freed pointer to zero may seem to be bullshit, but if the pointer is inadvertently accessed later, you'll get a segfault (at least in a real OS), and the debugger will point to where this abomination is happening. But as others have noted, when you call "free" later, all free has is the address to free, and nothing else.



回答11:

If I understand the question correctly the OP wants to not leave sensitive information "out there" in fear of it being compromised. As the previous posters pointed out freeing the memory before releasing it is the answer to wiping the data.

However, it is far from the answer to what the OP is trying to achieve. For starters zeroing the memory is 100% useless in securing your application. Even if the memory page is allocated to another running process, in most OSs this procedure is non-deterministic and no sane hacker will EVER use such a technique to compromise your data.

What a sane hacker would do is whack your program into a disassembler and debug through it until they figure out where the data is and then use it. Since a call to memset is bleedingly obvious once you are a competent disassemblerator(yes, disassemblerator :) ) our hypothetical hacker would just get to the data before memset happens.

To really answer your question. If you are trying to protect some sensitive data inside your C program you are getting in the domain that is far beyond normal C/C++ programmers(like myself) into realm of writing virtual machines for executing your data sensitive operations.

The fact that you even ask this question means that it would be reckless for you to develop something that requires this level of protection. Also it will absolutely not be the first stop in protecting your data. Pick the low hanging fruit first and there is plenty info on the web about that.



回答12:

This is a FAQ: Why isn't a pointer null after calling free?



回答13:

Because it would be a pure waste of time.



回答14:

Once you free memory using free(), the value & the memory allocated at that particular address gets deleted (freed) but the pointer still points to that address. If you try to de-reference that pointer you will get Segmentation fault or Bus error. So, its safe to assign NULL value to the pointer once the memory pointed by the pointer is freed. You may refer < Setting variable to NULL after free >



回答15:

There's also bzero(3).