简体   繁体   English

使用malloc是否安全?

[英]Is it secure to use malloc?

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++. 有人告诉我,分配malloc不再安全了,我不是C / C ++大师,但我用malloc和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 ++的弱点在于它的安全性,而阿喀琉斯的脚跟确实是malloc和滥用指针。 C/C++ it is a well known insecure language. C / C ++它是一种众所周知的不安全语言。 [..] There would be few apps in what I would not recommend to continue programming with C++." [..]我不建议继续用C ++编程的应用程序很少。“

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. C ++的new可能比malloc() 更安全 ,但这并不会自动使malloc()比以前更不安全。 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. 1)使用C ++,在同一程序中并行使用malloc() / free()new / delete时需要注意。 This is possible and permissible, but everything that was allocated with malloc() must be freed with free() , and not with delete . 这是可能的,也是允许的,但是使用malloc()分配的所有内容都必须使用free()释放,而不是使用delete Similarly, everything that was allocated with new must be freed with delete , and never with free() . 同样,使用new分配的所有内容都必须使用delete来释放,而不能使用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. (这个逻辑更进一步:如果你使用new[]分配一个数组,你必须使用delete[]释放它,而不仅仅是delete 。)每个对象总是使用相应的对应物进行分配和释放。

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. 2) malloc()new (再说一次C ++)不做完全相同的事情。 malloc() just gives you a chunk of memory to use; malloc()只是给你一大块内存来使用; new will additionally call a contructor (if available). new将另外调用一个构造函数 (如果可用)。 Similarly, delete will call a destructor (if available), while free() won't. 同样, delete将调用析构函数(如果可用),而free()则不会。 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() : 3) C ++的new也负责为指定的类型分配适量的内存 ,而你需要自己用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. 在C ++中, new / delete应尽可能优于malloc() / free() (In C, new / delete is not available, so the choice would be obvious there.) (在C中, new / delete不可用,因此选择很明显。)

[...] C/C++ it is a well known insecure language. [...] C / C ++它是一种众所周知的不安全语言。 [...] [...]

Actually, that's wrong. 实际上,那是错的。 Actually, "C/C++" doesn't even exist. 实际上,“C / C ++”甚至不存在。 There's C , and there's C++ . C ,还有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() ). C方式确实使用了malloc() / free() ,如果你需要动态内存,除了使用它们(或者malloc()的几个兄弟)之外,你可以做很少的事情。
The C++ way is to not to (manually) deal with dynamic resources (of which memory is but one) at all . C ++的方法是不给 (手动) 处理动态资源 (其中存储器仅仅是一个) 在所有 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. 例如,而不是手动处理零结尾的字符缓冲区,还有std::string ,而不是与动态分配的数组,有手动处理std:vector ,而不是手动处理打开的文件,还有的std::fstream家庭溪流等

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 . 例如,在C ++中,如果要使用malloc分配char数组,请质疑为什么不使用stringvector Pointers aren't insecure, but code that's buggy due to incorrect use of pointers is. 指针不是不安全的,但由于错误使用指针而导致错误的代码是。

  • Something about malloc in particular. 特别是关于malloc的东西。 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 . 在没有这样做的操作系统上,您可能会认为存在与malloc相关的不安全因素。 It's really more related to free . 这真的与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?". 当有人说“X不安全”时,我的回答是“以什么方式?”。

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++!). 也许你的朋友年纪大了,不熟悉现在的工作方式 - 我曾经认为C和C ++实际上是一样的,直到我发现了许多关于过去十年出现的语言的新事物(我的大部分时间)老师们是老派贝尔实验室的人,他们主要用C语言写作,只有粗略的C ++知识 - 而贝尔实验室的工程师发明了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. 在这方面,它是不安全的,他/她是正确的......然而,这种不安全的方面可以通过良好的编程实践来克服,如RAII和使用智能指针。

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. 但是对于许多应用程序来说,自动垃圾收集可能很好,并且一些程序员对指针的工作方式感到困惑,因此,如果没有经过一些培训,让新的,没有经验的开发人员在C / C ++中有效编程可能会很困难。 Which is maybe why your friend thinks C/C++ should be avoided. 这也许是为什么你的朋友认为应该避免使用C / C ++的原因。

