If the heap is initialized for security, then why is the stack uninitialized? The Next CEO of Stack OverflowRead the stack of another process?Reason for security repositories in Debian?How can I monitor per process/per thread memory consumption (divided into heap, stack, data, code)?Security of zone transfers for bindCreation of the heap region/segment in Linuxsecurity issues from installing from source code as rootWhat are the most restrictive external firewall / DNS listening port settings I can have for my DNS server (internal clients only)Why must the stack VMA be executable?Hardening the security of rhel6/7 serversWhen is the heap used for dynamic memory allocation?
How long to clear the 'suck zone' of a turbofan after start is initiated?
Term for the "extreme-extension" version of a straw man fallacy?
Overlapping nodes in a decision tree
suction cup thing with 1/4 TRS cable?
Why doesn't a table tennis ball float on the surface? How do we calculate buoyancy here?
Fastest way to shutdown Ubuntu Mate 18.10
How can a function with a hole (removable discontinuity) equal a function with no hole?
Customer Requests (Sometimes) Drive Me Bonkers!
How to start emacs in "nothing" mode
'Given that' in a matrix
Can the Reverse Gravity spell affect the Meteor Swarm spell?
Why does standard notation not preserve intervals (visually)
How to pronounce the slash sign
How do spells that require an ability check vs. the caster's spell save DC work?
What makes a siege story/plot interesting?
Number of words that can be made using all the letters of the word W, if Os as well as Is are separated is?
Can a caster that cast Polymorph on themselves stop concentrating at any point even if their Int is low?
Return the Closest Prime Number
Opposite of a diet
Is it my responsibility to learn a new technology in my own time my employer wants to implement?
Inappropriate reference requests from Journal reviewers
How do I construct this japanese bowl?
Anatomically Correct Strange Women In Ponds Distributing Swords
What is the point of a new vote on May's deal when the indicative votes suggest she will not win?
If the heap is initialized for security, then why is the stack uninitialized?
The Next CEO of Stack OverflowRead the stack of another process?Reason for security repositories in Debian?How can I monitor per process/per thread memory consumption (divided into heap, stack, data, code)?Security of zone transfers for bindCreation of the heap region/segment in Linuxsecurity issues from installing from source code as rootWhat are the most restrictive external firewall / DNS listening port settings I can have for my DNS server (internal clients only)Why must the stack VMA be executable?Hardening the security of rhel6/7 serversWhen is the heap used for dynamic memory allocation?
On my Debian GNU/Linux 9 system, when a binary is executed,
- the stack is uninitialized but
- the heap is zero-initialized.
Why?
I assume that zero-initialization promotes security but, if for the heap, then why not also for the stack? Does the stack, too, not need security?
My question is not specific to Debian as far as I know.
Sample C code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
const size_t n = 8;
// --------------------------------------------------------------------
// UNINTERESTING CODE
// --------------------------------------------------------------------
static void print_array(
const int *const p, const size_t size, const char *const name
)
printf("%s at %p: ", name, p);
for (size_t i = 0; i < size; ++i) printf("%d ", p[i]);
printf("n");
// --------------------------------------------------------------------
// INTERESTING CODE
// --------------------------------------------------------------------
int main()
int a[n];
int *const b = malloc(n*sizeof(int));
print_array(a, n, "a");
print_array(b, n, "b");
free(b);
return 0;
Output:
a at 0x7ffe118997e0: 194 0 294230047 32766 294230046 32766 -550453275 32713
b at 0x561d4bbfe010: 0 0 0 0 0 0 0 0
The C standard does not ask malloc() to clear memory before allocating it, of course, but my C program is merely for illustration. The question is not a question about C or about C's standard library. Rather, the question is a question about why the kernel and/or run-time loader are zeroing the heap but not the stack.
security memory
add a comment |
On my Debian GNU/Linux 9 system, when a binary is executed,
- the stack is uninitialized but
- the heap is zero-initialized.
Why?
I assume that zero-initialization promotes security but, if for the heap, then why not also for the stack? Does the stack, too, not need security?
My question is not specific to Debian as far as I know.
Sample C code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
const size_t n = 8;
// --------------------------------------------------------------------
// UNINTERESTING CODE
// --------------------------------------------------------------------
static void print_array(
const int *const p, const size_t size, const char *const name
)
printf("%s at %p: ", name, p);
for (size_t i = 0; i < size; ++i) printf("%d ", p[i]);
printf("n");
// --------------------------------------------------------------------
// INTERESTING CODE
// --------------------------------------------------------------------
int main()
int a[n];
int *const b = malloc(n*sizeof(int));
print_array(a, n, "a");
print_array(b, n, "b");
free(b);
return 0;
Output:
a at 0x7ffe118997e0: 194 0 294230047 32766 294230046 32766 -550453275 32713
b at 0x561d4bbfe010: 0 0 0 0 0 0 0 0
The C standard does not ask malloc() to clear memory before allocating it, of course, but my C program is merely for illustration. The question is not a question about C or about C's standard library. Rather, the question is a question about why the kernel and/or run-time loader are zeroing the heap but not the stack.
security memory
1
at any rate, storage returned by malloc() is zero-initialized That is flat-out WRONG. Storage returned bymalloc()is not initialized to any particular value.
– Andrew Henle
1 hour ago
@AndrewHenle Sure, but the storage is null-initialized in this case, as you see. Do you have an answer?
– thb
45 mins ago
Sure, but the storage is null-initialized No, again it's NOT "null-initialized". It just happens to holdbytes. For the example you posted. It could contain anything.
– Andrew Henle
26 mins ago
@AndrewHenle Please downvote and go to find another question to answer. You do not understand this question and are wasting my time.
– thb
16 mins ago
I don't understand? You obviously do not understand C initialization and are in over your head. Again, "storage returned by malloc() is zero-initialized" is flat-out WRONG: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. There is no such thing as a "heap" mentioned even once in the C standard. You can't even find the letters "h", "e", "a", and "p" in the C standard in order as part of a longer word.
– Andrew Henle
4 mins ago
add a comment |
On my Debian GNU/Linux 9 system, when a binary is executed,
- the stack is uninitialized but
- the heap is zero-initialized.
Why?
I assume that zero-initialization promotes security but, if for the heap, then why not also for the stack? Does the stack, too, not need security?
My question is not specific to Debian as far as I know.
Sample C code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
const size_t n = 8;
// --------------------------------------------------------------------
// UNINTERESTING CODE
// --------------------------------------------------------------------
static void print_array(
const int *const p, const size_t size, const char *const name
)
printf("%s at %p: ", name, p);
for (size_t i = 0; i < size; ++i) printf("%d ", p[i]);
printf("n");
// --------------------------------------------------------------------
// INTERESTING CODE
// --------------------------------------------------------------------
int main()
int a[n];
int *const b = malloc(n*sizeof(int));
print_array(a, n, "a");
print_array(b, n, "b");
free(b);
return 0;
Output:
a at 0x7ffe118997e0: 194 0 294230047 32766 294230046 32766 -550453275 32713
b at 0x561d4bbfe010: 0 0 0 0 0 0 0 0
The C standard does not ask malloc() to clear memory before allocating it, of course, but my C program is merely for illustration. The question is not a question about C or about C's standard library. Rather, the question is a question about why the kernel and/or run-time loader are zeroing the heap but not the stack.
security memory
On my Debian GNU/Linux 9 system, when a binary is executed,
- the stack is uninitialized but
- the heap is zero-initialized.
Why?
I assume that zero-initialization promotes security but, if for the heap, then why not also for the stack? Does the stack, too, not need security?
My question is not specific to Debian as far as I know.
Sample C code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
const size_t n = 8;
// --------------------------------------------------------------------
// UNINTERESTING CODE
// --------------------------------------------------------------------
static void print_array(
const int *const p, const size_t size, const char *const name
)
printf("%s at %p: ", name, p);
for (size_t i = 0; i < size; ++i) printf("%d ", p[i]);
printf("n");
// --------------------------------------------------------------------
// INTERESTING CODE
// --------------------------------------------------------------------
int main()
int a[n];
int *const b = malloc(n*sizeof(int));
print_array(a, n, "a");
print_array(b, n, "b");
free(b);
return 0;
Output:
a at 0x7ffe118997e0: 194 0 294230047 32766 294230046 32766 -550453275 32713
b at 0x561d4bbfe010: 0 0 0 0 0 0 0 0
The C standard does not ask malloc() to clear memory before allocating it, of course, but my C program is merely for illustration. The question is not a question about C or about C's standard library. Rather, the question is a question about why the kernel and/or run-time loader are zeroing the heap but not the stack.
security memory
security memory
edited 18 mins ago
thb
asked 5 hours ago
thbthb
534415
534415
1
at any rate, storage returned by malloc() is zero-initialized That is flat-out WRONG. Storage returned bymalloc()is not initialized to any particular value.
– Andrew Henle
1 hour ago
@AndrewHenle Sure, but the storage is null-initialized in this case, as you see. Do you have an answer?
– thb
45 mins ago
Sure, but the storage is null-initialized No, again it's NOT "null-initialized". It just happens to holdbytes. For the example you posted. It could contain anything.
– Andrew Henle
26 mins ago
@AndrewHenle Please downvote and go to find another question to answer. You do not understand this question and are wasting my time.
– thb
16 mins ago
I don't understand? You obviously do not understand C initialization and are in over your head. Again, "storage returned by malloc() is zero-initialized" is flat-out WRONG: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. There is no such thing as a "heap" mentioned even once in the C standard. You can't even find the letters "h", "e", "a", and "p" in the C standard in order as part of a longer word.
– Andrew Henle
4 mins ago
add a comment |
1
at any rate, storage returned by malloc() is zero-initialized That is flat-out WRONG. Storage returned bymalloc()is not initialized to any particular value.
– Andrew Henle
1 hour ago
@AndrewHenle Sure, but the storage is null-initialized in this case, as you see. Do you have an answer?
– thb
45 mins ago
Sure, but the storage is null-initialized No, again it's NOT "null-initialized". It just happens to holdbytes. For the example you posted. It could contain anything.
– Andrew Henle
26 mins ago
@AndrewHenle Please downvote and go to find another question to answer. You do not understand this question and are wasting my time.
– thb
16 mins ago
I don't understand? You obviously do not understand C initialization and are in over your head. Again, "storage returned by malloc() is zero-initialized" is flat-out WRONG: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. There is no such thing as a "heap" mentioned even once in the C standard. You can't even find the letters "h", "e", "a", and "p" in the C standard in order as part of a longer word.
– Andrew Henle
4 mins ago
1
1
at any rate, storage returned by malloc() is zero-initialized That is flat-out WRONG. Storage returned by
malloc() is not initialized to any particular value.– Andrew Henle
1 hour ago
at any rate, storage returned by malloc() is zero-initialized That is flat-out WRONG. Storage returned by
malloc() is not initialized to any particular value.– Andrew Henle
1 hour ago
@AndrewHenle Sure, but the storage is null-initialized in this case, as you see. Do you have an answer?
– thb
45 mins ago
@AndrewHenle Sure, but the storage is null-initialized in this case, as you see. Do you have an answer?
– thb
45 mins ago
Sure, but the storage is null-initialized No, again it's NOT "null-initialized". It just happens to hold
bytes. For the example you posted. It could contain anything.– Andrew Henle
26 mins ago
Sure, but the storage is null-initialized No, again it's NOT "null-initialized". It just happens to hold
bytes. For the example you posted. It could contain anything.– Andrew Henle
26 mins ago
@AndrewHenle Please downvote and go to find another question to answer. You do not understand this question and are wasting my time.
– thb
16 mins ago
@AndrewHenle Please downvote and go to find another question to answer. You do not understand this question and are wasting my time.
– thb
16 mins ago
I don't understand? You obviously do not understand C initialization and are in over your head. Again, "storage returned by malloc() is zero-initialized" is flat-out WRONG: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. There is no such thing as a "heap" mentioned even once in the C standard. You can't even find the letters "h", "e", "a", and "p" in the C standard in order as part of a longer word.
– Andrew Henle
4 mins ago
I don't understand? You obviously do not understand C initialization and are in over your head. Again, "storage returned by malloc() is zero-initialized" is flat-out WRONG: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. There is no such thing as a "heap" mentioned even once in the C standard. You can't even find the letters "h", "e", "a", and "p" in the C standard in order as part of a longer word.
– Andrew Henle
4 mins ago
add a comment |
3 Answers
3
active
oldest
votes
You’re not seeing a pristine stack, which you could use to deduce how the stack is initialised, because the C library does a number of things before calling main, and they touch the stack.
With the GNU C library, on x86-64, execution starts at the _start entry point, which calls __libc_start_main to set things up, and the latter ends up calling main. But before calling main, it calls a number of other functions, which causes various pieces of data to be written to the stack. The stack’s contents aren’t cleared in between function calls, so when you get into main, your stack contains leftovers from the previous function calls.
add a comment |
The storage returned by malloc() is not zero-initialized. Do not ever assume it is.
In your test program, it's just a fluke: I guess the malloc()just got a fresh block off mmap(), but don't rely on that, either.
For an example, if I run your program on my machine this way:
$ echo 'void __attribute__((constructor)) p(void)
void *b = malloc(4444); memset(b, 4, 4444); free(b);
' | cc -include stdlib.h -include string.h -xc - -shared -o pollute.so
$ LD_PRELOAD=./pollute.so ./your_program
a at 0x7ffd40d3aa60: 1256994848 21891 1256994464 21891 1087613792 32765 0 0
b at 0x55834c75d010: 67372036 67372036 67372036 67372036 67372036 67372036 67372036 67372036
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
add a comment |
In both cases, you get uninitialized memory, and you can't make any assumptions about its contents.
When the OS has to apportion a new page to your process, it guarantees that it won't expose data from other processes; the usual way to ensure that is to fill it with zeros (but it's equally valid to overwrite with anything else, including even a page worth of /dev/urandom - in fact some debugging malloc() implementations write non-zero patterns, to catch mistaken assumptions such as yours).
If malloc() can satisfy the request from memory already used in this process, its contents won't be cleared (in fact, the clearing is nothing to do with malloc() and it can't be - it has to happen before the memory is mapped into your address space). You may get memory that has previously been written by your process/program (e.g. before main()).
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
A week or two ago, I tried a different experiment, callingmalloc()andfree()repeatedly. Though nothing requiresmalloc()to reuse the same storage recently freed, in the experiment,malloc()did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.
– thb
7 mins ago
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f509232%2fif-the-heap-is-initialized-for-security-then-why-is-the-stack-uninitialized%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You’re not seeing a pristine stack, which you could use to deduce how the stack is initialised, because the C library does a number of things before calling main, and they touch the stack.
With the GNU C library, on x86-64, execution starts at the _start entry point, which calls __libc_start_main to set things up, and the latter ends up calling main. But before calling main, it calls a number of other functions, which causes various pieces of data to be written to the stack. The stack’s contents aren’t cleared in between function calls, so when you get into main, your stack contains leftovers from the previous function calls.
add a comment |
You’re not seeing a pristine stack, which you could use to deduce how the stack is initialised, because the C library does a number of things before calling main, and they touch the stack.
With the GNU C library, on x86-64, execution starts at the _start entry point, which calls __libc_start_main to set things up, and the latter ends up calling main. But before calling main, it calls a number of other functions, which causes various pieces of data to be written to the stack. The stack’s contents aren’t cleared in between function calls, so when you get into main, your stack contains leftovers from the previous function calls.
add a comment |
You’re not seeing a pristine stack, which you could use to deduce how the stack is initialised, because the C library does a number of things before calling main, and they touch the stack.
With the GNU C library, on x86-64, execution starts at the _start entry point, which calls __libc_start_main to set things up, and the latter ends up calling main. But before calling main, it calls a number of other functions, which causes various pieces of data to be written to the stack. The stack’s contents aren’t cleared in between function calls, so when you get into main, your stack contains leftovers from the previous function calls.
You’re not seeing a pristine stack, which you could use to deduce how the stack is initialised, because the C library does a number of things before calling main, and they touch the stack.
With the GNU C library, on x86-64, execution starts at the _start entry point, which calls __libc_start_main to set things up, and the latter ends up calling main. But before calling main, it calls a number of other functions, which causes various pieces of data to be written to the stack. The stack’s contents aren’t cleared in between function calls, so when you get into main, your stack contains leftovers from the previous function calls.
answered 3 hours ago
Stephen KittStephen Kitt
178k24406483
178k24406483
add a comment |
add a comment |
The storage returned by malloc() is not zero-initialized. Do not ever assume it is.
In your test program, it's just a fluke: I guess the malloc()just got a fresh block off mmap(), but don't rely on that, either.
For an example, if I run your program on my machine this way:
$ echo 'void __attribute__((constructor)) p(void)
void *b = malloc(4444); memset(b, 4, 4444); free(b);
' | cc -include stdlib.h -include string.h -xc - -shared -o pollute.so
$ LD_PRELOAD=./pollute.so ./your_program
a at 0x7ffd40d3aa60: 1256994848 21891 1256994464 21891 1087613792 32765 0 0
b at 0x55834c75d010: 67372036 67372036 67372036 67372036 67372036 67372036 67372036 67372036
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
add a comment |
The storage returned by malloc() is not zero-initialized. Do not ever assume it is.
In your test program, it's just a fluke: I guess the malloc()just got a fresh block off mmap(), but don't rely on that, either.
For an example, if I run your program on my machine this way:
$ echo 'void __attribute__((constructor)) p(void)
void *b = malloc(4444); memset(b, 4, 4444); free(b);
' | cc -include stdlib.h -include string.h -xc - -shared -o pollute.so
$ LD_PRELOAD=./pollute.so ./your_program
a at 0x7ffd40d3aa60: 1256994848 21891 1256994464 21891 1087613792 32765 0 0
b at 0x55834c75d010: 67372036 67372036 67372036 67372036 67372036 67372036 67372036 67372036
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
add a comment |
The storage returned by malloc() is not zero-initialized. Do not ever assume it is.
In your test program, it's just a fluke: I guess the malloc()just got a fresh block off mmap(), but don't rely on that, either.
For an example, if I run your program on my machine this way:
$ echo 'void __attribute__((constructor)) p(void)
void *b = malloc(4444); memset(b, 4, 4444); free(b);
' | cc -include stdlib.h -include string.h -xc - -shared -o pollute.so
$ LD_PRELOAD=./pollute.so ./your_program
a at 0x7ffd40d3aa60: 1256994848 21891 1256994464 21891 1087613792 32765 0 0
b at 0x55834c75d010: 67372036 67372036 67372036 67372036 67372036 67372036 67372036 67372036
The storage returned by malloc() is not zero-initialized. Do not ever assume it is.
In your test program, it's just a fluke: I guess the malloc()just got a fresh block off mmap(), but don't rely on that, either.
For an example, if I run your program on my machine this way:
$ echo 'void __attribute__((constructor)) p(void)
void *b = malloc(4444); memset(b, 4, 4444); free(b);
' | cc -include stdlib.h -include string.h -xc - -shared -o pollute.so
$ LD_PRELOAD=./pollute.so ./your_program
a at 0x7ffd40d3aa60: 1256994848 21891 1256994464 21891 1087613792 32765 0 0
b at 0x55834c75d010: 67372036 67372036 67372036 67372036 67372036 67372036 67372036 67372036
answered 1 hour ago
mosvymosvy
8,6071732
8,6071732
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
add a comment |
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
Well, yes, but this is why I have asked the question here rather than on Stack Overflow. My question was not about the C standard but about the way modern GNU/Linux systems typically link and load binaries. Your LD_PRELOAD is humorous but answers another question than the question I had meant to ask.
– thb
27 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
I'm happy I made you laugh, but your assumptions and prejudices aren't funny at all. On a "modern GNU/Linux system", binaries are typically loaded by a dynamic linker, which is running constructors from dynamic libraries before getting to the main() function from your program. On your very Debian GNU/Linux 9 system, both malloc() and free() will be called more than once before the main() function from your program, even when not using any preloaded libraries.
– mosvy
13 mins ago
add a comment |
In both cases, you get uninitialized memory, and you can't make any assumptions about its contents.
When the OS has to apportion a new page to your process, it guarantees that it won't expose data from other processes; the usual way to ensure that is to fill it with zeros (but it's equally valid to overwrite with anything else, including even a page worth of /dev/urandom - in fact some debugging malloc() implementations write non-zero patterns, to catch mistaken assumptions such as yours).
If malloc() can satisfy the request from memory already used in this process, its contents won't be cleared (in fact, the clearing is nothing to do with malloc() and it can't be - it has to happen before the memory is mapped into your address space). You may get memory that has previously been written by your process/program (e.g. before main()).
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
A week or two ago, I tried a different experiment, callingmalloc()andfree()repeatedly. Though nothing requiresmalloc()to reuse the same storage recently freed, in the experiment,malloc()did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.
– thb
7 mins ago
add a comment |
In both cases, you get uninitialized memory, and you can't make any assumptions about its contents.
When the OS has to apportion a new page to your process, it guarantees that it won't expose data from other processes; the usual way to ensure that is to fill it with zeros (but it's equally valid to overwrite with anything else, including even a page worth of /dev/urandom - in fact some debugging malloc() implementations write non-zero patterns, to catch mistaken assumptions such as yours).
If malloc() can satisfy the request from memory already used in this process, its contents won't be cleared (in fact, the clearing is nothing to do with malloc() and it can't be - it has to happen before the memory is mapped into your address space). You may get memory that has previously been written by your process/program (e.g. before main()).
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
A week or two ago, I tried a different experiment, callingmalloc()andfree()repeatedly. Though nothing requiresmalloc()to reuse the same storage recently freed, in the experiment,malloc()did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.
– thb
7 mins ago
add a comment |
In both cases, you get uninitialized memory, and you can't make any assumptions about its contents.
When the OS has to apportion a new page to your process, it guarantees that it won't expose data from other processes; the usual way to ensure that is to fill it with zeros (but it's equally valid to overwrite with anything else, including even a page worth of /dev/urandom - in fact some debugging malloc() implementations write non-zero patterns, to catch mistaken assumptions such as yours).
If malloc() can satisfy the request from memory already used in this process, its contents won't be cleared (in fact, the clearing is nothing to do with malloc() and it can't be - it has to happen before the memory is mapped into your address space). You may get memory that has previously been written by your process/program (e.g. before main()).
In both cases, you get uninitialized memory, and you can't make any assumptions about its contents.
When the OS has to apportion a new page to your process, it guarantees that it won't expose data from other processes; the usual way to ensure that is to fill it with zeros (but it's equally valid to overwrite with anything else, including even a page worth of /dev/urandom - in fact some debugging malloc() implementations write non-zero patterns, to catch mistaken assumptions such as yours).
If malloc() can satisfy the request from memory already used in this process, its contents won't be cleared (in fact, the clearing is nothing to do with malloc() and it can't be - it has to happen before the memory is mapped into your address space). You may get memory that has previously been written by your process/program (e.g. before main()).
answered 31 mins ago
Toby SpeightToby Speight
5,39711133
5,39711133
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
A week or two ago, I tried a different experiment, callingmalloc()andfree()repeatedly. Though nothing requiresmalloc()to reuse the same storage recently freed, in the experiment,malloc()did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.
– thb
7 mins ago
add a comment |
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
A week or two ago, I tried a different experiment, callingmalloc()andfree()repeatedly. Though nothing requiresmalloc()to reuse the same storage recently freed, in the experiment,malloc()did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.
– thb
7 mins ago
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
Your answer is good as far as it goes, +1, but my question has lent itself to misunderstanding. I have edited the question to clarify that I am not asking not about the requirements of the C standard (if I were asking that, I would ask on Stack Overflow) but about the observed behavior of GNU/Linux systems.
– thb
12 mins ago
A week or two ago, I tried a different experiment, calling
malloc() and free() repeatedly. Though nothing requires malloc() to reuse the same storage recently freed, in the experiment, malloc() did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.– thb
7 mins ago
A week or two ago, I tried a different experiment, calling
malloc() and free() repeatedly. Though nothing requires malloc() to reuse the same storage recently freed, in the experiment, malloc() did happen to do that. It happened to return the same address each time, but also nulled the memory each time, which I had not expected. This was interesting to me. Further experiments have led to today's question.– thb
7 mins ago
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f509232%2fif-the-heap-is-initialized-for-security-then-why-is-the-stack-uninitialized%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
at any rate, storage returned by malloc() is zero-initialized That is flat-out WRONG. Storage returned by
malloc()is not initialized to any particular value.– Andrew Henle
1 hour ago
@AndrewHenle Sure, but the storage is null-initialized in this case, as you see. Do you have an answer?
– thb
45 mins ago
Sure, but the storage is null-initialized No, again it's NOT "null-initialized". It just happens to hold
bytes. For the example you posted. It could contain anything.– Andrew Henle
26 mins ago
@AndrewHenle Please downvote and go to find another question to answer. You do not understand this question and are wasting my time.
– thb
16 mins ago
I don't understand? You obviously do not understand C initialization and are in over your head. Again, "storage returned by malloc() is zero-initialized" is flat-out WRONG: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. There is no such thing as a "heap" mentioned even once in the C standard. You can't even find the letters "h", "e", "a", and "p" in the C standard in order as part of a longer word.
– Andrew Henle
4 mins ago