Live data from Hacker News

Make CPython segfault in 5 lines of code

gist.github.com

51–60 of 78 posts

Re: Make CPython segfault in 5 lines of code

#51

Segfaults in scripting languages are remarkably common, especially if arbitrary bytecode can be loaded into the VM. One I ran into in the wild recently is that in older versions of Lua, exceptions in GC finalizers (the `__gc` metamethod) can trigger a segfault. In those same versions of Lua, the bytecode format is notoriously dangerous to load. I wonder whether this will be a large component of newer scripting langua…

> In those same versions of Lua, the bytecode format is notoriously dangerous to load.

Could you expand on this? Are the dangers such that they could be avoided with a bytecode verifier somewhat like Java's? Things like checking that the stack can never underflow, and that at the merge points of branches the stack always has the same depth.

Re: Make CPython segfault in 5 lines of code

#52
post #47

Earlier quoted context omitted.

> This would not have happened in a language with a proper type system as the type checker would have rejected the program at compile time. How about in Rust, then? [0] Bugs happen in every language. When memory corruption occurs, you can segfault. [0] https://users.rust-lang.org/t/rust-guarantees-no-segfaults-w...

I said "a language with a proper type system". Rust is not one such language.

Can you give an example of such language so we don't have to guess?

Apparently neither Rust, Haskell nor Go fit.

Re: Make CPython segfault in 5 lines of code

#53
post #5
post #3

A quick search in bugs.python.org shows several crashes. I don’t know much about Python. Is there anything particularly special about this one?

I read it as related to the "limit Python to 1 million lines so it can be stable."

These two things have nothing to do with each other. The 1 million limit wouldn't have any effect here.

Re: Make CPython segfault in 5 lines of code

#54
post #29

Earlier quoted context omitted.

This doesn't trigger a segfault for me in Python 3.7, just an exception that `print_exception` expects an `Exception`. Someone commented below the gist with this one-liner: (i for i in []).throw(type('E', (BaseException,), dict(__new__=lambda cls, *args: cls))()) I managed to golf it a bit down to this ;): n="__new__";(i for i in []).throw(type(n,(IOError,),{n:lambda c,*a:c})())

Just one character but replace `[]` with `n` too :)

Or save that character by removing the space before `[]` instead (which you can’t do if you write `n`).

Re: Make CPython segfault in 5 lines of code

#55
post #18

Earlier quoted context omitted.

Is anybody fuzzing Python bytecodes? This sounds like a super-great application for afl.

It has always been the position of the CPython developers that using python for sandboxing is unsupported. With that in mind it doesn't really matter if you can "exploit" python with weird bytecode because you are supposed to be on the other side of the airtight hatchway[0] anyways. I don't know what the stance of other python runtimes are, but you should probably just use a sandbox at OS level which is likely to be…

It's worth mentioning the interesting failure of pysandbox:

> I now think that putting a sandbox directly in Python cannot be secure. To build a secure sandbox, the whole Python process must be put in an external sandbox.

https://mail.python.org/pipermail/python-dev/2013-November/1...

Re: Make CPython segfault in 5 lines of code

#56
post #29

If # of lines are important, this problem can actually be demonstrated in 1 line: for x, x.__new__ in [(__import__('queue').Full, print)]: __import__('glob').iglob(0).throw(x)

This doesn't trigger a segfault for me in Python 3.7, just an exception that `print_exception` expects an `Exception`. Someone commented below the gist with this one-liner: (i for i in []).throw(type('E', (BaseException,), dict(__new__=lambda cls, *args: cls))()) I managed to golf it a bit down to this ;): n="__new__";(i for i in []).throw(type(n,(IOError,),{n:lambda c,*a:c})())

Mine produces segfault with

    $ python3.7 -VV
    Python 3.7.5 (default, Nov  7 2019, 10:50:52) 
    [GCC 8.3.0]
Some more golfing with yours:

    (i for i in[]).throw(type('',(IOError,),{'__new__':lambda a,*b:a}))

Re: Make CPython segfault in 5 lines of code

#58
post #47

Earlier quoted context omitted.

> This would not have happened in a language with a proper type system as the type checker would have rejected the program at compile time. How about in Rust, then? [0] Bugs happen in every language. When memory corruption occurs, you can segfault. [0] https://users.rust-lang.org/t/rust-guarantees-no-segfaults-w...

I said "a language with a proper type system". Rust is not one such language.

You'll need to define "proper type system" then.

At a guess, you want something with dependent types?

Like Idris, or Haskell. You already have a Haskell example. This [0] release of Idris fixed a segfault when concatenating strings.

Maybe you meant a language that is proven from the ground up. Like CakeML. You can find a segfault example here [1].

Maybe you meant a language with an algebraic type system like Ada. You can find a segfault example here [2].

Maybe you meant something like Dotty (Research for the next version of Scala). You can find a segfault example here [3].

In short: You'll need to describe what you believe to be a "proper" type system, and name the languages you think fit that description, or no one can have a conversation with you.

[0] https://www.idris-lang.org/idris-1-1-1-released/

[1] https://github.com/CakeML/cakeml/issues/438

[2] https://stackoverflow.com/questions/56227629/segmentation-fa...

[3] https://github.com/lampepfl/dotty/pull/7466/

Re: Make CPython segfault in 5 lines of code

#59
post #11

Earlier quoted context omitted.

IMO the biggest reason to adopt the WebAssembly format is that a segfault inside the runtime doesn't affect the host process at all. It's a plausible approach to a fully-safe, near-native-speed plugin architecture.

Segfault inside the runtime, What does it means exactly? A segfault is by definition at the OS level. WebAssembly koolaid is strong on HN, let's wait the first exploits that escapes the runtime to assess the "fully-safe" architecture.

I think they're trying to say that an out of bounds memory access within the emulated WebAssembly machine can be caught by the WebAssembly runtime. (I don't know whether this is true; I hardly know anything about WebAssembly.)

The way they said it, though, makes it sound like WebAssembly is implemented with full process sandboxing or something, which is patently false. It works that way in neither Chrome nor Firefox, and there are no other browsers right now.

Re: Make CPython segfault in 5 lines of code

#60
post #15

Earlier quoted context omitted.

The problem isn't the segfault -- it's the earlier unsafe behavior. That is, the untrapped error that eventually caused the segfault. If the language only has trapped errors, which are indicated by seg faults, it's a safe language. Every language has such errors. What does divide by zero do? What does blowing the stack / infinite recursion do in Rust? It seg faults. The seg fault is the safe behavior. If the stack ov…

> What does divide by zero do? Returns a value, of course! (And that said, JavaScript does have some trapped errors, such as (1/0).foo.foo (and yes you need the second .foo…)) IMO, the execution "error" here (in this thread) is accessing memory illegally. Sometimes the runtime traps it, but sometimes it does not, and "sometimes" isn't always, so its effectively untrapped as we cannot depend on the trap. (Especially i…

> I think it is fair to call C "unsafe" given the above definition of safe/unsafe.

I don't think anyone would disagree with this. What they're saying is that a segfault is safe and that's because a segfault is essentially your OS's version of an out-of-bounds error, one of the reasons that C is not safe is because an out-of-bounds access will not necessarily cause a segfault.

Post reply on HN