It's the only way to allocate and deallocate memory in C natively. 这是本机分配和释放C内存的唯一方法。 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? 微软提供了一些其他功能的“安全”版本,需要额外的size_t参数 - 也许你的朋友指的是类似的东西? If that's the case, perhaps he simply prefers calloc() over malloc()? 如果是这种情况,也许他只是喜欢calloc()而不是malloc()?

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. 如果您使用C,则必须使用malloc来分配内存,除非您有第三方库为您分配/管理内存。

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. 当然,您的朋友有一个观点,即在C中编写安全代码很困难,尤其是在分配内存和处理缓冲区时。 But we all know that, right? 但我们都知道,对吧? :) :)

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". malloc不安全就像是说“不要使用系统X,因为它不安全”。

Until that, use malloc in C, and new in C++. 在此之前,在C中使用malloc ,在C ++中使用new If you use malloc in C++, people will look mad at you, but that's fine in very specific occasions. 如果你在C ++中使用malloc ,人们会对你生气,但在非常特殊的场合这很好。

There is nothing wrong with malloc as such. malloc没有任何问题。 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). 当然在C ++中你根本不会真正触摸malloc(因为它在功能上并不等同于new ,只是没有做你需要的,假设大多数时候你不想只获取原始内存) 。 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. 此外,完全可以使用几乎完全消除内存泄漏和损坏(RAII)的可能性的技术进行编程,但这需要专业知识。

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. 从技术上讲, malloc从一开始就不安全,但除此之外,我唯一能想到的就是Linux内核使用的臭名昭着的“OOM杀手”(OOM =内存不足)。 You can read up on it if you want. 如果你愿意,你可以阅读它 Other than that, I don't see how malloc itself is inherently insecure. 除此之外,我没有看到malloc本身是如何本质上不安全的。

In C++, there is no such problem if you stick to good conventions. 在C ++中,如果你遵守良好的约定就没有这样的问题。 In C, well, practice. 在C,嗯,练习。 Malloc itself is not an inherently insecure function at all - people simply can deal with it's results inadequately. Malloc本身并不是一种固有的不安全功能 - 人们只是可以不恰当地处理它的结果。

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. 使用malloc是不安全的,因为不可能编写大规模的应用程序并确保以有效的方式释放每个malloc。 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. 因此,您将有大量内存泄漏,这可能是也可能不是问题...... 但是 ,当您双重free或使用错误的delete等时,可能会导致未定义的行为。 Indeed, using the wrong delete in C++ will typically allow arbitrary code execution. 实际上,在C ++中使用错误的delete通常会允许任意代码执行。

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. 使用C或C ++等语言编写的代码唯一的安全方法是在数学上证明整个程序的依赖性因素。

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). 只要底层语言实现不易受攻击,现代内存安全语言就可以安全地避免这些类型的错误(这种情况确实很少见,因为这些都是用C / C ++编写的,但是当我们转向硬件JVM时,这个问题就会出现远)。

Perhaps the person was referring to the possibility of accessing data via malloc()? 也许这个人指的是通过malloc()访问数据的可能性?

Malloc doesn't affect the contents of the region that it provides, so it MAY be possible to collect data from other processes by mallocing a large area and then scanning the contents. Malloc不会影响它提供的区域的内容,因此可以通过mallocing大区域然后扫描内容来从其他进程收集数据。

free() doesn't clear memory either so data paced into dynamically allocated buffers is, in principle, accessible. free()不会清除内存,因此原则上可以访问数据调入动态分配的缓冲区。

I know someone who, many years ago admittedly, exploited malloc to create an inter-process communication scheme when he found that mallocs of equal size would return the address of the most recently free'd block. 我知道很多年前,当他发现大小相同的malloc会返回最近freed块的地址时,会利用malloc来创建一个进程间通信方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM