Posts from this year

Questions or comments? Email me.

Sun 15 March 2020

You Did Not EARN IT

In the midst of a global pandemic, there's a bill moving through the Senate that has massive ramifications for private companies and platforms utilizing encryption to secure user data. Smarter people than me have written in depth about it, and I urge you to read their take and contact your representatives to take action against this bill.

Essential Reading

Contact Your Representatives

If you can take action, contact your representatives and ask them to vote against or condemn this bill. The passage of this would cause serious harm to users, ranging from the general web-browsing population to activists and targeted groups (e.g, minorities). I've included a copy of the letter I sent to my representatives earlier this week - feel free to use it as a base when contacting your own. If you're unsure where to look or how to contact your representatives, check out this EFF tool for getting started.

I'm writing today to ask you to consider voting against the EARN IT act currently making its way through the Senate. While the act is targeting the very serious issue of child exploitation, it does so in an overly broad way that threatens the foundations of the internet. The bill effectively proposes the creation of a government-funded commission that would be tasked with establishing U.S. government dictated best practices for private-sector companies and services in regards to detecting Child Sexual Abuse Material, or "CSAM".

Private companies that would be threatened by this already work to aggressively detect, flag, and address harmful content (CSAM), and are actively engaged in working with the government to further this work. Passage of this bill, however, would ensure that the freedoms the internet has held, which allowed it to grow and innovate on an unprecedented scale, would effectively be tied to Attorney General signoff.

The bill (indirectly, but notably) curtails the ability for private companies to design secure products and services. These types of development require strong encryption, both for systems like digital commerce, as well as the safety of users - including children.

Allowing this type of legislation to pass under an adminstration that has seen fit to strip away civil liberties is a frightening prospect that must be rejected.

Wed 01 January 2020

Wobbling in Rust

In 2019, one of my goals was to get back to writing here more regularly. I'm proud to say I was mostly successful in that endeavor: it was certainly an increase from the amount written in 2018, and absolutely a win over 2017 (which saw... no posts). I think personal websites still have value in the modern era, and so I'm going to continue this goal in 2020 and try to write at least a post a month.

To start things off, I figured this'd be an amusing topic - equal parts stupid, dangerous, and potentially useful.

How to never fail in Rust

Let's say that you've got a task you need to run. For whatever reason, a multitude of runtime errors can occur where you need to just keep retrying - for example, an upstream network endpoint is finnicky and drops the connection sometimes, and resuming is not an option. It can panic due to a third party library, too - Rust is still a newer language, even with the insane growth it's seen the past few years, so this isn't too out there concept-wise.

Assuming we have a method like the following:

use std::error::Error;

fn do_something() -> Result<(), Box<dyn Error>> {
    // Code that could potentially Err() or panic

Our goal is simple: how do we just keep retrying this thing, results be damned?

Unwinding a panic

In the standard library, we can find some methods that are useful for this problem. The one we use below is std::panic::catch_unwind, which will catch unwinding panic events. Note that this doesn't cover every type of panic event - as the docs point out, one that aborts the process will bypass this entirely. It returns a Result, where the Ok variant is just the result of a passed in closure, and the Err variant being the cause of the panic.

Hey, listen! This is a Footgun.

The docs do point out that you should not use this as a general try/catch mechanism. They're right.

My use case for this was a panic happening somewhere in ssh2, where I'd occassionally run into a panic due (seemingly) to it linking against C code. In my particular case, it was easier to just keep trying since it was randomly failing, but would work 100% fine the rest of the time.

It's entirely possible this was a bug in an older version of ssh2 and would not happen today. Consider this trick a footgun and only contemplate using it if you're truly in a situation that requires it.

You've been warned!

Corrections as of March 19th, 2020

A few weeks after this was posted, it wound up /r/rust, where /u/najamelan and /u/viaxxdev pointed out some issues with the original code in this post. This has been updated to take their points into account, and major thanks to them for catching it!

Later in the day, type_N_is_N_to_Never also noted that this could be reduced down - so the code block below now uses that approach, as it's cleaner and arguably easier to digest. Nice!

Disclaimers out of the way, we now know how to catch and loop a panic. The code below illustrates a naive way to loop and handle panic events. Notice we mark the passed in closure as requiring RefUnwindSafe.

use std::error::Error;
use std::panic::{catch_unwind, RefUnwindSafe};

/// Given a closure, will attempt to run it and unwind from panics... infinitely
/// retrying until it works.
/// Maybe.
fn wobble<
    F: RefUnwindSafe + Fn() -> Result<(), Box<dyn Error>>
>(process: F) {
    while let Err(err) = catch_unwind(|| process()) {
        eprintln!("{:?}", err);

Usage is relatively straightforward. For example:

fn do_something() -> Result<(), Box<dyn Error>> {
    panic!("Induce a panic here, for testing");

fn main() {
    wobble(|| {

Why's it called Wobbling?

It's an "infinite" move (or glitch, some might say) in Super Smash Bros Melee for the Nintendo Gamecube. I chose the name because the move is divisive, not something most people enjoy seeing in competitive tournaments, and while valid (depending on the ruleset), might not be the best way to play the game. It kind of symbolically fits here: you probably don't want to use this, and it's arguably not a smart way of doing things... but hey, you might make top 8 once in awhile.

Great! Should I use this?

Probably not.

I mean, sure, you can. For a small subset of problems it can be a useful trick. It's probably not what you want to do, though. It almost feels like a lurking unsafe {} without explicitly being so. The code could also be slightly less verbose, for sure, albeit code golf wasn't the point here.

With that said, it definitely worked for me. Lately I've come to value my time more highly than I did in the past, and this let me focus on other things while still logging errors to determine what the actual issue was. I'll call it a win.

Ryan around the Web