github HuskerMinion/techo5 v0.7.16

latest releases: v1.6.37, spot-v1.4.37, dot-v1.0.64...
one month ago

The rest of a day's code review: Wi-Fi, crash safety, and what this project actually ships.

A password with a quote or a backslash in it now joins the network. The configuration writer
escaped those two characters; wpa_supplicant does not read escapes — for a quoted value it copies the
bytes between the first quote and the last one, untouched. So a correct password was written wrong
and the screen said "could not join". The name and key now go in as hex and as the key WPA derives,
which is the form the supplicant reads back exactly. A passphrase typed on the screen is no longer
written to disk at all. The same fault had a second half: joining compared the name it asked for
against the one the supplicant reports, and the supplicant escapes what it prints, so a network with
a quote in its name would associate and still be reported as a failure.

A saved open network no longer breaks a first boot. The boot script took the first network name
in Android's saved networks together with the first key in the file, as though they belonged
together. Save an open network before the home one and a unit gets the name of one with the key of
the other: it cannot associate, spends its boot attempts on a network that never existed, and lands
in rescue. The store is read a record at a time now, and on a Show every network it holds is written
out, so the supplicant joins whichever it can hear.

This was tested on real hardware: the fault reproduced on a unit under its own busybox awk, the new
format associated against a real access point in 11 seconds, and the device's own key derivation
agrees with the two published 802.11i vectors the code is tested against.

A stream from the network can no longer take the daemon down. The FLAC decoder trusted a stream's
own header about how many channels its frames hold. A peer that says two and sends one killed the
daemon — and multi-room audio accepts a connection from anything on the network with no key. Fixed,
and the parser now runs supervised instead of in a bare goroutine.

Nor can a model file. Nothing checked that a tensor index pointed at a tensor that exists, so a
malformed model panicked rather than being refused.

The loading screen says what it is waiting for. It stays up until Home Assistant subscribes,
which cannot happen until you accept the device there — so between flashing and adopting it looked
like a unit that had hung. After twelve seconds it now names what it is waiting for and where to go.
Thanks to the person who sat in front of one for ten minutes and then took the trouble to say so.

Fixed

  • A service whose restart failed was run anyway.
  • Four fields written on one thread and read on another, now published properly; and setting the time
    zone no longer rewrites a value the standard library reads from everywhere without a lock.
  • An update is refused if it ranks below what the device is running, so an older signed release
    cannot be replayed at a device. A deliberate downgrade now needs a newer version carrying the older
    code.
  • The update download is bounded by the size the release declares, and the free-space check runs
    before the download and against the filesystem it is actually written to.
  • Pictures are measured before they are decoded, so an 8 MB photo that unpacks to a gigabyte is
    refused rather than taking the device with it.
  • Radio metadata and announcement audio are bounded.
  • The workflow that builds and attests every release is pinned to exact commits.

Documentation and licensing
The wake word models shipped in these images are now credited: microWakeWord and esphome's models
(Apache-2.0), openWakeWord's front end — whose embedding model is Google's — and the community
collection, whose per-model authorship is not recorded upstream, which is now said rather than
glossed. Every kernel published with a release is GPL-2.0, and two of the three NOTICE files did not
say so; each now names the source tree, commit, configuration and patches, so anyone handed a binary
can rebuild it. The Dot's said kernels were not distributed while every release has shipped one.

Verify this release was built by CI from its own tag:

gh attestation verify echod-arm --repo HuskerMinion/techo5 --source-ref refs/tags/v0.7.16

Don't miss a new techo5 release

NewReleases is sending notifications on new releases.