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

Relying on cloud services is a big liability. I'd think twice before feeding data to these LLM cloud products. If you make them a fundamental part of your product / development / workflow, be ready for the eventual moment the pricing and terms change.

Its opposite. Windows and MacOS lacks proper sandboxing. While openbsd has pinsyscalls and linux has seccomp-bpf. Windows and MacOS only have filesystem and worse version of user namespace sandboxes, anything else and you need to write a kernel extension or rely on a hypervisor.

> Unfortunately implementing an Apple style architecture on Linux would be very difficult.

The apple apps kind of thing already exists and its called flatpak.


Windows has virtualisation based sandboxing and NT has object-level security (albeit not often used correctly and granularly) and macOS has (among other things) SIP and a subsystem called sandbox that does exactly what it says: it sandboxes. It can sandbox in comparable namespace terms (like cgroups v1 or v2, but more in translocation style execution since it's a MAC framework) yet it also does it a much more fine-grained level depending on what you need. It is used by launchd and applications by default, some entitlements require it so if you want to do some broad kind of elevated application, you also have to have a specific sandbox profile. It's also been around for 16 years, and comes with a ton of examples if you wanted to use it yourself to constrain some process. Yes, it can do filesystem (would be pointless without it), but also does ipc, io, network, memory, fcntl, sysctl, mach ports, sys calls, processes, ui, sockets, messaging, events and all of that including context-aware filtering and compound matching for all of them. And if that's not enough there is also ESF and NEF, the latter only working on networking. You can compare those two to eBFP LSM and XDP. If you want all of this on linux, you'll need to add a lot of custom eBPF and LSM as well as always run in a hypervisor for guaranteed IOMMU usage, but you can't use bare KVM for that either, so you'll either need to never touch the privileged kernel (not even give it a console) or you need to run Xen and use XSM.

Flatpak is just a cheap container copy. Can't do anything beyond what cgroups and things like apparmor and selinux can do, and uses a runtime to do soft higher-level policy functions that translate down to the same primitives. If anything, it's a great bundler, but doesn't do anything new policy-wise.

So, can you get the macOS-level capabilities (both low-level and higher abstractions)? On Linux, yes, but they don't exist yet. On Windows: technically possible, but since that would break most GUI workflow it's not likely that anyone is going to bother, and you're going to have a hard time recompiling windows yourself to make that happen.


Hello, can you tell me if I can filter syscalls made from a memory address in macos without virtualizing the process, or requiring special entitlements and root? I currently have a project where sandboxing is important and i need to prevent all syscalls from a region. This is very simple in linux, and on openbsd i dont have to do anything because openbsd by default does not allow untrusted callsites from making syscalls (and the region in this case is not loaded by openbsd's dynamic loader).

On macos i currently virtualize the process itself, but this has virtualization overhead and some emulation overhead because macos does not let you map all the host process pages to a guest.


I don't think so, the XNU and macOS LS architecture doesn't assume you're going to do policies based on the internal memory topology of a process. It's usually done with multiple processes and having one be very constrained doing only some very specific calls and the other not being able to do any calls at all.

You can probably get by with mprotect or mach internals, but if you're developing at that level you've probably already either implemented or dismissed that.

It's a bit of a different architecture with PAC/MIE/APRR (and to a degree AMFI) being used to prevent abuse that would require syscall filtering in the first place. While I personally don't think that's airtight, it does appear to work out well for their ecosystem.

Edit: come to think of it, region-based call filtering is never really going to be enough on its own, if you don't combine it with other techniques it's basically a rop gadget fest. Probably also why SBX went for intent rather than trying to do it based on location/origin.


Windows has a brokered sandbox architecture too these days, but it's very new and nobody uses it.

This isn't the case at all. Please learn about Apple's security architecture before making sweeping claims like this, it is very deep and has nothing to do with user namespace sandboxes. Windows also has a sandboxing architecture, it's just not as good as Apple's.

FlatPak's security architecture is an attempt to sort of head in the same direction, but they are a decade+ behind and will probably never get there.


macOS absolutely has sandboxing, what are you talking about? But the reality is that you need custom sandboxing tools less when you don't have basic problems like "anything that runs ever can read my ~/.ssh directory without problem" or "you can hijack my password by interposing sudo and thus do anything". This does not matter because macOS will see a program signed by Corp XYZ is trying to read data not owned by that cryptographic signature, and it can't escape the code signature check, and it will flag it. A program cannot simply read your password from stdin and elevate privileges silently, because granting new privileges requires communicating with a higher privilege program so it can delegate to you, and that program has a non spoofable prompt. And so on.

You can use Linux's sandboxing functionality to make a pretty hardened server. If you take in mind the physical deployment and go the extra mile, it can be very secure. The Linux desktop is not and will never be secure in its current form from things like extremely basic local malware. You would have to redesign much of the desktop stack from the init system downward so you could easily do things signature-based identity, proper per-identity secure storage and key management, securitizing elevation of privileges, getting rid of setuid, etc.


They purposefully used a weasel word - "proper" - to shift the argument to being about their opinion on what a proper sandboxing system is.

I chuckled, but isnt godzilla product of the nuclear aftermatch?


Yes, and on multiple levels of meaning too.

I think it could go either way depending on how genre-savvy the character is, in the story-document being emitted by the LLM.

For example, perhaps the Kaiju-flavored narrative demands that Military Bigwig dismisses Concerned Scientists' desperate pleas, and empowers the monster by attacking it with a nuclear weapon. Not because it's a strategically (in)correct choice, but because it "fits" with a story trying to make its subtext clear.


True. In the West, nuclear radiation creates super heroes, while in Japan, it produces devastating kaiju.

I wonder what accounts for the difference?


The way simd speeds up "compute" is indeed mainly the reason that you operate on multiple pieces of data at once.


Yeah, and in the blog post he mentions that he had to transform the data to SoA. If he had done that alone, he might already have seen a speedup from better cache utilization.

Also, I see no mention of alignment in the post. I understand x86/AVX2 likes your load/stores to be aligned, even if it technically allows unaligned access.


Unaligned loads/stores aren't super bad; if still within a cacheline, there's zero penalty, and on crossing cachelines it's alike two ops (except page crossing, which is more bad).

So, for 32B loads/stores and 64B cachelines, it's 1.5x more L1 cache ops (as half of the ops will cross a cacheline); perhaps bad if you're L1-cache-throughput-bound, but less so if you're at L2+ as the extra work sits in L1.


If so they should just name it that


They should name it Multiple memory data, one single CPU instruction, or mmdosci for short. Easy to remember.


Its possible and boy do i have a youtube channel for you https://youtu.be/ndG-6-vONNc https://youtu.be/8dfgum9XlJc


Good modelling


Apple does not allow running code from internet either (even if interpreted iirc)

That said shipping JIT / interpreter with your program to recompile updates / parts of it sounds silly to me.


>That said shipping JIT / interpreter with your program to recompile updates / parts of it sounds silly to me.

why is it silly? modern phones can easily do this (they are running local llm, what issue is with jit?), if it's done one time per update what's the problem?

what's the problem with jitting couple of hot paths which have been updated and were not part of base app?

>Apple does not allow running code from internet either (even if interpreted iirc)

And how is React native expo/eas updates are working then? Isn't it downloading a bytecode bundle?

Afaik, interpreter is allowed. JIT isn't?


There's 2 different parts of their terms about this. One seems to forbid it. The other basically says that you can do it as long as you aren't shipping some kind of update to the app that changes its nature significantly. Basically the generally accepted viewpoint in the industry is that you can OTA bugfixes and small changes but you if you ship whole features without going through app store review first you are definitely on thin ice.


Try reading zig code. For me its much more readable than the other languages, and does not suffer the fact go doesnt have language level errors. Local allocators are very useful and if you dont think so, perhaps you havent dwelved too deeply into systems programming or the language isnt targeted for you.


The dot syntax used everywhere really confuses me. I get its use in struct fields, or for defining anonymous structs, but what is this one for? (Some kind of module-level enum space, where .sampler and .unknown are defined previously?)

  const Sampler = @SpirvType(.sampler);
                             ^

  const Image = @SpirvType(.{ .image = .{
    .usage = .{ .sampled = u32 },
    .format = .unknown,
              ^
  } });
Everything else about zig is quite readable, but this gets me every time. Maybe I'm being dumb though.


"Dot" in zig is a placeholder for types that can be unambigously inferred from the surrounding expression.

So ".unknown" is a standin for "SomeEnum.unknown" or "SomeStruct.unknown", depending on what .format is.


Yeah, after looking it up, it looks like it is basically only used as either field access or an 'infer operator', is that right?

I thought it was used in four completely separate ways:

· normal struct field access

· anonymous struct definition

· field definition within structs (for reasons to do with the parser)

· an extra 'infer operator' for syntactic sugar

But there's no support for anonymous structs/fields, and all structs and fields require a type somewhere for it to be inferred. Which is why this is invalid zig:

  const test = .{ .x = 0, .y = 1 };
(It would need the type to be specified in the called function definition, or inline when assigning)

Correct me if I'm wrong here! (And thank you)


I don't think that "infer operator" is a special case of field access, to me it feels like regular known-type elision similar to how C# and C++ use the var keyword if the data type can be inferred from the rhs expression:

    const Enum = enum {one, two, five};
    const t: Enum = .one;  // Enum.one, but the type was inferred from lhs
    std.debug.print("{t}\n", .{t});

Defining an anonymous struct is valid in zig; your example is only invalid because "test" is a reserved keyword. But you are correct that it reifies into a concrete type, and after initialization it doesn't coerce into other types because zig doesn't do structural typing:

    const anonymous = .{ .x = 0, .y = 1 };
    std.debug.print("{}\n", .{@TypeOf(anonymous)}); // will output something like test_0__struct_45138

    const Point = struct { x: i32, y: i32 };
    const p1 = Point{ .x = 0, .y = 1 };  // valid, explicit struct literal
    const p2: Point = .{ .x = 0, .y = 1 };  // valid, anonymous struct will coerce to Point
    //const pt: Point = anonymous; // error: expected type 'test_0.Point', found 'test_0__struct_45138'

And then there's fieldless anonymous structs aka tuples. I'm including them because they were used in the print statements above:

    const tuple = .{ 0, "1", true };
    std.debug.print("{}\n", .{@TypeOf(tuple)});
    // struct { comptime comptime_int = 0, comptime *const [1:0]u8 = "1", comptime bool = true }


Thanks for the detailed answer :)

All this does for me is raise the question of why they chose to use the `.` for so many different uses. I'd be fine if it was just to infer the type, but it seems very overloaded.


I get the usefulness of allocators, I just don't see them as useful enough where I'd pick zig over another established systems programming language. Do you have an example?


I think Zig would do better than Go at things like kernels, drivers, game engines, lower level sorts of things. Edited to add the obvious: SPIR-V, for instance.

Of course there’s lots of programming that can afford to pay for GC side effects, if there weren’t we wouldn’t have invented GC, but it’s a little less universal, a little less ‘system’.

For me, I came to Zig after horrible cross-platform experiences led me to try going all the way back to C and I found that I was spending way too much time learning to deal with accidental complexity instead of essential complexity. (Respect to the C masters but I failed to adapt.)


>I think Zig would do better than Go at things like kernels, drivers, game engines, lower level sorts of things. Edited to add the obvious: SPIR-V, for instance.

But people don't write those in Go, they use Rust for it


My specific reply was to laszlojamf saying “it seems like go, but with manual allocation”.

To your point though, if Rust is getting it done, go for it. A lot of people still write those in C though.


Yes they do. Only those with anti-GC bias don't.

Which is why TamaGo, TinyGo and gVisor exist.


a lot of heavy duty systems have multiple allocator systems. the erlang virtual machine has 12:

https://www.erlang.org/docs/25/man/erts_alloc.html

jvm has at least 5:

https://github.com/openjdk/jdk/blob/master/src/hotspot/share...

postgres has at least 8:

https://github.com/postgres/postgres/blob/master/src/backend...

since zig anoints an allocator interface in its stdlib, your (and the stdlib's) data structures which use allocators can be trivially reused across different allocation strategies without rewriting code; and very likely (not guaranteed ofc) if you bring in someone else's code they will cleave to convention.


Just yesterday I was thinking about the BEAM and would it be tidier if it were written in Zig.


JVM has surely more than 5, because the ecosystem enjoys multiple implementations.


> Secure boot prevents tampering of your kernel and/or bootloader, nothing about Linux prevents this from being possible.

By trusting another chain of trust and firmware binary blobs involved in booting your PC.

Secure boot exists only as one of the puzzle pieces for remote attestation for MS and trusted OEMs, nothing to do with your security.


If you want yourself to be the root of trust, you CAN generate and use your own keys for secure boot.


>By trusting another chain of trust and firmware binary blobs involved in booting your PC.

So what? I'm still preventing a random person from tampering with my bootloader?


Quite depends, I had times when my posix emulation of io_uring (with poll, not epoll) was faster than io_uring. For large zero-copy buffers, io_uring is king however. Also io_uring is useful even for non asynchronous IO as it can implement chain of operations as single atomic operation (mkdir + open it for example).

For something like networking, if you are maximizing packets per second, you'll hit kernel limits[1] very quickly and instead have to start leveraging features like GSO/GRO or completely bypass the network stack.

1: https://github.com/axboe/liburing/discussions/1346


Also it’s nice for things like SPI which have no user space non-blocking API.


SPI the bus?


Symbian was really awful OS. Nokia's mistake was ignoring Maemo.


I liked Symbian a lot, but I agree that Maemo was superior! Two after what I told above, in 2010, a few friends of mine had N900 and they seemed great. I was still in my study at the time and I interviewed for a summer internship at Nokia to work on Maemo and it was going great, but at some point during the recruitment process, that part of Nokia was sold (to Intel I think? the MeeGo project was announced a bit later) so they stopped all hiring even of interns and I had to find another internship.


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

Search: