HNHacker News
TopNewBestAskShowJobs

arielb1

213 karma · joined January 4, 2015

submissionscomments
arielb1··on Israel passes law denying naturalization to Palestinian spouses
The people of the West Bank have engaged in terrorism against Israeli civilians up to 2005 - https://en.wikipedia.org/wiki/Second_Intifada - and that's not particularly ancient history.
arielb1··on Async Rust: Panics vs. Cancellation
Maybe that's the subject for the next blog post, but I think the main reason cancellation causes more troubles than ordinary IO problems, is that with ordinary errors you assume that the resource that suffered the errors is down and don't care about its precise state, while with cancellation the resource is perfectly OK and you want to continue using it.
arielb1··on Async Rust: Panics vs. Cancellation
Its more that in Rust, async cancellation will occur exactly at await points, which are generally when you do IO.
arielb1··on The Big DevOps Misunderstanding
The one system I've seen work is when each medium team (of say, 20-36 people) has a "devops team" of say 4-6 people that is responsible for all the infrastructure stuff, while the rest of the people can focus on product work. It's just that keeping track of infrastructure is much more efficient as a full-time job rather than a 10%-time job.

It's important to do the org engineering right so that the infrastructure people and developers feel responsible for each-other and work well together - ideally both teams should be able to open PRs against each other's code if needed and get help any time.

If the org engineering isn't done right, devs write code that pages the ops and the ops don't respond to devs quickly enough for things to work well ("traditional ops").

arielb1··on How to do things safely in Bash (2018)
The main difficulty I have with this method is that I don't have an easy way to pass a Python array to bash as an array of parameters.
arielb1··on How to do things safely in Bash (2018)
When calling shell from bash (to use pipes etc.), I found it useful to pass variables via the environment, like this:

    def safe_call(command, **keywds):
        return subprocess.check_call(f'set -euo pipefail; {command}', shell=True, env=keywds)

    safe_call('command1 -- "$bar" | command2 --baz="$baz" | command3 > "$output_file"', bar=bar, baz=baz, output_file=output_file)
arielb1··on Safe-Linking – Eliminating a 20 year-old malloc() exploit primitive
Not that surprising: CPUs can perform scalar in parallel with computation, so I would expect a few scalar ops to be free in any code that is not scalar-bound.
arielb1··on Inferring and hijacking VPN-tunneled TCP connections
> The described attack utilized a malicious router.

I understand how cross-interface packets can be used maliciously. I'm just trying to figure out the non-malicious use cases for them.

arielb1··on Inferring and hijacking VPN-tunneled TCP connections
What's the configuration you're talking about? In the Wifi+Ethernet case, how do the routers know to send the packets towards the "right" interface, without the computer having the "right" IP address?

