Python是memorysafe吗?

2022-05-21 08:12:56 发布

您现在位置:Python中文网/ 问答频道 /正文

由于Deno是Node.js的新竞争对手,许多新闻文章都提到了Rust的内存安全特性,其中一篇文章指出Rust和Go有利于其内存安全特性,Swift和Kotlin也是如此,但后两者并未广泛用于系统编程

Safe Rust is the true Rust programming language. If all you do is write Safe Rust, you will never have to worry about type-safety or memory-safety. You will never endure a dangling pointer, a use-after-free, or any other kind of Undefined Behavior.

这激发了我的兴趣,让我了解Python是否可以被视为内存安全,如果是或否,安全性或不安全性如何

从一开始,维基百科上的article on memory safety甚至没有提到Python,而关于Python的文章似乎只提到内存管理。 我找到的最接近答案是this one by Daniel

The wikipedia article associates type-safe to memory-safe, meaning, that the same memory area cannot be accessed as e.g. integer and string. In this way Python is type-safe. You cannot change the type of a object implicitly.

但即便如此,这似乎也只是暗示了两个方面之间的联系(使用维基百科的一个关联,这也是有争议的),并且对于Python是否可以被视为内存安全没有明确的答案


Tags: theto内存youistype文章特性rustwillsafememorysafetynever
1条回答
网友
1楼 ·

Wikipedialists以下是内存安全问题的示例:

Access errors: invalid read/write of a pointer
    Buffer overflow - out-of-bound writes can corrupt the content of adjacent objects, or internal data (like bookkeeping information for the heap) or return addresses.
    Buffer over-read - out-of-bound reads can reveal sensitive data or help attackers bypass address space layout randomization.

Python at least tries来防止这些攻击

    Race condition - concurrent reads/writes to shared memory

在具有可变数据结构的语言中,这其实并不难做到。(函数式编程和不可变数据结构的倡导者经常使用这一事实作为支持他们的论据)

    Invalid page fault - accessing a pointer outside the virtual memory space. A null pointer dereference will often cause an exception or program termination in most environments, but can cause corruption in operating system kernels or systems without memory protection, or when use of the null pointer involves a large or negative offset.
    Use after free - dereferencing a dangling pointer storing the address of an object that has been deleted.
Uninitialized variables - a variable that has not been assigned a value is used. It may contain an undesired or, in some languages, a corrupt value.
    Null pointer dereference - dereferencing an invalid pointer or a pointer to memory that has not been allocated
    Wild pointers arise when a pointer is used prior to initialization to some known state. They show the same erratic behaviour as dangling pointers, though they are less likely to stay undetected.

没有真正的方法阻止某人尝试访问空指针。在C#和Java中,这会导致exception。在C++中,这个results in undefined behavior

Memory leak - when memory usage is not tracked or is tracked incorrectly
    Stack exhaustion - occurs when a program runs out of stack space, typically because of too deep recursion. A guard page typically halts the program, preventing memory corruption, but functions with large stack frames may bypass the page.
<> C++中的内存泄漏,如C语言、java和python,它们的含义不同于C语言和C++语言,它们在这里手动管理内存。在C或C++中,由于无法释放分配的内存,会导致内存泄漏。在具有托管内存的语言中,您不必显式地取消分配内存,但仍然可以通过在某处意外地维护对它的引用来执行类似的操作

对于event handlers in C#和长寿命的集合类,这实际上非常容易做到;事实上,尽管我们使用的是托管内存,但我还是参与过内存泄漏的项目。从某种意义上说,使用具有托管内存的环境实际上会使这些问题更加危险,因为程序员可能会有错误的安全感。根据我的经验,即使是经验丰富的工程师也常常无法进行内存分析或编写测试用例来检查这一点(可能是因为环境给了他们错误的安全感)

在Python中,堆栈耗尽也很容易做到

    Heap exhaustion - the program tries to allocate more memory than the amount available. In some languages, this condition must be checked for manually after each allocation.

还是很有可能的——我很不好意思承认,我个人是用C#做的(虽然还没有用Python)

    Double free - repeated calls to free may prematurely free a new object at the same address. If the exact address has not been reused, other corruption may occur, especially in allocators that use free lists.
    Invalid free - passing an invalid address to free can corrupt the heap.
    Mismatched free - when multiple allocators are in use, attempting to free memory with a deallocation function of a different allocator[20]
    Unwanted aliasing - when the same memory location is allocated and modified twice for unrelated purposes.

在Python中,不需要的别名实际上很容易实现。这里有一个Java的example(完全公开:我写了接受的答案);您也可以轻松地在Python中执行类似的操作。其他的由Python解释器自己管理

所以,似乎记忆安全是相对的。根据你认为的“内存安全问题”,它实际上很难完全防止。Java、C#和Python等高级语言可以防止这些错误中最严重的错误,但还有其他一些问题很难或不可能完全防止