Hacker Newsnew | past | comments | ask | show | jobs | submit | thomashabets2's commentslogin

The portability story for Go is awful. I've blogged about this before: https://blog.habets.se/2022/02/Go-programs-are-not-portable....

It's yet another example of Go authors just implementing the least-effort without even a slight thought to what it would mean down the line, creating a huge liability/debt forever in the language.


You expect Go to magically make systemd journaling exist in macOS?

I can't even begin to comprehend the thought process here.


I can't even begin to comprehend how you got from here to there.

I encourage you to elaborate on how you think that's connected, and not make a strawman argument. You may have not done so deliberately, but if you can't begin to comprehend that I would mean what you said, then you could give me the benefit of doubt and maybe entertain the idea that I did not.

Edit: In my blog post I give the example of getpwnam_r. One should not check for if the OS is Solaris in a given version range, but if getpwnam_r is one or the other type.


No language is going to do that for you. And I don't think Go promissed otherwise.

Perhaps it's about managing expectations.


I mean… my whole blog post is about how autotools does that easily, and Go does not.

"Language", no. But Go's build comments are not really part of the language proper.


It doesn't.

For users in the UID range in sysctl `net.ipv4.ping_group_range` the normal ping command uses this non-root way.

Sure, maybe your system still sets suid root on your ping binary, or shows it adding `cap_net_raw` according to `getcap`, but mine does not.


Since basically all the comments are about how both the author and many commenters are confused about what UDP and DGRAM sockets are, I have corrected the author's code to no longer miscommunicate what protocol is being used.

https://github.com/ThomasHabets/rust-ping-example-corrected

There is no UDP used anywhere in this example. ICMP is not UDP.

I'm not saying my fix is pretty (e.g. uses unwrap(), and ugly destination address parsing), but that's not the point.


Seems a bit subjective. I find iptables much easier to work with.

But then again I've not run iptables for years. nftables has many benefits.


Finally Linux has something that approaches pledge/unveil: landlock.

Seccomp was never actually usable: https://blog.habets.se/2022/03/seccomp-unsafe-at-any-speed.h...


> Seccomp was never actually usable

It's barely usable by itself but I don't think it's an inherent problem of seccomp-bpf, rather the lack of libc support. Surely the task of "determine which syscalls are used for feature X" belongs in the software that decides which syscalls to use for feature X.

In fact, Cosmopolitan libc implements pledge on Linux on top of seccomp-bpf: https://justine.lol/pledge/


Well, kinda.

The "what does the equivalent of pledge(stdio) actually mean?" doesn't have to actually be on the kernel side. But it's complicated by the fact that on Linux, syscalls can be made from anywhere. On OpenBSD syscalls are now only allowed from libc code.

So even if one uses Cosmopolitan libc, if you link to some other library that library may also do direct syscalls. And which syscalls is does, and under which circumstances, is generally not part of the ABI promise. So this can still break between semver patch version upgrades.

Like if a library used to just not write debug logs by default, but then changed so that they are written, but to /dev/null, then there's no way to inform application code for that library, much less update it.

If you ONLY link to libc, then what you said will work. But if you link to anything else (including using LD_PRELOAD), then all bets are off. And at the very least you'll also be linking to libseccomp. :-)

If libc were the only library in existence, then I'd agree with your 100%.


> So even if one uses Cosmopolitan libc, if you link to some other library that library may also do direct syscalls. And which syscalls is does, and under which circumstances, is generally not part of the ABI promise. So this can still break between semver patch version upgrades.

Well but isn't that a more general problem with pledge? I can link to libfoo, drop rpath privileges, and it'll work fine until libfoo starts lazily loading /etc/fooconf (etc.)

A nice thing about pledge is that it's modularized well enough so such problems don't occur very often, but I'd argue it's not less common of an issue than "libfoo started doing raw syscalls." The solution is also the same: a) ask libfoo not to do it, or b) isolate libfoo in an auxiliary process, or c) switch to libbar.

> And at the very least you'll also be linking to libseccomp. :-)

libseccomp proponents won't tell you this, but you can in fact use seccomp without libseccomp, as does Cosmopolitan libc. All libseccomp does is abstract away CPU architecture differences, which a libc already has to do by itself anyway.

(In my project, I got annoyed enough by the kernel header dependency that I just replaced libseccomp with a shell script: https://codeberg.org/bptato/chawan/src/commit/cad5664fc0aa10... although this might have gotten me a place reserved in hell.)


> isn't that a more general problem with pledge?

No, for two reasons: 1) pledge() lets you give high level "I just want to do I/O on what I already have", and it doesn't matter if new syscalls "openat2" (should be blocked) or "getrandom" (should be allowed) are created. (see the `newfstatat` example on printf). And 2) OpenBSD limits syscalls to be done from libc, and libc & kernel are released together. Other libs need to go through libc.

Yes, if libfoo starts doing actual behavioral changes like suddenly opening files, then that's inherently indistinguishable from a compromised process. But I don't think that we need to throw out the baby with that bathwater.

