tags:

views:

729

answers:

11

Somebody told me that allocating with malloc is not secure anymore, I'm not a C/C++ guru but I've made some stuff with malloc and C/C++. Does anyone know about what risks I'm into?

Quoting him:

[..] But indeed the weak point of C/C++ it is the security, and the Achilles' heel is indeed malloc and the abuse of pointers. C/C++ it is a well known insecure language. [..] There would be few apps in what I would not recommend to continue programming with C++."

+1  A: 

If you are using C, you have to use malloc to allocate memory, unless you have a third-party library that will allocate / manage your memory for you.

Certainly your friend has a point that it is difficult to write secure code in C, especially when you are allocating memory and dealing with buffers. But we all know that, right? :)

Justin Ethier
maybe he meant you should use calloc so that the returned memory is zero'd out.
darren
+7  A: 

Your friend could be talking about:

  • The safety of using pointers in general. For example in C++ if you're allocating an array of char with malloc, question why you aren't using a string or vector. Pointers aren't insecure, but code that's buggy due to incorrect use of pointers is.

  • Something about malloc in particular. Most OSes clear memory before first handing it to a process, for security reasons. Otherwise, sensitive data from one app, could be leaked to another app. On OSes that don't do that, you could argue that there's an insecurity related to malloc. It's really more related to free.

It's also possible your friend doesn't know what he's talking about. When someone says "X is insecure", my response is, "in what way?".

Steve Jessop
I've used in vectors.
Felix Guerrero
I agree, it looks like his friend is speaking from a C#/Java security perspective, where all pointers are evil.
caspin
+1  A: 

What he maybe wanted to warn you is about pointers usage. Yes, that will cause problems if you don't understand how it works. Otherwise, ask what your friend meant, or ask him for a reference that proof his affirmation.

Saying that malloc is not safe is like saying "don't use system X because it's insecure".

Until that, use malloc in C, and new in C++. If you use malloc in C++, people will look mad at you, but that's fine in very specific occasions.

jweyrich
+15  A: 

It's probably true that C++'s new is safer than malloc(), but that doesn't automatically make malloc() more unsafe than it was before. Did your friend say why he considers it insecure?


However, here's a few things you should pay attention to:

1) With C++, you do need to be careful when you use malloc()/free() and new/delete side-by-side in the same program. This is possible and permissible, but everything that was allocated with malloc() must be freed with free(), and not with delete. Similarly, everything that was allocated with new must be freed with delete, and never with free(). (This logic goes even further: If you allocate an array with new[], you must free it with delete[], and not just with delete.) Always use corresponding counterparts for allocation and deallocation, per object.

int* ni = new int;
free(ni);   // ERROR: don't do this!
delete ni;  // OK

int* mi = (int*)malloc(sizeof(int));
delete mi;  // ERROR!
free(mi);   // OK  

2) malloc() and new (speaking again of C++) don't do exactly the same thing. malloc() just gives you a chunk of memory to use; new will additionally call a contructor (if available). Similarly, delete will call a destructor (if available), while free() won't. This could lead to problems, such as incorrectly initialized objects (because the constructor wasn' called) or un-freed resources (because the destructor wasn't called).

3) C++'s new also takes care of allocating the right amount of memory for the type specified, while you need to calculate this yourself with malloc():

int *ni = new int;
int *mi = (int*)malloc(sizeof(int));  // required amount of memory must be
                                      // explicitly specified!
                                      // (in some situations, you can make this 
                                      // a little safer against code changes by
                                      // writing  sizeof(*mi)  instead.)

Conclusion:

In C++, new/delete should be preferred over malloc()/free() where possible. (In C, new/delete is not available, so the choice would be obvious there.)

stakx
Don't forget that a C++ implementation is free to implement `new` using any sort of allocation function as long as its behaviour conforms to the standard. In other words, `malloc` could very well be called in order to implement the allocation part of the behaviour of `new`.
Dustin
*@Dustin:* This is correct, **but** it still doesn't mean that you can `free()` something allocated with `new`. What you mentioned is implementation-specific and thus comes with no guarantees whatsoever; it shouldn't affect how you write code.
stakx
+2  A: 

It's the only way to allocate and deallocate memory in C natively. If you misuse it, it can be as insecure as anything else. Microsoft provides some "secure" versions of other functions, that take an extra size_t parametre - maybe your friend was referring to something similar? If that's the case, perhaps he simply prefers calloc() over malloc()?

mingos
Not really. Some systems provide specific APIs for memory allocation. For instance, Windows provides `LocalAlloc`, `HeapAlloc`, `GlobalAlloc`, etc. These are native.
jweyrich
By saying "native", I meant something like "present in standard C libs and available on any platform". LocalAlloc is M$-specific.
mingos
A: 

Technically speaking, malloc was never secure to begin with, but that aside, the only thing I can think of is the infamous "OOM killer" (OOM = out-of-memory) that the Linux kernel uses. You can read up on it if you want. Other than that, I don't see how malloc itself is inherently insecure.

Dustin
What do you mean by "was never secure"? In what sense?
jweyrich
By stating that current implementations of the `malloc` function are insecure, it is saying that all previous implementations that behaved in the same manner are also insecure. In other words, if `malloc` isn't secure now, then it was never secure at all. As for WHY it is insecure, I really have no idea. I was merely giving the OP the benefit of the doubt. :P
Dustin
+1  A: 