I mean, suppose the computer has WiFi IP address 10.0.0.3 & Ethernet IP address 10.0.0.5, then after NAT the return packets will go to 10.0.0.3, and therefore should go to the WiFi interface, not to the Ethernet interface (or, if they don't, how do they know which interface they should go to?).

arielb1··on Inferring and hijacking VPN-tunneled TCP connections
Is there a place where I can read about these cases?
arielb1··on Inferring and hijacking VPN-tunneled TCP connections
How is this supposed to work? How will the packet destined to the WiFi IP address get to the Ethernet interface?
arielb1··on Inferring and hijacking VPN-tunneled TCP connections
> nping --tcp --flags SA --source-ip 192.168.12.1 --dest-ip 10.8.0.8 -- rate 3 -c 3 -e ap0 --dest-mac 08:00:27:9c:53:12

Why is Linux accepting packets coming from one interface into an IP address belonging to a different interface? It feels like it is "forwarding" the packets internally, but `ip_forward` is turned off.

Is there any case where this behavior is legitimately useful?

arielb1··on Chrome OS exploit: WebAsm, Site Isolation, crosh, crash reporter, cryptohomed
From the outside, it feels that most exploit chains on modern systems rely on 4 mostly-independent steps: 1. code execution in a worker process - typically a memory corruption 2. ACE in worker process to ACE in unsandboxed process 3. code execution in unsandboxed process to local root 4. local root to persistence

Finding (1) (3) and (4) is old-school exploit development - a combination of looking at fuzzers, looking at code, looking at bug reports, and memory exploit development (which is a black art I'm not familiar with). So persistence and luck. Be lucky 3 times and you have 3 steps. If you were an organization I suppose you could have 3 separate groups or buy from 3 separate blackhats.

I'm less familiar with the "worker process to user process" part, which tends to rely on combining a few vulnerabilities (in this exploit, 2 + 1 broken hardening), but it's probably similar.

arielb1··on Fearless Concurrency in Firefox Quantum
For example, accidentally sharing a lock-less cache or a non-atomic reference counted pointer between threads.

For example this code, which tries to send a reference-counted pointer between threads, which can cause the reference counter to become unsynchronized and random use-after-free:

    use std::thread;
    use std::rc::Rc;

    fn main() {
        let rcs = Rc::new("Hello, World!".to_string());
    
        let thread_rcs = rcs.clone();
        thread::spawn(move || {
            println!("{}", thread_rcs);
        });
    }
Is detected by the compiler and causes this error

    error[E0277]: the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied in `[closure@src/main.rs:8:19: 10:6 thread_rcs:std::rc::Rc<std::string::String>]`
     --> src/main.rs:8:5
      |
    8 |     thread::spawn(move || {
      |     ^^^^^^^^^^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
      |
      = help: within `[closure@src/main.rs:8:19: 10:6 thread_rcs:std::rc::Rc<std::string::String>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
      = note: required because it appears within the type `[closure@src/main.rs:8:19: 10:6 thread_rcs:std::rc::Rc<std::string::String>]`
      = note: required by `std::thread::spawn`
arielb1··on SpaceX rocket engine explodes during test at Texas facility
Engine failed during qualification testing, not acceptance testing - so it's a new design.

If you don't occasionally blow an engine up on the stand you are either not testing hard enough or not pushing the limits hard enough.

arielb1··on Top medical experts say we should decriminalize all drugs (2016)
But these are "customer protection" laws, which are intended to make sure people are informed and to make it reasonable to shop in the street, not to protect against people who intentionally try to break them.

They are easily opted out of - they won't prevent you from e.g. buying whatever you want from China, and that's by design. There's no point in protecting a customer that doesn't want your protection.

As opposed to drug laws, which are designed to make drugs hard and dangerous to buy, even if you really want them.

arielb1··on Wall Street Profits by Putting Investors in the Slow Lane
The main criticism of HFT I have heard is that it makes life harder for institutional investors, which makes them less likely to take effort to invest well.
arielb1··on How Rust is tested
In Rust the "verified product" is the chain of bors merges - we even save build artifacts for each node in the chain for easy bisection of issues. A rollup creates a single bors merge for all the commits in them, so it's only 1 link in the chain.
arielb1··on Common Errors in Undergraduate Mathematics (2009)
This is how you do high-school algebra, after all. As long as it is clear that all steps are reversible, it is ok.
arielb1··on Differences between Tmux vs Screen (2015)
> PTYs are "terminal servers"—they're just sucky ones from a time when a terminal had fewer expected capabilities. But, indeed, you can connect a TTY directly to e.g. a serial modem, and then the person dialling your modem will get a TTY and login(8) will accept(2) on that descriptor and serve them a login prompt.

In a way, but ptys both don't do the "UI state" thing well, and don't do the "server" thing well - you can't really "take over" the controlling side of a pty easily.

> Now it was more like SSH was the terminal server, and screen/tmux was virtual desktops.

In the normal use of SSH+screen (`ssh -t foobaz screen -r`), SSH just tunnels the VT100-over-serial over the network, and provides the needed authentication and routing.

arielb1··on Differences between Tmux vs Screen (2015)
If you don't care about "making it pretty", you can make a cookie-cutter 3270-style UI pretty easily.
arielb1··on Differences between Tmux vs Screen (2015)
You need some sort of "terminal server" to maintain the session and station state, and I think screen's server does that thing quite well - I don't see a good reason to integrate the "terminal server" with the OS. You could split "UI session management" and "process management" somewhat (e.g. have Docker manage the process swarm and pass stdio to screen), but that's even more splitting.

The uglier part is that screen needs to communicate the UI state to a terminal emulator. Theoretically, you could have screen expose an API and have a client-side GUI client directly display a UI, and that is even probably a good idea (I'll like a Qt tmux client that can talk to a remote tmux with JSON over SSH), but nobody bothered to implement it yet, and a "VT100 over serial" client can be used without running new software at the "user endpoint".

arielb1··on The world’s biggest problems and why they’re not what first comes to mind
While we are post-scarcity in respect to food production, we are not post-scarcity in food distribution in undeveloped countries. That turns out to be a much harder problem.
arielb1··on Don't use Hadoop when your data isn't that big (2013)
Performance is really not something you can design from scratch. If you are using Hadoop for a 1GB job, it's likely that you have architectural bottlenecks that will prevent you from scaling to multiple-terabyte workloads anyway.

And if you overcomplicate things, you can easily get to a state where there are 2 guys that both half-understood the Hadoop setup, but both left for different startups. Complexity alone does not make things simpler.

Of course, you can provide the non-technical value of providing ~training~ makework and resume lines for 10 code monkeys and their managers, but that is not really value to the company.

arielb1··on Quoting command line arguments the wrong way (2011)
The reason is of course that returning a variably-sized value to an already-existing address space is annoying. IOW that's what standard output (and pipes on /proc/self/fd/N) is for.
arielb1··on Quoting command line arguments the wrong way (2011)
If you use some API other than system(3) - even if you literally use a shell-script - it's:

1) serialize data structure to semi-typed array of strings 2) pass array of strings directly to target program 3) have target program parse the array of strings to flags & parameters

With no shell or C library touching the command line arguments at all.

The only way this could be more direct would be if you used JSON instead of arrays of strings, web-API style.

arielb1··on Why does software development take so long?
> Compiler writers actually have it pretty easy once the language is defined, which is a real honest to god spec.

Compilers are typically developed in-parallel with the spec, exactly because you don't know what you want to spec before you try it out.

Optimizers have it even worse - they do not have much of a spec beyond "make it fast, quickly", so all development is trying to find interesting places in existing code.

arielb1··on Why does software development take so long?
For buildings not collapsing, the main thing that matters is that the structure's strength is larger that the applied forces. Edge cases can be solved by adding more material, or more intelligently by having enough redundancy that you have enough strength even if a small number of components fail.

This, of course, does not apply to software functionality - you can't fix bugs by "more CPU power". However, if you look in the places where you can apply this methodology - like cloud services - you find that they are indeed very reliable.

arielb1··on Why does software development take so long?
Yeah. Software projects that are as complex as a house are typically called "the script that guy wrote a decade ago", and tend to work fairly well, even considering that use-cases for software have changed rapidly in the last few decades.
arielb1··on Gitless: a version control system
`git checkout` is indeed a stupid command, because it has 3 modes:

> git checkout [--detach|-b] <commit-ish>

Set HEAD to a new place and sync the working-directory/index to it.

> git checkout <paths>

Copy paths from the index to the working directory.

> git checkout <tree-ish> <paths>

Copy paths from a given commit to the working directory.

This means that "git checkout HEAD file" is different from "git checkout file".

Similarly, `git reset` has 2 modes:

> git reset <tree-ish> <paths>

Copy paths from a given commits to the index, leaving the cwd unchanged.

> git reset [--soft | --mixed | --hard] <commit>

Set *HEAD to a new place, and optionally sync the working directory/index to it.

This is obviously terrible, but changing the names now might be worse.

Page 1 of 4Next →