And it's not just about libfoo doing raw syscalls. `unveil()` allows blocking off the filesystem. And it'll apply to open, creat, openat, openat2, unlink, io_uring versions of the relevant calls (if OpenBSD had it), etc…

But yes, if libc could ship its best-effort pledge()/unveil(), that also blocks any further syscalls (in case the kernel is newer), that'd be great. But this needs to be part of (g)libc.

Though another problem is that it doesn't help child processes with a statically compiled newer libc, that quite reasonably wants to use the newer syscalls that the kernel has. OpenBSD decided to simply not support statically linked libc, but musl (and Cosmopolitan libc?) have that as an explicit goal.

So yeah, because they mandate syscalls from libc, ironically OpenBSD should have been able to make pledge/unveil a libc feature using a seccomp-like API, or hell, implemented entirely in user space. But Linux, which has that API, kinda can't.

(ok, so I don't know how strictly OpenBSD mandates the exact system libc, so maybe what I just said would open a vulnerability)


> 1) pledge() lets you give high level "I just want to do I/O on what I already have", and it doesn't matter if new syscalls "openat2" (should be blocked) or "getrandom" (should be allowed) are created. (see the `newfstatat` example on printf).

You can do this with seccomp if you're libc. A new syscall is of no consequence for the seccomp filter unless libc starts using it, in which case libc can just add it to the filter. (Of course the filter has to be an allow-list.)

> And 2) OpenBSD limits syscalls to be done from libc, and libc & kernel are released together. Other libs need to go through libc.

That avoids one failure mode, but I think you assign too much importance to it. If your dependency uses a raw syscall (and let's be honest this isn't that common), you'll see your program SIGSYS and add it manually.

If you have so many constantly changing dependencies that you can't tell/test which ones use raw syscalls and when, you have no hope of successfully using pledge either.

> But I don't think that we need to throw out the baby with that bathwater.

We agree here, just not on which baby :)

> And it's not just about libfoo doing raw syscalls. `unveil()` allows blocking off the filesystem.

You're right, seccomp is unsuitable for implementing unveil because it can't inspect contents of pointers. I believe Cosmopolitan uses Landlock for it.

> Though another problem is that it doesn't help child processes with a statically compiled newer libc

If you're trying to pledge a program written by somebody else, expect problems on OBSD too because pledge was not designed for that. (It can work in many cases, but that's kind of incidental.)

If it's your own program, fine, but that means you're compiling your binaries with different libcs and then wat.

> So yeah, because they mandate syscalls from libc, ironically OpenBSD should have been able to make pledge/unveil a libc feature using a seccomp-like API, or hell, implemented entirely in user space. But Linux, which has that API, kinda can't.

My take is "it can, with caveats that don't matter in 99% the cases pledge is useful in." (Entirely in user space no, with seccomp yes.)


Chrome and Firefox use seccomp for sandboxing since more that 15 years: https://lwn.net/Articles/346902/


But only in very small sandboxes, right? Yes, seccomp could potentially be used for your JIT/interpreter sandbox. And because it inherently executes untrusted input, that's definitely the most important place.

But compare how many applications execute untrusted remote programs to how many programs that have had security vulnerabilities. Or indeed, how much code.

What percentage of code runs in chrome/firefox's sandbox? 0.0001%?

Have you tried to create a seccomp ruleset for a real program? I have. There are too many variations between machines and code paths that you'll necessarily need to leave wide open doors through your policy. Sure, the more you disable the "luck" you manufacture in case of a bug, preventing exploitation. But no, it's not fit for purpose outside these extremely niche use cases.


Seccomp is heavily used on Android.


Linux is far too bloated to ve run as a secure system and the attack surface of any linux distro, due to the number of kernel modules loaded by default, is very big.


And yet, countless companies do just fine.


Be prepared to be called a newbie for criticising typed nils.

My post https://news.ycombinator.com/item?id=44982491 got a lot of hate from people who defend Go by saying "so just don't do that!", and people trying to explain my own blog post to me.


There are a billion copies of simple apps. As you say, this is not new.

We already had a cambrian explosion of flashlight apps and GPS apps. What is the article talking about?


I wouldn't say it "took off", but at least two people use the spreadsheet I built.

I made a video rebuilding it from scratch, for those who like to nerd out about these things: https://youtu.be/H5Xqwlwew98

The sheet has been filled out and evolved for my use since 2011.


Not necessarily, no. I've dabbled in VHDL, but not remotely close to being proficient. Is it useful for that kind of thing? I don't recognize the term.

Maybe this project unlocks be getting into it? But as is, I have no idea if this makes it easier, or is even related.

I thought it was a software defined radio thing.


When the ads showed up I immediately put disqus loading behind a "load comments despite ads" button, and instead just had a static export of the comments loaded by default.

But that's a temporary solution.

Sure, I can code an in house comment system within an hour, but the real work is to combat spam. Because people (and now also disqus) suck.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: