Live data from Hacker News

Memory safe ‘curl’ for a more secure internet

daniel.haxx.se

111–120 of 210 posts

Re: Memory safe ‘curl’ for a more secure internet

#111
post #73
post #49

Earlier quoted context omitted.

This is true today, will it remain true?

You could argue the same thing for many big monolithic C projects though. How many of the original authors/maintainers are left in OpenSSL or the Linux kernel? My main worry about Rust dependencies is not so much the number, it's that it's still a fairly young ecosystem that hasn't stabilized yet, packages come and go fairly quickly even for relatively basic features. For instance for a long time lazy_static (which i…

I switched ripgrep to clap 4 years ago. And that was well after clap had already become the popular "go to" solution.

Some parts of the ecosystem are more stable than others. That's true. And it takes work to know which things are stable and which aren't.

And yet, some things just take a longer time to improve. lazy_static has been stable and unchanged for a very long time and it works just fine. You don't need to switch to once_cell if you don't want to. lazy_static isn't going anywhere. The real change here, I think, is that we're hoping to get a portion of once_cell into std so that you don't need a dependency at all for it.

The async ecosystem is definitely moving more quickly because it just hasn't had that much time to stabilize. If you're using async in Rust right now then you're probably an early adopter and you'll want to make sure you're okay with the costs that come with that.

Re: Memory safe ‘curl’ for a more secure internet

#112
post #76

Earlier quoted context omitted.

I'm still annoyed that the Rust people screwed up error handling so badly. The designers should have gone with classical exceptions like other languages, but instead went for a fashionable-at-the-time combination of error codes and added exceptions (spelled "panics"), cribbed for some reason from Go. And on top of that, the Rust designers copied one of the most annoying parts of the C++ ecosystem: a compiler switch f…

Most applications are not supposed to survive a panic!(), to the point where I personally tend to use "panic = 'abort'" for any code where performance matters. As such it's not really a mental overhead, and definitely not the Rust way of doing error handling (in the same way than using "assert" and a signal handler is not the way you're supposed to do error handling in C++). The Rust way of dealing with errors is to…

How does Rust handle errors coming out of library operations? Is the main application able to override the panic handling behavior of a library?

Re: Memory safe ‘curl’ for a more secure internet

#113
post #76

Earlier quoted context omitted.

Most applications are not supposed to survive a panic!(), to the point where I personally tend to use "panic = 'abort'" for any code where performance matters. As such it's not really a mental overhead, and definitely not the Rust way of doing error handling (in the same way than using "assert" and a signal handler is not the way you're supposed to do error handling in C++). The Rust way of dealing with errors is to…

How does Rust handle errors coming out of library operations? Is the main application able to override the panic handling behavior of a library?

Libraries can declare "I require semantic x or semantic y." Applications can as well. If an application says it needs semantic x, and a library says it requires semantic y, you get a compile error.

Most libraries do not depend on a particular semantic, in my experience.

Re: Memory safe ‘curl’ for a more secure internet

#114

Earlier quoted context omitted.

This is an interesting case for error-handling, because a) it can happen virtually anywhere , so handling it with Result would add huge API overhead in terms of ergonomics (given that most code never really has to think about it), yet b) it's very important that it is able to be handled in certain kinds of system contexts, which panics are not designed to facilitate. Most error cases seem to fall neatly into one camp…

> This is an interesting case for error-handling, because I think this is a very good articulation of this space, thank you. > It feels like a workaround. I agree, but the needed work to improve this has taken a very, very, very long time, and so I think workarounds are ultimately helpful. We'll get there...

I think it can honestly be traced down to just how wide a stretch of usecases Rust itself has managed to span. For systems, this arguably is "something you always want to explicitly handle", whereas for applications it's almost always "something where you just want to abort". The level of abstraction is very different, but a single language is spanning both. Or, more precisely, a single standard library.

Just spitballing: maybe one solution could be an alternate set of standard primitives, specifically for low-level work, that do return a Result for everything that might trigger OOM? Maybe those could be abstracted out of the current standard library, and the existing ("application-level") APIs could wrap them with a panic?

Re: Memory safe ‘curl’ for a more secure internet

#115

I've been holding my breath ever since I saw https://github.com/hyperium/hyper/issues/2265#issuecomment-6... Glad to see it seems to be going well!

(and the pull request under active development here: https://github.com/hyperium/hyper/pull/2278 ) I see that Stenberg (bagder) is receiving funding for the work from the ISRG, but I wonder if McArthur (seanmonstar) is, too? It seems like a sizable amount of work on their part, too.

Considering the discussion in https://github.com/hyperium/hyper/issues/2265, that seems unlikely.

Re: Memory safe ‘curl’ for a more secure internet

#116

I think Ada/SPARK would have been a much better choice, but oh well. Is it a licensing issue?

Certainly, SPARK's GPLv3 license is incompatible with Curl's license. Curl's license is MIT-ish, but adds a prohibition for those who use it from using the author's name to promote their business. That restriction is not compatible with GPLv3. Since the author of curl took the time to write that restriction, I would imagine it is more important to them than SPARK. Since the copyleft licenses are hostile to restricting free speech, it's safe to assume that all copyleft options would be similarly unacceptable.

Rust is dual APL2/MIT, and Curl's modified MIT is compatible with MIT, so no such issue would exist for Rust.

(Standard disclaimer, I'm not your lawyer, no citations offered, seek legal counsel.)

Re: Memory safe ‘curl’ for a more secure internet

#117
post #94

Earlier quoted context omitted.

> The only thing new about it is that programmers are exposed to more of the costs of it up-front. That's funny, because it's only "new" if your experiences primarily lie in newer languages and communities. There's a lot of criticism of C, but one thing it does is make dependencies pretty explicit. Some say that's good, some say that's bad, I guess it can be both at different times.

I don't believe that's accurate in general. Let's say you open up a new C codebase: What are its dependencies? You'll have to hunt through its README (hopefully it's up to date!), other build instructions, maybe CMake, maybe some custom build system, etc. What version of dependencies does it use? If the code has been vendored, you at least know what code its using - but where do you look for updates to that code? Do…

This. Take even CURL as an example, try to list its dependencies and you'll see how harder it is.

Re: Memory safe ‘curl’ for a more secure internet

#118
post #101
post #32

I like this idea, but I dont know if Hyper is the best package to go with. Hyper occupies part of the Rust ecosystem that I think suffers from package bloat, like much of NPM. For example, currently Hyper requires 52 packages: autocfg, bitflags, bytes, cfg-if, fnv, fuchsia-zircon, fuchsia-zircon-sys, futures-channel, futures-core, futures-sink, futures-task, futures-util, h2, hashbrown, http, http-body, httparse, htt…

I also wonder if Hyper is really the right tool for the job here. When I was looking into HTTP/S crates, I decided against Hyper because it seemed to require bringing in a runtime for HTTPS, and the async nature of hyper did not seem necessary for my totally synchronous CLI tool. For something like CURL it seems like you would just want the leanest, simplest synchronous HTTP implementation possible

The curl easy api perform call is just a blocking wrapper around the curl multi async interface afaik, so I actually think it makes sense.

Re: Memory safe ‘curl’ for a more secure internet

#119

Earlier quoted context omitted.

Thinking about crates this way is a revelation to me. Is there any tooling to make analyzing dependencies as you did easier?

That. And then we become responsible for yet more possible vulns in all those deps. Current number of cURL deps: 14 I wish it relied only on OpenSSL.

You dont have to use OpenSSL. For example Windows already includes Schannel, so you can build cURL with Schannel and avoid OpenSSL:

https://daniel.haxx.se/blog/wp-content/uploads/2020/09/curl-...

Re: Memory safe ‘curl’ for a more secure internet

#120

Earlier quoted context omitted.

I'm still annoyed that the Rust people screwed up error handling so badly. The designers should have gone with classical exceptions like other languages, but instead went for a fashionable-at-the-time combination of error codes and added exceptions (spelled "panics"), cribbed for some reason from Go. And on top of that, the Rust designers copied one of the most annoying parts of the C++ ecosystem: a compiler switch f…

> The overall result is that everyone pays the cognitive cost of exception (spelled "unwind" in Rust) safety Very, very few people have to think about unwind safety, because it really only comes into play when you're writing unsafe code, and relying on the ability for panics to be caught. Many folks aren't writing any unsafe, and many who are are doing it explicitly in a panic=abort environment. And most don't rely o…

> It's one character.

No it isn't. With exceptions:

  fn foo() -> i32 {
    let x = bar();
    x + 1
  }
vs

  fn foo() -> Result {
    let x = bar()?;
    Ok(x + 1)
  }
Post reply on HN