There is nothing wrong with malloc as such. Your friend apparently means that manual memory management is insecure and easily leads to bugs. Compared to other languages where the memory is managed automatically by a garbage collector (not that it is not possible to have leaks - nowadays nobody cares if the program cleans up when it terminates, what matters is that something is not hogging memory while the program is running).

Of course in C++ you wouldn't really touch malloc at all (because it simply isn't functionally equivalent to new and just doesn't do what you need, assuming most of the time you don't want just to get raw memory). And in addition, it is completely possible to program using techniques which almost entirely eliminate the possibility of memory leaks and corruption (RAII), but that takes expertise.

UncleBens
Hmmm. malloc doesn't do "what you need?" Hell, raw memory rules, and proves your mettle as a programmer. Try inheriting a C program with hundreds of thousands of lines of C, thousands of mallocs and an X-Windows base and migrating to C++. Some of us don't mind malloc/free and don't get confused on how they work and differ from new/delete. But I guess that's a matter of how many years you have been in this biz. I am an old (but adaptable) old fart.
xcramps
@xcramps: there is a _proper_ way to use raw memory in C++ and it's _not_ `malloc`: http://www.icce.rug.nl/documents/cplusplus/cplusplus08.html#l128
Longpoke
Malloc is fine for raw memory, but if you want an *object*, then it doesn't do it. Fine, use malloc + placement new + manual destructor + free if you must.
UncleBens
+12  A: 

[...] C/C++ it is a well known insecure language. [...]

Actually, that's wrong. Actually, "C/C++" doesn't even exist. There's C, and there's C++. They share some (or, if you want, a lot of) syntax, but they are indeed very different languages.

One thing they differ in vastly is their way to manage dynamic memory. The C way is indeed using malloc()/free() and if you need dynamic memory there's very little else you can do but use them (or a few siblings of malloc()).
The C++ way is to not to (manually) deal with dynamic resources (of which memory is but one) at all. Resource management is handed to a few well-implemented and -tested classes, preferably from the standard library, and then done automatically. For example, instead of manually dealing with zero-terminated character buffers, there's std::string, instead of manually dealing with dynamically allocated arrays, there std:vector, instead of manually dealing with open files, there's the std::fstream family of streams etc.

sbi
Indeed I only use vector types, when I got some arrays of images in raw format. (OPENCV)
Felix Guerrero
"There's C, and there's C++." - that's the case now, but it wasn't always the case (the early C++ implementations translated all C++ code to C and then compiled them with a C compiler". His friend might now be familiar with the way things used to be.
sheepsimulator
@sheepsimulator: Sorry, but I don't follow you at all. What does it matter what C++ code used to be translated into? FWIW, yacc files are still translated into C code, which is then compiled by a C compiler. Would you claim that there is any resemblance between the declarative programming paradigm of yacc files and the structured paradigm of C, just because yacc files are translated into C? Is there a Yacc/C language family? And C++ is mostly translated into machine code now. Is that relevant? Would you claim there's a C++/MachineCode language family?
sbi
I'm fine to admit that C++ was once closer to C than it is now. But C++ now has mostly cursory syntactic resemblance to C. A class in C++ (even if spelled `struct`) is something fundamentally different from a C `struct`. And that's not even mentioning inheritance, exceptions, templates... C++ supports structured, object-oriented, generic, generative, functional, and other paradigms. C directly supports structured programming only. There, in the structured programming, they are alike. But, setting aside the syntax, C++ has just as much alike to Pascal and other structured paradigm languages.
sbi
@sbi - Read the answer I gave, and maybe my comment will make a bit more sense... some programmers make incorrect assumptions about things.
sheepsimulator
@sheepsimulator: I just did, and I still disagree with your comment.
sbi
+1 for "C/C++ doesn't exist". That's a major pet peeve of mine.
Maulrus
A: 

In C++, there is no such problem if you stick to good conventions. In C, well, practice. Malloc itself is not an inherently insecure function at all - people simply can deal with it's results inadequately.

DeadMG
+3  A: 

Maybe your friend is older, and isn't familiar with how things work now - I used to think C and C++ were effectively the same until I discovered many new things about the language that have come out in the last 10 years (most of my teachers were old-school Bell Laboratories guys who wrote primarily in C and had only a cursory knowledge of C++ - and Bell Laboratories engineers invented C++!). Don't laugh at him/her - you might be there someday too!

I think your friend is uncomfortable with the idea that you have to do your own memory management - ie, its easy to make mistakes. In that regard, it is insecure and he/she is correct... However, that insecure aspect can be overcome with good programming practices, like RAII and using smart pointers.

For many applications, though, having automated garbage collection is probably fine, and some programmers are confused about how pointers work, so as far as getting new, inexperienced developers to program effectively in C/C++ without some training might be difficult. Which is maybe why your friend thinks C/C++ should be avoided.

sheepsimulator
A: 

It is not secure to use malloc because it's not possible to write a large scale application and ensure every malloc is freed in an efficient manner. Thus, you will have tons of memory leaks which may or may not be a problem... but, when you double free, or use the wrong delete etc, undefined behaviour can result. Indeed, using the wrong delete in C++ will typically allow arbitrary code execution.

The ONLY way for code written in a language like C or C++ to be secure is to mathematically prove the entire program with its dependencies factored in.

Modern memory-safe languages are safe from these types of bugs as long as the underlying language implementation isn't vulnerable (which is indeed rare because these are all written in C/C++, but as we move towards hardware JVMs, this problem will go away).

Longpoke