Merged
Conversation
Contributor
|
Successfully generated as following: http://localhost:1200/cmpxchg8b/articles - Success ✔️<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
>
<channel>
<title><![CDATA[cmpxchg8b]]></title>
<link>https://lock.cmpxchg8b.com/#articles</link>
<atom:link href="http://localhost:1200/cmpxchg8b/articles" rel="self" type="application/rss+xml" />
<description><![CDATA[cmpxchg8b - Made with love by RSSHub(https://github.com/DIYgod/RSSHub)]]></description>
<generator>RSSHub</generator>
<webMaster>[email protected] (DIYgod)</webMaster>
<language>zh-cn</language>
<lastBuildDate>Wed, 15 Nov 2023 13:21:22 GMT</lastBuildDate>
<ttl>5</ttl>
<item>
<title><![CDATA[What happens when a CPU goes wrong?]]></title>
<description><![CDATA[We have a CPU mystery! We found a way to cause some processors to enter a glitch state where the normal rules don’t apply, but what does that mean…?]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/reptar.html</guid>
<link>https://lock.cmpxchg8b.com/reptar.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[An overview of hacking the Timex m851.]]></title>
<description><![CDATA[<small> <em>This post is part of a series on my quest to find the perfect watch.</em> </small>]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/timex.html</guid>
<link>https://lock.cmpxchg8b.com/timex.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I found an interesting CPU bug.]]></title>
<description><![CDATA[If you remove the first word from the string <code>"hello world"</code>, what should the result be? This is the story of how we discovered that the answer could be your root password!]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/zenbleed.html</guid>
<link>https://lock.cmpxchg8b.com/zenbleed.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[George Lucas once sued someone over a spreadsheet.]]></title>
<description><![CDATA[<h1>Introduction</h1>
<p>In the late 1980s there was - believe it or not - a popular monthly magazine dedicated to spreadsheets. It had a respectable eight year run, along with two companion books.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/lotus-magazine.png" alt="Lotus Magazines" referrerpolicy="no-referrer"><figcaption>Lotus Magazines</figcaption>
</figure>
<p>The entire <a href="https://archive.org/details/pub_lotus">back catalog</a> is on archive.org, although most issues were scanned from microfiche so there’s no color.</p>
<p>I’m interested in Lotus 1-2-3 history, so I’ve been slowly reading through back issues. It’s actually great, there are some really approachable articles on linear regression, forecasting, calculating bond yields, etc… mixed in with some retro computing news!</p>
<p>There’s also advice, tips, reviews, reader questions, and so on.</p>
<blockquote>
<h3 id="why-1-2-3">Why 1-2-3?</h3>
<p><small> I’m sometimes asked what it is I find appealing about Lotus 1-2-3. It’s from an era where there was an expectation that “powerful” software would be designed around keystroke macros. I think I just really appreciate that.</small></p><small>
<p>The moment that Vim first “clicked” for me is when I wrote my first macro. I suddenly understood why there is this huge selection of commands, and why that is so powerful.</p>
</small><p><small>In vim you can record a keystroke macro to a register called <code>x</code> with <code>qx</code>, then run it with <code>@x</code>. In 1-2-3 you can write a keystroke macro to a range called <code>\x</code>, and run it with <kbd>Alt</kbd>-<kbd>x</kbd>. Not so different! </small></p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/doom.html</guid>
<link>https://lock.cmpxchg8b.com/doom.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I’m looking for a new wrist watch.]]></title>
<description><![CDATA[<h1>Intro</h1>
<figure>
<img src="https://lock.cmpxchg8b.com/img/prw-3100t.jpg" alt="Casio PRW-3100T" referrerpolicy="no-referrer"><figcaption>Casio PRW-3100T</figcaption>
</figure>
<p>I love my Casio Protrek watch, I won’t leave the house without it. I’ve owned it for years, as well as some earlier Protrek models. Those earlier models didn’t break — these watches are basically indestructible — I just liked them so much I went and bought the new revisions!</p>
<p>It has the standard digital watch features (alarms, timers, stopwatch, world time, calendar, backlight, etc), but this watch is really intended for hikers — it has an altimeter, barometer, thermometer and digital compass built in. I’m not outdoorsy — The only hiking I’ll do is to Starbucks — but I still love this watch. I think the reason is it’s reliable — I never worry that it won’t work.</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/prw-modes.png" alt="Watch Modes" referrerpolicy="no-referrer"> <font size="-2"> The standard watch modes displayed in the manual. <br> <font size="-4"> I think I’ve looked at the barometric pressure graph a total of two times over the years. It is pretty cool though, the theory is you can predict an upcoming weather change based on the direction the graph is trending. If the graph is flat, the current weather is likely to hold for a few hours. </font> </font></p>
</blockquote>
<p>Maybe you’re thinking “hah, unless the battery needs to be replaced” — wrong! The watch face is literally a solar panel, it sips so little power (we’re talking μamps) that a few cumulative minutes exposure to daylight is enough to keep the watch running for months.</p>
<p>I would be astonished if I woke up tomorrow and it wasn’t working, and it’s rare I can say that about any other tech I use. If an unattended update hosed my laptop, or an app update breaks my workflow — oh well, that’s par for the course. Sure, a digital watch is simple in comparison, but it’s nice to have something I can trust to do it’s job.</p>
<section id="smartwatch" class="level2">
<h2>Smartwatch</h2>
<p>Still, I am a nerd — and I hear the siren call of smartwatches. I think I would get frustrated quickly with an Android or iOS smartwatch, but is there some middle ground? A simple, reliable, programmable digital watch?</p>
<p>It doesn’t have to be zero-maintenance, I can tolerate annual battery replacements… but daily or weekly recharging and any dependence on online services really seems unbearable to me after years with my Casio.</p>
<p>The main feature I would like is some sort of sync capability. Ideally, I would like the alarms and <a href="https://dianne.skoll.ca/projects/remind/">reminders</a> from my UNIX <code>~/.reminders</code> file to appear on my watch, perhaps over RF or BLE. I don’t mind writing code to make this happen, so some customizability, automation or programmability is essential.</p>
<p>What options are there for someone like me?</p>
</section>
<section id="go-homebrew" class="level2">
<h2>Go Homebrew?</h2>
<p>There are a few homebrew smartwatches that appeal to me.</p>
<section id="sensorwatch" class="level3">
<h3>Sensorwatch</h3>
<p>Jose Castillo has built <a href="https://www.sensorwatch.net/">SensorWatch</a>, a fully programmable replacement board for the Casio F-91W watch.</p>
<p>This almost meets all my needs, it lasts a full year on a single battery and I could write an app to handle my reminders. The only issue is that sending data to the watch would be difficult once it’s assembled, as only the buttons can be used for input.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch.jpg" alt="Sensor Watch" referrerpolicy="no-referrer"><figcaption>Sensor Watch</figcaption>
</figure>
<p>There is an add-on board that adds GPIO pins, the idea is you can add your own additional sensors… if you can make them fit. This might be beyond my hardware skills, but perhaps exposing the pins externally to add some form of i2c might be good enough — at the expense of water resistance.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch-flexboard.jpg" alt="Sensor Watch Addon" referrerpolicy="no-referrer"><figcaption>Sensor Watch Addon</figcaption>
</figure>
<p>I could ask Jose how he would add sync, perhaps he knows of some small sensor like a magnetometer or IR photodiode that I could use to build a low-bandwidth communication channel.</p>
</section>
<section id="goodwatch" class="level3">
<h3>Goodwatch</h3>
<p>Travis Goodspeed (unfortunately for him, people sometimes confuse us because of our similar names!) has a very impressive project called <a href="https://github.com/travisgoodspeed/goodwatch">goodwatch</a> for amateur radio enthusiasts. It’s another board swap using the MSP430, but for a different Casio shell with far more inputs and a more capable segment display. Travis says a battery can last months, perhaps longer depending on usage. That’s a little lower than I would like, but it sounds tolerable.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/pocsag.jpg" alt="Goodwatch" referrerpolicy="no-referrer"><figcaption>Goodwatch</figcaption>
</figure>
<p>I don’t have much amateur radio knowledge, but it seems plausible I could add some low-bandwidth sync capability with a cheap <abbr title="Software Defined
Radio">SDR</abbr> dongle and a weekend hacking MSP340 assembly. I can absolutely imagine using this, although Travis is a notable hardware hacker and I can barely solder! Assembly looks a little more involved than the sensorwatch, so I worry this might be out of my league!</p>
</section>
</section>
<section id="go-hybrid" class="level2">
<h2>Go Hybrid?</h2>
<p><img src="https://lock.cmpxchg8b.com/img/sony-wena-pro.jpg" alt="Sony Wena Pro" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/wena3.jpg" alt="Sony Wena3" referrerpolicy="no-referrer"></p>
<p>There is an interesting Sony product line called Wena, primarily sold in the Japanese market. Wena is not a smartwatch, it’s a “smartband” that replaces the band on your existing watch. This seems moderately interesting, it needs regular recharging but degrades gracefully into a regular watch if the battery dies.</p>
<p>Of course, there is no built-in functionality to use it for what I want, but it seems totally plausible I could add it — decompiling the companion APK if necessary to figure out the API.</p>
<p>It is not cheap, and I would have to import one to the US. Frankly, <a href="https://www.wareable.com/smartwatches/sony-wena-wrist-pro-active-review-6982">online reviews</a> are not favourable at all — but as I would write my own software, I think I could make it work.</p>
<p>There are two interesting models, the Wena Pro and the Wena3. The Wena3 has a heartrate monitor, bigger screen and USB-C, but I think I prefer the simpler Wena Pro design.</p>
</section>
<section id="go-retro" class="level2">
<h2>Go Retro?</h2>
<p>There have been smartwatches around since the 80s, and the specifications I’m interested in are hardly cutting edge! Perhaps the closest device to what I’m looking for is actually from 2003, the Timex m851.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/m851.png" alt="Timex m851" referrerpolicy="no-referrer"><figcaption>Timex m851</figcaption>
</figure>
<p>It’s a programmable digital watch based on the 8-bit SEIKO 88349 CPU, and 2kb of RAM. Here is the <a href="https://assets.timex.com/developer/developer_downloads/WA_Design_Guide.pdf">developer manual</a>, and here is the <a href="https://www.rayslogic.com/Software/TimexUSB/Docs/s1c88%20core%20cpu%20manual.pdf">CPU manual</a>. Essentially, you can write “wrist apps” in S1C88 assembly, and sync it over USB with a cable.</p>
<p>There is apparently also a C compiler and simulator available, although I suspect writing in C might not be an optimal use of the constrained system resources!</p>
<p>The simulator seems capable, here are screenshots from the manual.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/timex-simulator.png" alt="Timex Simulator" referrerpolicy="no-referrer"><figcaption>Timex Simulator</figcaption>
</figure>
</blockquote>
<p>The documentation says the battery needs to be replaced every 2 years, which is totally acceptable.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/timex-battery.png" alt="Timex Battery" referrerpolicy="no-referrer"><figcaption>Timex Battery</figcaption>
</figure>
</blockquote>
<p>There was also a modest enthusiast community at some point, who wrote some interesting apps. Amusingly, this watch uses the same CPU as a popular retro gaming device (the <a href="https://wiki.sublab.net/index.php/Pokemon_Mini">Pokemon mini</a>), so retro game hackers have already documented the toolchain and device quirks, and even built emulators I might be able to repurpose!</p>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/watch.html</guid>
<link>https://lock.cmpxchg8b.com/watch.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[Putting debugging symbols back into stripped binaries.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I’ve written before about how much I enjoy vintage software. Lately I’ve been tinkering with <a href="https://github.com/taviso/wpunix">WordPerfect for UNIX</a>.</p>
<p>It’s working great, combined with <a href="https://github.com/taviso/123elf/">Lotus 1-2-3</a> you can have a full-featured office suite in an xterm! 😂</p>
<blockquote>
<p><a href="https://github.com/taviso/wpunix"><img src="https://lock.cmpxchg8b.com/img/wp-preview.gif" alt="WordPerfect" referrerpolicy="no-referrer"></a></p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/symbols.html</guid>
<link>https://lock.cmpxchg8b.com/symbols.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I solved a mystery in an old UNIX print ad.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I found this interesting <a href="https://archive.org/details/word-perfect-5.1-for-unix-ad-1993/">print-ad</a> for WordPerfect for UNIX, apparently the best UNIX product of 1992! (Very) Belated congratulations Corel!</p>
<blockquote>
<p><a href="https://lock.cmpxchg8b.com/img/wp-unix1.png"><img src="https://lock.cmpxchg8b.com/img/wp-unix1-small.png" alt="WordPerfect Ad Pg1" referrerpolicy="no-referrer"></a></p>
</blockquote>
<p>However, this section intrigued me:</p>
<pre><code>But what if you don’t go for the GUI? Just choose the Character version, and
depending on your hardware, you’ll get great-looking features rarely seen on a
character terminal. Like document preview, column layout, and other important
features such as easy-to-use drop down menus and easy-to-understand help
screens.</code></pre>
<p>I understand <em>“column layout”</em> and <em>“drop down menus”</em>, but what exactly does <em>“document preview”</em> mean?</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/wordperfect.html</guid>
<link>https://lock.cmpxchg8b.com/wordperfect.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I rediscovered some lost UNIX software.]]></title>
<description><![CDATA[<h1>Intro</h1>
<figure>
<img src="https://lock.cmpxchg8b.com/img/lotus-123-logo.png" alt="Lotus 1-2-3 Logo" referrerpolicy="no-referrer"><figcaption>Lotus 1-2-3 Logo</figcaption>
</figure>
<p>It’s an exciting time in the Lotus 1-2-3 enthusiast community – that was a joke, there is no enthusiast community, it’s just me! 😆</p>
<p>It really is an exciting time though – that part isn’t a joke!</p>
<p>There have been some major developments in the last few weeks, and I guess that’s pretty unusual for 30 year old abandonware.</p>
<p>I’ll cut to the chase; through a combination of unlikely discoveries, crazy hacks and the 90s BBS warez scene I’ve been able to port Lotus 1-2-3 natively to Linux – an operating system that literally didn’t exist when 1-2-3 was released!<a href="https://lock.cmpxchg8b.com/linux123.html#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>If you want to hear how a proprietary application could be ported to new operating systems 30 years after release, read on.</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/linux123.html</guid>
<link>https://lock.cmpxchg8b.com/linux123.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I wrote down some thoughts about Password Managers.]]></title>
<description><![CDATA[<h1>Introduction</h1>
<p>I’ve spent a lot of time trying to understand the attack surface of popular password managers. I think I’ve spent more time analyzing them than practically anybody else, and I think that qualifies me to have an opinion!</p>
<p>First, let’s get a few things out of the way. For some reason, few subjects can get heated faster than passwords. Maybe politics and religion, but that’s about it. It’s okay if you don’t like my opinion.</p>
<p>Second, everyone needs to be using unique passwords. You don’t have to use a password manager to do that, whatever system works for you is fine. If you want to use a notebook in a desk drawer, that’s totally acceptable.</p>
<p>Okay, let’s begin.</p>
<blockquote>
<p>If you just want some advice on what to use, skip to the <a href="https://lock.cmpxchg8b.com/passmgrs.html#conclusion">conclusion</a>.</p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/passmgrs.html</guid>
<link>https://lock.cmpxchg8b.com/passmgrs.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I wrote a display driver for an old DOS program.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p><a href="https://lock.cmpxchg8b.com/img/lotus-online-help.png" title="Screenshot of 1-2-3"><img src="https://lock.cmpxchg8b.com/img/lotus-online-help.png" alt="1-2-3 Screenshot" referrerpolicy="no-referrer"></a></p>
<p>I tend to use a lot of retro software, partly because I’m a big nerd but also because I just prefer to work in a terminal. There were a ton of major commercial software products for MS-DOS that were highly polished, and can still be used effectively in an xterm today.</p>
<p>I do like using <a href="https://www.youtube.com/watch?v=5cNJNKkCQ2E">Lotus 1-2-3</a>, I even have a boxed copy of the last DOS version released, version 4!</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/lotus123.html</guid>
<link>https://lock.cmpxchg8b.com/lotus123.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[You can make popup ads in XTerm with Tektronix mode.Linking a binary with two versions of the same library.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>xterm can emulate a <a href="https://en.wikipedia.org/wiki/Tektronix_4010">Tektronix 4010</a> terminal, It’s actually pretty neat, it’s enabled by default and applications can plot simple graphics (lines, curves, etc) or use it to show graphs.</p>
<p>It randomly occurred to me that windows unexpectedly opening is a bit like a popup browser ad.</p>
<p>Well, it turns out that Tektronix emulation in xterm is so fast that you can draw monochrome bitmaps. Nobody ever asked for or wanted this, but here is a <a href="https://lock.cmpxchg8b.com/files/README.xterm.txt">README file</a> that abuses this to create a popup ad when you <code>cat</code> it in an xterm. 😈</p>
<blockquote>
<p><a href="https://lock.cmpxchg8b.com/img/xtermpopup.mp4"><img src="https://lock.cmpxchg8b.com/img/xtermpopup.gif" alt="XTerm Popup Ad" referrerpolicy="no-referrer"></a></p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/tektronix.html</guid>
<link>https://lock.cmpxchg8b.com/tektronix.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I reviewed some spreadsheets that work in the terminal.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I’m not a heavy spreadsheet user, just keeping track of expenses, household inventory, investments, that kind of thing. I mostly just use Google Sheets.</p>
<p>However, I really prefer to stay in a terminal if I can, so decided to review some of the options. My only requirements are that it runs in a terminal and works on Linux, but bonus points if it’s extensible (scripts, macros, plugins, etc).</p>
<p>I’ve tested two F/OSS and two commercial console spreadsheets. Here’s the big caveat, it might surprise you to learn (haha) that there isn’t a huge demand for console productivity software. That means these programs havn’t been actively developed for a very long time, but they were once <strong>incredibly</strong> popular.</p>
<p>Their userbase may now be extinct, but they’re all still mature, stable and functional.</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/spreadsheet.html</guid>
<link>https://lock.cmpxchg8b.com/spreadsheet.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[Read about me trying out some old MS-DOS software, Lotus Agenda.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I never used <a href="https://en.wikipedia.org/wiki/Lotus_Agenda">Lotus Agenda</a>, but I’m told it was a popular productivity tool for MS-DOS in the late 80s. I’ve been on a retro software rediscovery kick lately, so I’ve decided to give it a whirl and write about my experiences. There is something that appeals to me about using long-abandoned software. Perhaps it’s update fatigue, there’s certainly no need to dread a major update breaking something!</p>
<p>Regardless, I’ve always enjoyed finding new productivity tools to try out, and I’m not afraid of steep learning curves or getting my hands dirty. I’ll usually choose powerful and flexible software over simplicity.</p>
<p>At the moment I mostly use <a href="https://taskwarrior.org/">taskwarrior</a>, but I’ve lost count of all the others I’ve tried!</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/lotusagenda.html</guid>
<link>https://lock.cmpxchg8b.com/lotusagenda.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
</channel>
</rss>
|
TonyRL
reviewed
Nov 15, 2023
lib/v2/cmpxchg8b/articles.js
Outdated
Comment on lines
8
to
11
Collaborator
There was a problem hiding this comment.
Contributor
|
Successfully generated as following: http://localhost:1200/cmpxchg8b/articles - Success ✔️<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
>
<channel>
<title><![CDATA[cmpxchg8b]]></title>
<link>https://lock.cmpxchg8b.com/#articles</link>
<atom:link href="http://localhost:1200/cmpxchg8b/articles" rel="self" type="application/rss+xml" />
<description><![CDATA[cmpxchg8b - Made with love by RSSHub(https://github.com/DIYgod/RSSHub)]]></description>
<generator>RSSHub</generator>
<webMaster>[email protected] (DIYgod)</webMaster>
<language>zh-cn</language>
<lastBuildDate>Wed, 15 Nov 2023 14:44:17 GMT</lastBuildDate>
<ttl>5</ttl>
<item>
<title><![CDATA[What happens when a CPU goes wrong?]]></title>
<description><![CDATA[We have a CPU mystery! We found a way to cause some processors to enter a glitch state where the normal rules don’t apply, but what does that mean…?]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/reptar.html</guid>
<link>https://lock.cmpxchg8b.com/reptar.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[An overview of hacking the Timex m851.]]></title>
<description><![CDATA[<small> <em>This post is part of a series on my quest to find the perfect watch.</em> </small>]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/timex.html</guid>
<link>https://lock.cmpxchg8b.com/timex.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I found an interesting CPU bug.]]></title>
<description><![CDATA[If you remove the first word from the string <code>"hello world"</code>, what should the result be? This is the story of how we discovered that the answer could be your root password!]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/zenbleed.html</guid>
<link>https://lock.cmpxchg8b.com/zenbleed.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[George Lucas once sued someone over a spreadsheet.]]></title>
<description><![CDATA[<h1>Introduction</h1>
<p>In the late 1980s there was - believe it or not - a popular monthly magazine dedicated to spreadsheets. It had a respectable eight year run, along with two companion books.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/lotus-magazine.png" alt="Lotus Magazines" referrerpolicy="no-referrer"><figcaption>Lotus Magazines</figcaption>
</figure>
<p>The entire <a href="https://archive.org/details/pub_lotus">back catalog</a> is on archive.org, although most issues were scanned from microfiche so there’s no color.</p>
<p>I’m interested in Lotus 1-2-3 history, so I’ve been slowly reading through back issues. It’s actually great, there are some really approachable articles on linear regression, forecasting, calculating bond yields, etc… mixed in with some retro computing news!</p>
<p>There’s also advice, tips, reviews, reader questions, and so on.</p>
<blockquote>
<h3 id="why-1-2-3">Why 1-2-3?</h3>
<p><small> I’m sometimes asked what it is I find appealing about Lotus 1-2-3. It’s from an era where there was an expectation that “powerful” software would be designed around keystroke macros. I think I just really appreciate that.</small></p><small>
<p>The moment that Vim first “clicked” for me is when I wrote my first macro. I suddenly understood why there is this huge selection of commands, and why that is so powerful.</p>
</small><p><small>In vim you can record a keystroke macro to a register called <code>x</code> with <code>qx</code>, then run it with <code>@x</code>. In 1-2-3 you can write a keystroke macro to a range called <code>\x</code>, and run it with <kbd>Alt</kbd>-<kbd>x</kbd>. Not so different! </small></p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/doom.html</guid>
<link>https://lock.cmpxchg8b.com/doom.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I’m looking for a new wrist watch.]]></title>
<description><![CDATA[<h1>Intro</h1>
<figure>
<img src="https://lock.cmpxchg8b.com/img/prw-3100t.jpg" alt="Casio PRW-3100T" referrerpolicy="no-referrer"><figcaption>Casio PRW-3100T</figcaption>
</figure>
<p>I love my Casio Protrek watch, I won’t leave the house without it. I’ve owned it for years, as well as some earlier Protrek models. Those earlier models didn’t break — these watches are basically indestructible — I just liked them so much I went and bought the new revisions!</p>
<p>It has the standard digital watch features (alarms, timers, stopwatch, world time, calendar, backlight, etc), but this watch is really intended for hikers — it has an altimeter, barometer, thermometer and digital compass built in. I’m not outdoorsy — The only hiking I’ll do is to Starbucks — but I still love this watch. I think the reason is it’s reliable — I never worry that it won’t work.</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/prw-modes.png" alt="Watch Modes" referrerpolicy="no-referrer"> <font size="-2"> The standard watch modes displayed in the manual. <br> <font size="-4"> I think I’ve looked at the barometric pressure graph a total of two times over the years. It is pretty cool though, the theory is you can predict an upcoming weather change based on the direction the graph is trending. If the graph is flat, the current weather is likely to hold for a few hours. </font> </font></p>
</blockquote>
<p>Maybe you’re thinking “hah, unless the battery needs to be replaced” — wrong! The watch face is literally a solar panel, it sips so little power (we’re talking μamps) that a few cumulative minutes exposure to daylight is enough to keep the watch running for months.</p>
<p>I would be astonished if I woke up tomorrow and it wasn’t working, and it’s rare I can say that about any other tech I use. If an unattended update hosed my laptop, or an app update breaks my workflow — oh well, that’s par for the course. Sure, a digital watch is simple in comparison, but it’s nice to have something I can trust to do it’s job.</p>
<section id="smartwatch" class="level2">
<h2>Smartwatch</h2>
<p>Still, I am a nerd — and I hear the siren call of smartwatches. I think I would get frustrated quickly with an Android or iOS smartwatch, but is there some middle ground? A simple, reliable, programmable digital watch?</p>
<p>It doesn’t have to be zero-maintenance, I can tolerate annual battery replacements… but daily or weekly recharging and any dependence on online services really seems unbearable to me after years with my Casio.</p>
<p>The main feature I would like is some sort of sync capability. Ideally, I would like the alarms and <a href="https://dianne.skoll.ca/projects/remind/">reminders</a> from my UNIX <code>~/.reminders</code> file to appear on my watch, perhaps over RF or BLE. I don’t mind writing code to make this happen, so some customizability, automation or programmability is essential.</p>
<p>What options are there for someone like me?</p>
</section>
<section id="go-homebrew" class="level2">
<h2>Go Homebrew?</h2>
<p>There are a few homebrew smartwatches that appeal to me.</p>
<section id="sensorwatch" class="level3">
<h3>Sensorwatch</h3>
<p>Jose Castillo has built <a href="https://www.sensorwatch.net/">SensorWatch</a>, a fully programmable replacement board for the Casio F-91W watch.</p>
<p>This almost meets all my needs, it lasts a full year on a single battery and I could write an app to handle my reminders. The only issue is that sending data to the watch would be difficult once it’s assembled, as only the buttons can be used for input.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch.jpg" alt="Sensor Watch" referrerpolicy="no-referrer"><figcaption>Sensor Watch</figcaption>
</figure>
<p>There is an add-on board that adds GPIO pins, the idea is you can add your own additional sensors… if you can make them fit. This might be beyond my hardware skills, but perhaps exposing the pins externally to add some form of i2c might be good enough — at the expense of water resistance.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch-flexboard.jpg" alt="Sensor Watch Addon" referrerpolicy="no-referrer"><figcaption>Sensor Watch Addon</figcaption>
</figure>
<p>I could ask Jose how he would add sync, perhaps he knows of some small sensor like a magnetometer or IR photodiode that I could use to build a low-bandwidth communication channel.</p>
</section>
<section id="goodwatch" class="level3">
<h3>Goodwatch</h3>
<p>Travis Goodspeed (unfortunately for him, people sometimes confuse us because of our similar names!) has a very impressive project called <a href="https://github.com/travisgoodspeed/goodwatch">goodwatch</a> for amateur radio enthusiasts. It’s another board swap using the MSP430, but for a different Casio shell with far more inputs and a more capable segment display. Travis says a battery can last months, perhaps longer depending on usage. That’s a little lower than I would like, but it sounds tolerable.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/pocsag.jpg" alt="Goodwatch" referrerpolicy="no-referrer"><figcaption>Goodwatch</figcaption>
</figure>
<p>I don’t have much amateur radio knowledge, but it seems plausible I could add some low-bandwidth sync capability with a cheap <abbr title="Software Defined
Radio">SDR</abbr> dongle and a weekend hacking MSP340 assembly. I can absolutely imagine using this, although Travis is a notable hardware hacker and I can barely solder! Assembly looks a little more involved than the sensorwatch, so I worry this might be out of my league!</p>
</section>
</section>
<section id="go-hybrid" class="level2">
<h2>Go Hybrid?</h2>
<p><img src="https://lock.cmpxchg8b.com/img/sony-wena-pro.jpg" alt="Sony Wena Pro" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/wena3.jpg" alt="Sony Wena3" referrerpolicy="no-referrer"></p>
<p>There is an interesting Sony product line called Wena, primarily sold in the Japanese market. Wena is not a smartwatch, it’s a “smartband” that replaces the band on your existing watch. This seems moderately interesting, it needs regular recharging but degrades gracefully into a regular watch if the battery dies.</p>
<p>Of course, there is no built-in functionality to use it for what I want, but it seems totally plausible I could add it — decompiling the companion APK if necessary to figure out the API.</p>
<p>It is not cheap, and I would have to import one to the US. Frankly, <a href="https://www.wareable.com/smartwatches/sony-wena-wrist-pro-active-review-6982">online reviews</a> are not favourable at all — but as I would write my own software, I think I could make it work.</p>
<p>There are two interesting models, the Wena Pro and the Wena3. The Wena3 has a heartrate monitor, bigger screen and USB-C, but I think I prefer the simpler Wena Pro design.</p>
</section>
<section id="go-retro" class="level2">
<h2>Go Retro?</h2>
<p>There have been smartwatches around since the 80s, and the specifications I’m interested in are hardly cutting edge! Perhaps the closest device to what I’m looking for is actually from 2003, the Timex m851.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/m851.png" alt="Timex m851" referrerpolicy="no-referrer"><figcaption>Timex m851</figcaption>
</figure>
<p>It’s a programmable digital watch based on the 8-bit SEIKO 88349 CPU, and 2kb of RAM. Here is the <a href="https://assets.timex.com/developer/developer_downloads/WA_Design_Guide.pdf">developer manual</a>, and here is the <a href="https://www.rayslogic.com/Software/TimexUSB/Docs/s1c88%20core%20cpu%20manual.pdf">CPU manual</a>. Essentially, you can write “wrist apps” in S1C88 assembly, and sync it over USB with a cable.</p>
<p>There is apparently also a C compiler and simulator available, although I suspect writing in C might not be an optimal use of the constrained system resources!</p>
<p>The simulator seems capable, here are screenshots from the manual.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/timex-simulator.png" alt="Timex Simulator" referrerpolicy="no-referrer"><figcaption>Timex Simulator</figcaption>
</figure>
</blockquote>
<p>The documentation says the battery needs to be replaced every 2 years, which is totally acceptable.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/timex-battery.png" alt="Timex Battery" referrerpolicy="no-referrer"><figcaption>Timex Battery</figcaption>
</figure>
</blockquote>
<p>There was also a modest enthusiast community at some point, who wrote some interesting apps. Amusingly, this watch uses the same CPU as a popular retro gaming device (the <a href="https://wiki.sublab.net/index.php/Pokemon_Mini">Pokemon mini</a>), so retro game hackers have already documented the toolchain and device quirks, and even built emulators I might be able to repurpose!</p>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/watch.html</guid>
<link>https://lock.cmpxchg8b.com/watch.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[Putting debugging symbols back into stripped binaries.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I’ve written before about how much I enjoy vintage software. Lately I’ve been tinkering with <a href="https://github.com/taviso/wpunix">WordPerfect for UNIX</a>.</p>
<p>It’s working great, combined with <a href="https://github.com/taviso/123elf/">Lotus 1-2-3</a> you can have a full-featured office suite in an xterm! 😂</p>
<blockquote>
<p><a href="https://github.com/taviso/wpunix"><img src="https://lock.cmpxchg8b.com/img/wp-preview.gif" alt="WordPerfect" referrerpolicy="no-referrer"></a></p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/symbols.html</guid>
<link>https://lock.cmpxchg8b.com/symbols.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I solved a mystery in an old UNIX print ad.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I found this interesting <a href="https://archive.org/details/word-perfect-5.1-for-unix-ad-1993/">print-ad</a> for WordPerfect for UNIX, apparently the best UNIX product of 1992! (Very) Belated congratulations Corel!</p>
<blockquote>
<p><a href="https://lock.cmpxchg8b.com/img/wp-unix1.png"><img src="https://lock.cmpxchg8b.com/img/wp-unix1-small.png" alt="WordPerfect Ad Pg1" referrerpolicy="no-referrer"></a></p>
</blockquote>
<p>However, this section intrigued me:</p>
<pre><code>But what if you don’t go for the GUI? Just choose the Character version, and
depending on your hardware, you’ll get great-looking features rarely seen on a
character terminal. Like document preview, column layout, and other important
features such as easy-to-use drop down menus and easy-to-understand help
screens.</code></pre>
<p>I understand <em>“column layout”</em> and <em>“drop down menus”</em>, but what exactly does <em>“document preview”</em> mean?</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/wordperfect.html</guid>
<link>https://lock.cmpxchg8b.com/wordperfect.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I rediscovered some lost UNIX software.]]></title>
<description><![CDATA[<h1>Intro</h1>
<figure>
<img src="https://lock.cmpxchg8b.com/img/lotus-123-logo.png" alt="Lotus 1-2-3 Logo" referrerpolicy="no-referrer"><figcaption>Lotus 1-2-3 Logo</figcaption>
</figure>
<p>It’s an exciting time in the Lotus 1-2-3 enthusiast community – that was a joke, there is no enthusiast community, it’s just me! 😆</p>
<p>It really is an exciting time though – that part isn’t a joke!</p>
<p>There have been some major developments in the last few weeks, and I guess that’s pretty unusual for 30 year old abandonware.</p>
<p>I’ll cut to the chase; through a combination of unlikely discoveries, crazy hacks and the 90s BBS warez scene I’ve been able to port Lotus 1-2-3 natively to Linux – an operating system that literally didn’t exist when 1-2-3 was released!<a href="https://lock.cmpxchg8b.com/linux123.html#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>If you want to hear how a proprietary application could be ported to new operating systems 30 years after release, read on.</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/linux123.html</guid>
<link>https://lock.cmpxchg8b.com/linux123.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I wrote down some thoughts about Password Managers.]]></title>
<description><![CDATA[<h1>Introduction</h1>
<p>I’ve spent a lot of time trying to understand the attack surface of popular password managers. I think I’ve spent more time analyzing them than practically anybody else, and I think that qualifies me to have an opinion!</p>
<p>First, let’s get a few things out of the way. For some reason, few subjects can get heated faster than passwords. Maybe politics and religion, but that’s about it. It’s okay if you don’t like my opinion.</p>
<p>Second, everyone needs to be using unique passwords. You don’t have to use a password manager to do that, whatever system works for you is fine. If you want to use a notebook in a desk drawer, that’s totally acceptable.</p>
<p>Okay, let’s begin.</p>
<blockquote>
<p>If you just want some advice on what to use, skip to the <a href="https://lock.cmpxchg8b.com/passmgrs.html#conclusion">conclusion</a>.</p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/passmgrs.html</guid>
<link>https://lock.cmpxchg8b.com/passmgrs.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I wrote a display driver for an old DOS program.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p><a href="https://lock.cmpxchg8b.com/img/lotus-online-help.png" title="Screenshot of 1-2-3"><img src="https://lock.cmpxchg8b.com/img/lotus-online-help.png" alt="1-2-3 Screenshot" referrerpolicy="no-referrer"></a></p>
<p>I tend to use a lot of retro software, partly because I’m a big nerd but also because I just prefer to work in a terminal. There were a ton of major commercial software products for MS-DOS that were highly polished, and can still be used effectively in an xterm today.</p>
<p>I do like using <a href="https://www.youtube.com/watch?v=5cNJNKkCQ2E">Lotus 1-2-3</a>, I even have a boxed copy of the last DOS version released, version 4!</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/lotus123.html</guid>
<link>https://lock.cmpxchg8b.com/lotus123.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[You can make popup ads in XTerm with Tektronix mode.Linking a binary with two versions of the same library.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>xterm can emulate a <a href="https://en.wikipedia.org/wiki/Tektronix_4010">Tektronix 4010</a> terminal, It’s actually pretty neat, it’s enabled by default and applications can plot simple graphics (lines, curves, etc) or use it to show graphs.</p>
<p>It randomly occurred to me that windows unexpectedly opening is a bit like a popup browser ad.</p>
<p>Well, it turns out that Tektronix emulation in xterm is so fast that you can draw monochrome bitmaps. Nobody ever asked for or wanted this, but here is a <a href="https://lock.cmpxchg8b.com/files/README.xterm.txt">README file</a> that abuses this to create a popup ad when you <code>cat</code> it in an xterm. 😈</p>
<blockquote>
<p><a href="https://lock.cmpxchg8b.com/img/xtermpopup.mp4"><img src="https://lock.cmpxchg8b.com/img/xtermpopup.gif" alt="XTerm Popup Ad" referrerpolicy="no-referrer"></a></p>
</blockquote>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/tektronix.html</guid>
<link>https://lock.cmpxchg8b.com/tektronix.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I reviewed some spreadsheets that work in the terminal.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I’m not a heavy spreadsheet user, just keeping track of expenses, household inventory, investments, that kind of thing. I mostly just use Google Sheets.</p>
<p>However, I really prefer to stay in a terminal if I can, so decided to review some of the options. My only requirements are that it runs in a terminal and works on Linux, but bonus points if it’s extensible (scripts, macros, plugins, etc).</p>
<p>I’ve tested two F/OSS and two commercial console spreadsheets. Here’s the big caveat, it might surprise you to learn (haha) that there isn’t a huge demand for console productivity software. That means these programs havn’t been actively developed for a very long time, but they were once <strong>incredibly</strong> popular.</p>
<p>Their userbase may now be extinct, but they’re all still mature, stable and functional.</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/spreadsheet.html</guid>
<link>https://lock.cmpxchg8b.com/spreadsheet.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[Read about me trying out some old MS-DOS software, Lotus Agenda.]]></title>
<description><![CDATA[<h1>Intro</h1>
<p>I never used <a href="https://en.wikipedia.org/wiki/Lotus_Agenda">Lotus Agenda</a>, but I’m told it was a popular productivity tool for MS-DOS in the late 80s. I’ve been on a retro software rediscovery kick lately, so I’ve decided to give it a whirl and write about my experiences. There is something that appeals to me about using long-abandoned software. Perhaps it’s update fatigue, there’s certainly no need to dread a major update breaking something!</p>
<p>Regardless, I’ve always enjoyed finding new productivity tools to try out, and I’m not afraid of steep learning curves or getting my hands dirty. I’ll usually choose powerful and flexible software over simplicity.</p>
<p>At the moment I mostly use <a href="https://taskwarrior.org/">taskwarrior</a>, but I’ve lost count of all the others I’ve tried!</p>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/lotusagenda.html</guid>
<link>https://lock.cmpxchg8b.com/lotusagenda.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
</channel>
</rss>
|
Signed-off-by: yuguorui <[email protected]>
Co-authored-by: Tony <[email protected]>
Contributor
|
Successfully generated as following: http://localhost:1200/cmpxchg8b/articles - Success ✔️<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
>
<channel>
<title><![CDATA[cmpxchg8b]]></title>
<link>https://lock.cmpxchg8b.com/#articles</link>
<atom:link href="http://localhost:1200/cmpxchg8b/articles" rel="self" type="application/rss+xml" />
<description><![CDATA[cmpxchg8b - Made with love by RSSHub(https://github.com/DIYgod/RSSHub)]]></description>
<generator>RSSHub</generator>
<webMaster>[email protected] (DIYgod)</webMaster>
<language>zh-cn</language>
<lastBuildDate>Wed, 15 Nov 2023 15:39:39 GMT</lastBuildDate>
<ttl>5</ttl>
<item>
<title><![CDATA[What happens when a CPU goes wrong?]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Reptar</h1>
<p class="author">Tavis Ormandy</p>
</header>
<p>We have a CPU mystery! We found a way to cause some processors to enter a glitch state where the normal rules don’t apply, but what does that mean…?</p>
<p>If you’re interested what can go wrong inside modern CPUs, read on!</p>
<section id="introduction" class="level2">
<h2>Introduction</h2>
<p>If you’ve ever written any x86 assembly at all, you’ve probably used <code>rep movsb</code>. It’s the idiomatic way of moving memory around on x86. You set the <em>source</em>, <em>destination</em>, <em>direction</em> and the <em>count</em> - then just let the processor handle all the details!</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb1-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-1" aria-hidden="true"></a><span class="kw">lea</span> <span class="kw">rdi</span>, [rel dst]</span>
<span id="cb1-2"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-2" aria-hidden="true"></a><span class="kw">lea</span> <span class="kw">rsi</span>, [rel src]</span>
<span id="cb1-3"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-3" aria-hidden="true"></a><span class="kw">std</span></span>
<span id="cb1-4"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-4" aria-hidden="true"></a><span class="kw">mov</span> <span class="kw">rcx</span>, <span class="dv">32</span></span>
<span id="cb1-5"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-5" aria-hidden="true"></a>rep <span class="kw">movsb</span></span></code></pre></div>
<p>The actual instruction here is <code>movsb</code>, the <code>rep</code> is simply a prefix that changes how the instruction works. In this case, it indicates that you want this operation <strong>rep</strong>eated multiple times.</p>
<p>There are lots of other prefixes too, but they don’t all apply to every instruction.</p>
<section id="prefix-decoding" class="level4">
<h4>Prefix Decoding</h4>
<p>An interesting feature of x86 is that the instruction decoding is generally quite relaxed. If you use a prefix that doesn’t make sense or conflicts with other prefixes nothing much will happen, it will usually just be ignored.</p>
<p>This fact is sometimes useful; compilers can use redundant prefixes to pad a single instruction to a desirable alignment boundary.</p>
<p>Take a look at this snippet, this is exactly the same code as above, just a bunch of useless or redundant prefixes have been added:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb2-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-1" aria-hidden="true"></a> rep <span class="kw">lea</span> <span class="kw">rdi</span>, [rel dst]</span>
<span id="cb2-2"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-2" aria-hidden="true"></a> <span class="kw">cs</span> <span class="kw">lea</span> <span class="kw">rsi</span>, [rel src]</span>
<span id="cb2-3"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-3" aria-hidden="true"></a> <span class="kw">gs</span> <span class="kw">gs</span> <span class="kw">gs</span> <span class="kw">std</span></span>
<span id="cb2-4"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-4" aria-hidden="true"></a> repnz <span class="kw">mov</span> <span class="kw">rcx</span>, <span class="dv">32</span></span>
<span id="cb2-5"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-5" aria-hidden="true"></a>rep rep rep rep <span class="kw">movsb</span></span></code></pre></div>
<p>Perhaps the most interesting prefixes are <code>rex</code>, <code>vex</code> and <code>evex</code>, all of which change how subsequent instructions are decoded.</p>
<p>Let’s take a look at how they work.</p>
</section>
<section id="the-rex-prefix" class="level4">
<h4>The REX prefix</h4>
<p>The i386 only had 8 general purpose registers, so you could specify which register you want to use in just 3 bits (because 2^3 is 8).</p>
<p>The way that instructions were encoded took advantage of this fact, and reserved <em>just</em> enough bits to specify any of those registers.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/rep-modrm.svg" class="noborder" style="width:100.0%" alt="" referrerpolicy="no-referrer"><figcaption>modr/m example</figcaption>
</figure>
<p>Simple 2-byte instructions that use modr/m might be encoded like this, for example <code>mov eax, ebx</code>.</p>
<p>This is an 8-bit opcode, 2 bit addressing mode (labeled m), and 3 bits each for the source (s) and destination (d).</p>
</blockquote>
<p>Well, this is a problem, because x86-64 added 8 additional general purpose registers. We now have sixteen possible registers..that’s 2^4, so we’re going to need another bit! 😆</p>
<p>The solution to this is the <code>rex</code> prefix, which gives us some spare bits that the next instruction can borrow.</p>
<p>When we’re talking about rex, we usually write it like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb3-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb3-1" aria-hidden="true"></a>rex.rxb</span></code></pre></div>
<p><code>rex</code> is a single-byte prefix, the first four bits are mandatory and the remaining four bits called <code>b</code>, <code>x</code>, <code>r</code> and <code>w</code> are all optional. If you see <code>rex.rb</code> that means only the <code>r</code> and <code>b</code> bits are set, all the others are unset.</p>
<p>These optional bits give us room to encode more general purpose registers in the following instruction.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/rep-rexmodrm.svg" class="noborder" style="width:100.0%" alt="" referrerpolicy="no-referrer"><figcaption>rex example</figcaption>
</figure>
<p>The <code>rex</code> prefix can lend the next instruction extra bits to use for operands, so now we can encode all 16 possible general purpose registers!</p>
</blockquote>
<p>Now we’re fine until someone <a href="https://www.intel.com/content/www/us/en/developer/articles/technical/advanced-performance-extensions-apx.html">adds another register</a>! 😂</p>
</section>
<section id="encoding-rules" class="level4">
<h4>Encoding Rules</h4>
<p>So now we know that <code>rex</code> increases the available space for encoding operands, and that useless or redundant prefixes are usually ignored on x86. So… what should this instruction do?</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb4-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb4-1" aria-hidden="true"></a>rex.rxb rep <span class="kw">movsb</span></span></code></pre></div>
<p>The <code>movsb</code> instruction doesn’t have any operands - they’re all implicit - so any <code>rex</code> bits are meaningless, right?</p>
<p>If you guessed that the processor will just silently ignore the <code>rex</code> prefix, you would be correct!</p>
<p>Well… except on machines that support a new feature called <em>fast short repeat move</em>! We discovered that a bug with redundant <code>rex</code> prefixes could interact with this feature in an unexpected way and introduce a serious vulnerability, oops 🙂</p>
</section>
<section id="fast-short-repeat-move" class="level4">
<h4>Fast Short Repeat Move</h4>
<p>FSRM is a new feature introduced in <a href="https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(client)#New_instructions">Ice Lake</a> that fixes some of the shortcomings of ERMS. Hopefully that clears up any confusion. 😆</p>
<p>Just kidding, let’s quickly look at ERMS.</p>
<p>The hard part of moving strings around efficiently is getting all the buffers aligned so you can use the widest possible stores available. You <em>could</em> do this in software, but if we do it in microcode then the processor can just transparently make your existing code faster for you.</p>
<p>This requires some expensive setup, but once that’s done you get vastly improved throughput. This feature is known as <em>enhanced repeat move/store</em>, ERMS.</p>
<p>If you have a processor with ERMS support, simple <code>rep movsb</code> operations can sometimes perform comparably with more complicated hand-tuned vector move operations.</p>
<p>However, there is a problem with ERMS. That initial setup is so expensive that it just isn’t worth it for very short strings. This is what FSRM is designed to solve, it handles the case of only moving 128 bytes or less and makes that faster too!</p>
<p>I’m not aware of any documentation that explains exactly how FSRM works, but you can check if you have a processor that supports it by looking at the flags line in <code>/proc/cpuinfo</code>:</p>
<pre><code>flags : fpu vme de pse tsc msr pae mce cx8 [...] fsrm</code></pre>
<p>Some of the processors that have this feature include:</p>
<ul>
<li>Ice Lake</li>
<li>Rocket Lake</li>
<li>Tiger Lake</li>
<li>Raptor Lake</li>
<li>Alder Lake</li>
<li>Sapphire Rapids</li>
</ul>
<blockquote>
<p>Note: This list may not be comprehensive, please see Intel advisory INTEL-SA-00950 for a complete list.</p>
</blockquote>
</section>
</section>
<section id="discovery" class="level2">
<h2>Discovery</h2>
<p>I’ve written previously about a processor validation technique called <em>Oracle Serialization</em> that we’ve been using. The idea is to generate two forms of the same randomly generated program and verify their final state is identical.</p>
<blockquote>
<p>You can read more about Oracle Serialization in my <a href="https://lock.cmpxchg8b.com/zenbleed.html">previous writeup</a>.</p>
</blockquote>
<p>In August, our validation pipeline produced an interesting assertion. It had found a case where adding redundant <code>rex.r</code> prefixes to an FSRM optimized <code>rep movs</code> operation seemed to cause unpredictable results.</p>
<p>We observed some very strange behavior while testing. For example, branches to unexpected locations, unconditional branches being ignored and the processor no longer accurately recording the instruction pointer in <code>xsave</code> or <code>call</code> instuctions.</p>
<p>Oddly, when trying to understand what was happening we would see a debugger reporting impossible states!</p>
<p>This already seemed like it could be indicative of a serious problem, but within a few days of experimenting we found that when multiple cores were triggering the same bug, the processor would begin to report machine check exceptions and halt.</p>
<p>We verified this worked even inside an unprivileged guest VM, so this already has serious security implications for cloud providers. Naturally, we reported this to Intel as soon as we confirmed this was a security issue.</p>
<section id="reproduce" class="level4">
<h4>Reproduce</h4>
<p>We’re publishing all of our research today to our <a href="https://github.com/google/security-research/tree/master/pocs/cpus/reptar">security research repository</a>. If you want to reproduce the vulnerability you can use our <code>icebreak</code> tool, I’ve also made a local mirror available <a href="https://lock.cmpxchg8b.com/files/icebreak.tar.gz">here</a>.</p>
<pre><code>$ ./icebreak -h
usage: ./icebreak [OPTIONS]
-c N,M Run repro threads on core N and M.
-d N Sleep N usecs between repro attempts.
-H N Spawn a hammer thread on core N.
icebreak: you must at least specify a core pair with -c! (see -h for help)</code></pre>
<p>The testcase enters what should be an infinite loop, and unaffected systems should see no output at all. On affected systems, a <code>.</code> is printed on each successful reproduction.</p>
<pre><code>$ ./icebreak -c 0,4
starting repro on cores 0 and 4
.........................................................................
.........................................................................
.........................................................................
.........................................................................
.........................................................................</code></pre>
<p>In general, if the cores are <abbr title="Symmetric Multithreading">SMT</abbr> siblings then you may observe random branches and if they’re <abbr title="Symmetric Multiprocessing">SMP</abbr> siblings from the same package then you may observe machine checks.</p>
<p>If you do <em>not</em> specify two different cores, then you might need to use a hammer thread to trigger a reproduction.</p>
</section>
<section id="analysis" class="level4">
<h4>Analysis</h4>
<p>We know something strange is happening, but how microcode works in modern systems is a closely guarded secret. We can only theorize about the root cause based on observations.</p>
<section id="μops" class="level5">
<h5>μops</h5>
<p>The CPU is split in two major components, the <em>frontend</em> and the <em>backend</em>. The frontend is responsible for fetching instructions, decoding them and generating μops to send to the backend for execution.</p>
<p>The backend executes instructions <em>out of order</em>, and uses a unit called the ROB, <em>reorder buffer</em>, to store and organize results.</p>
<p>We believe this bug causes the frontend to miscalculate the size of the <code>movsb</code> instruction, causing subsequent entries in the ROB to be associated with incorrect addresses. When this happens, the CPU enters a confused state that causes the instruction pointer to be miscalculated.</p>
<p>The machine can eventually recover from this state, perhaps with incorrect intermediate results, but becoming internally consistent again. However, if we cause multiple SMT or SMP cores to enter the state simultaneously, we can cause enough microarchitectural state corruption to force a machine check.</p>
</section>
</section>
<section id="questions" class="level4">
<h4>Questions</h4>
<p>I’m sure some readers will have questions about what is possible in this unexpected “glitch” state. Well, so do we!</p>
<p>We know that we can corrupt the system state badly enough to cause machine check errors, and we’ve also observed threads interfere with execution of processes scheduled on SMT siblings.</p>
<p>However, we simply don’t know if we can control the corruption precisely enough to achieve privilege escalation. I suspect that it <em>is</em> possible, but we don’t have any way to debug μop execution!</p>
<p>If you’re interested in studying this, then we would love to get your input!</p>
</section>
<section id="credit" class="level4">
<h4>Credit</h4>
<p>This bug was independently discovered by multiple research teams within Google, including the <a href="https://github.com/google/silifuzz">silifuzz</a> team and Google <a href="https://bughunters.google.com/blog">Information Security Engineering</a>. The bug was analyzed by Tavis Ormandy, Josh Eads, Eduardo Vela Nava, Alexandra Sandulescu and Daniel Moghimi.</p>
</section>
</section>
<section id="solution" class="level2">
<h2>Solution</h2>
<p>Intel have <a href="https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00950.html">published</a> updated microcode for all affected processors. Your operating system or BIOS vendor may already have an update available!</p>
<section id="workaround" class="level4">
<h4>Workaround</h4>
<p>If you can’t update for some reason, you <em>could</em> disable fast strings via the <code>IA32_MISC_ENABLE</code> model specific register.</p>
<p>This will cause a significant performance penalty, and should not be used unless absolutely necessary.</p>
</section>
</section>
<section id="notes" class="level2">
<h2>Notes</h2>
<p>If you’re interested in more CPU bugs, we publish everything we find!</p>
<p>Not all the bugs we discover have security consequences, but they’re usually worth reading! For example, did you know that sometimes <a href="https://github.com/google/security-research/tree/master/pocs/cpus/errata/amd/genoa-lps-hps">movlps just doesn’t work</a>? or that registers can sometimes <a href="https://github.com/google/security-research/tree/master/pocs/cpus/errata/amd/1386">roll back</a> to previous values?</p>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/reptar.html</guid>
<link>https://lock.cmpxchg8b.com/reptar.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[An overview of hacking the Timex m851.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Hacking the Timex m851</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: a07cf90837a3c4373b82d6724b97593810766af7 $</p>
</header>
<p><small> <em>This post is part of a series on my quest to find the perfect watch.</em> </small></p>
<section id="intro" class="level1">
<h1>Intro</h1>
<p><a href="https://lock.cmpxchg8b.com/img/datalink.jpg" title="Timex m851"><img src="https://lock.cmpxchg8b.com/img/datalink.jpg" alt="Timex m851" referrerpolicy="no-referrer"></a></p>
<p>Take a look at this watch, it’s just some boring watch for runners, right?</p>
<p>Nope, I think this might be the best ultra-low power consumer digital watch ever produced!</p>
<p>Let me explain…</p>
<section id="specifications" class="level4">
<h4>Specifications</h4>
<p>This is the Timex m851. It uses an 8-bit Seiko SC188 CPU, has 48KB of ROM, 2KB of RAM and a 42x11 dot matrix main display.</p>
<p>The cpu is designed for ultra-low power operation - a single battery can last 3 <em>years</em>!</p>
<p>This is a big selling point for me, I don’t think they’re making consumer watches like this any more.</p>
<p><img src="https://lock.cmpxchg8b.com/img/datalink-usb.jpg" alt="Timex USB" class="noclear" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/datalink-pins.jpg" alt="Timex USB" class="noclear" referrerpolicy="no-referrer"></p>
<p>Those pins on the side? That’s USB. Naturally, you can synchronize things like appointments, and so on (there’s a neat <a href="https://github.com/HuidaeCho/libdlusb">linux library</a> for that).</p>
<p>Here’s where it get’s interesting… this thing has an SDK, and it is <em>surprisingly</em> good!</p>
<p>You can just <code>$ cc helloworld.c</code>, and upload it to your watch.</p>
<p>I didn’t really think I would be enamored with this watch at first – the Windows XP-era wizard Timex provided for development was… <strong><em>painful</em></strong>. However, it turned out it was just driving a UNIX-like toolchain behind the scenes.</p>
<p>After pulling that out, hacking this started to become pretty fun!</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/datalink-make.gif" alt="Makefile" style="width:70.0%" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/watch.gif" alt="Hello World" style="width:20.0%" referrerpolicy="no-referrer"></p>
</blockquote>
</section>
</section>
<section id="watchapps" class="level1">
<h1>WatchApps</h1>
<p>Just want to see some code? No problem, I’ve uploaded a <em>hello world</em> and a <code>Makefile</code> to build it to github:</p>
<p><a href="https://github.com/taviso/timex/">https://github.com/taviso/timex/</a></p>
<p>If you want to browse the full manual, there are some links below.</p>
<p>You can do some fun things with this, people wrote all kinds of <a href="https://www.youtube.com/watch?v=mitJafrsimw">games</a>, <a href="http://datalinkwristapps.free.fr/index.php5?n=Wristapps.MyWatch">utilities</a>, and <a href="https://rayslogic.com/Software/TimexUSB/WristApps/WristApps.htm">tools</a>.</p>
<p>If you want a TL;DR of development, I’ll try!</p>
<section id="design" class="level4">
<h4>Design</h4>
<section id="states-and-modes" class="level5">
<h5>States and Modes</h5>
<p>You need to split your application into <em>states</em>.</p>
<p>A <em>state</em> is just a way to swap code in and out as needed. When you switch states, the active code is discarded and the new code is swapped in.</p>
<blockquote>
<p>You <em>could</em> write an app that uses up to ~30kb of code and/or data, <em>but</em> there is only ~2kb of RAM. This is why you need to use states, there is no paging and you couldn’t fit that in!</p>
</blockquote>
<p>There is room for some <em>common</em> code that all your states share, and of course there is space for variables, along with a database API for persistent data.</p>
<p>The first few states are reserved for handling common events. The rest you can use for anything you want - you just ask the kernel to switch you whenever you need it!</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb1-1" title="1"><span class="cf">if</span> (foo > bar) {</a>
<a class="sourceLine" id="cb1-2" title="2"> coreRequestStateChange(FOOBAR_STATE);</a>
<a class="sourceLine" id="cb1-3" title="3">}</a></code></pre></div>
<p>A <em>mode</em> is just a foreground application.</p>
<p>Your app is (probably) providing a mode, but you can also add background tasks, periodic tasks, and so on.</p>
<p>Requesting a mode change is sort of like <code>exit()</code>, the next app will gain control.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb2-1" title="1">coreRequestModeChangeNext();</a></code></pre></div>
</section>
<section id="events" class="level5">
<h5>Events</h5>
<p>Each state needs an event handler. A super simple one would be like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb3-1" title="1"><span class="dt">void</span> default_state_manager(<span class="dt">void</span>)</a>
<a class="sourceLine" id="cb3-2" title="2">{</a>
<a class="sourceLine" id="cb3-3" title="3"> <span class="cf">switch</span> (CORECurrentEvent) {</a>
<a class="sourceLine" id="cb3-4" title="4"> <span class="co">// This is called when this state becomes active.</span></a>
<a class="sourceLine" id="cb3-5" title="5"> <span class="cf">case</span> COREEVENT_STATEENTRY:</a>
<a class="sourceLine" id="cb3-6" title="6"> coreEnableSwitchReleaseEvents();</a>
<a class="sourceLine" id="cb3-7" title="7"> coreAllowKeys(COREALLOWALLSWITCHES);</a>
<a class="sourceLine" id="cb3-8" title="8"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-9" title="9"> <span class="co">// This is called when the user pulls the crown out.</span></a>
<a class="sourceLine" id="cb3-10" title="10"> <span class="co">// When they push it back in, you get a CROWN_HOME event.</span></a>
<a class="sourceLine" id="cb3-11" title="11"> <span class="co">// It can be rotated in either home or set positions.</span></a>
<a class="sourceLine" id="cb3-12" title="12"> <span class="cf">case</span> COREEVENT_CROWN_SET:</a>
<a class="sourceLine" id="cb3-13" title="13"> coreRequestStateChange(CORESETBANNERSTATE);</a>
<a class="sourceLine" id="cb3-14" title="14"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-15" title="15"> <span class="co">// You can get button events too, like start/split:</span></a>
<a class="sourceLine" id="cb3-16" title="16"> <span class="cf">case</span> COREEVENT_STARTSPLITDEPRESS:</a>
<a class="sourceLine" id="cb3-17" title="17"> show_message();</a>
<a class="sourceLine" id="cb3-18" title="18"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-19" title="19"> <span class="co">// The mode button probably means the user wants to exit...</span></a>
<a class="sourceLine" id="cb3-20" title="20"> <span class="cf">case</span> COREEVENT_MODEDEPRESS:</a>
<a class="sourceLine" id="cb3-21" title="21"> coreRequestModeChangeNext();</a>
<a class="sourceLine" id="cb3-22" title="22"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-23" title="23"> }</a>
<a class="sourceLine" id="cb3-24" title="24"></a>
<a class="sourceLine" id="cb3-25" title="25"> <span class="cf">return</span>;</a>
<a class="sourceLine" id="cb3-26" title="26">}</a></code></pre></div>
<p>In general, you can ignore any event you don’t care about.</p>
</section>
<section id="services" class="level5">
<h5>Services</h5>
<p>The kernel takes care of handling the hardware, dispatching events to you and provides various services.</p>
<p>Things like timers, generating tones (beeps), scrolling the display, access to database records, etc.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb4-1" title="1"><span class="dt">uint8_t</span> banner[] = {</a>
<a class="sourceLine" id="cb4-2" title="2"> LCDBANNER_COL10,</a>
<a class="sourceLine" id="cb4-3" title="3"> DM5_H, DM5_E, DM5_L, DM5_L, DM5_O, DM5_EXCLAMATION,</a>
<a class="sourceLine" id="cb4-4" title="4"> LCD_END_BANNER</a>
<a class="sourceLine" id="cb4-5" title="5">};</a>
<a class="sourceLine" id="cb4-6" title="6"></a>
<a class="sourceLine" id="cb4-7" title="7">lcdClearDisplay();</a>
<a class="sourceLine" id="cb4-8" title="8"></a>
<a class="sourceLine" id="cb4-9" title="9"><span class="co">// Draw "hello!" using kernel services.</span></a>
<a class="sourceLine" id="cb4-10" title="10">lcdDispBannerMsg(&banner);</a></code></pre></div>
<p>The watch has a crown - and you can ask the kernel to configure it in a few different ways. For example, you might want pulse mode so you can monitor how quickly the user is turning it.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/crown.gif" alt="Crown Demo" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>Crown Demo</figcaption>
</figure>
</blockquote>
<p>It has a backlight, you can control that from software too.</p>
</section>
</section>
<section id="debugging" class="level4">
<h4>Debugging</h4>
<p>There’s no memory protection or anything, you can just clobber the kernel if you want… so what happens if you crash?</p>
<p>Well, one thing the kernel does is notify a watchdog every 2 seconds that it’s still alive. If the watchdog doesn’t see that notification, it will just reset the watch… so try not to do that! 😀</p>
<p>If you’re doing some heavy computation you could accidentally trigger the watchdog. Just remember to let the watchdog know you’re still alive:</p>
<pre><code> // Let the watchdog know we're not dead.
hwResetWatchdog();</code></pre>
<section id="simulator" class="level5">
<h5>Simulator</h5>
<p>Luckily there’s a really good simulator available, so you don’t have to sit through tedious resets everytime you make a typo. It’s actually an open source 3rd party tool, <a href="http://datalinkwristapps.free.fr/index.php5?n=PC.VirtualDatalink">Virtual Datalink</a> (<a href="https://sourceforge.net/projects/virtualdatalink/">source</a>).</p>
<blockquote>
<p>Sadly it’s for Windows only. I would port it to Linux, but it’s written in Delphi… is it feasible to port it to free pascal? Let me know!</p>
</blockquote>
<p>It has conditional breakpoints, a dissasembler, save states, resource and power analysis. I’ve found it pretty capable.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/vdatalink.gif" alt="Virtual Datalink" class="noborder" referrerpolicy="no-referrer"><figcaption>Virtual Datalink</figcaption>
</figure>
</blockquote>
</section>
</section>
</section>
<section id="conclusion" class="level1">
<h1>Conclusion</h1>
<p>The main app I’m working on right now is integrating my watch with <a href="https://dianne.skoll.ca/projects/remind/">remind</a>.</p>
<p>Hacking this little watch has been a super fun project!</p>
<section id="availability" class="level4">
<h4>Availability</h4>
<p>Now that I’ve told you how much I love this thing - the bad news.</p>
<p>They’re long out of production, and getting hard to come by.</p>
<p>I bought a set of two on eBay, they just needed new batteries and were as good as new.</p>
<p>If this is the sort of thing that appeals to you, setup an alert and then help me hack on it 😀</p>
</section>
<section id="references" class="level4">
<h4>References</h4>
<ul>
<li>The most important doc is the <a href="https://assets.timex.com/developer/developer_downloads/WA_Design_Guide.pdf">Design Guide</a>, it’s very well written.</li>
<li>Then of course, you need the <a href="https://www.rayslogic.com/Software/TimexUSB/Docs/s1c88%20core%20cpu%20manual.pdf">CPU manual</a>. It’s also excellent!</li>
<li>The toolchain also has a thorough manual.</li>
<li>Finally, the complete <a href="https://assets.timex.com/developer/developer_downloads/WA_API_Reference.pdf">API reference</a> lists the services provided by the Kernel.</li>
</ul>
</section>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/timex.html</guid>
<link>https://lock.cmpxchg8b.com/timex.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I found an interesting CPU bug.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Zenbleed</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: 7d85ef516b9682eaf0db09cc9c4e53a523486f3f $</p>
</header>
<p>If you remove the first word from the string <code>"hello world"</code>, what should the result be? This is the story of how we discovered that the answer could be your root password!</p>
<section id="introduction" class="level2">
<h2>Introduction</h2>
<p>All x86-64 CPUs have a set of 128-bit vector registers called the <code>XMM</code> registers. You can never have enough bits, so recent CPUs have extended the width of those registers up to 256-bit and even 512-bits.</p>
<p>The 256-bit extended registers are called <code>YMM</code>, and the 512-bit registers are <code>ZMM</code>.</p>
<p>These big registers are useful in lots of situations, not just number crunching! They’re even used by standard C library functions, like <code>strcmp</code>, <code>memcpy</code>, <code>strlen</code> and so on.</p>
<p>Let’s take a look at an example. Here are the first few instructions of glibc’s AVX2 optimized <code>strlen</code>:</p>
<pre><code>(gdb) x/20i __strlen_avx2
...
<__strlen_avx2+9>: vpxor xmm0,xmm0,xmm0
...
<__strlen_avx2+29>: vpcmpeqb ymm1,ymm0,YMMWORD PTR [rdi]
<__strlen_avx2+33>: vpmovmskb eax,ymm1
...
<__strlen_avx2+41>: tzcnt eax,eax
<__strlen_avx2+45>: vzeroupper
<__strlen_avx2+48>: ret</code></pre>
<p>The full routine is complicated and handles lots of cases, but let’s step through this simple case. Bear with me, I promise there’s a point!</p>
<p>The first step is to initialize <code>ymm0</code> to zero, which is done by just <code>xor</code>ing <code>xmm0</code> with itself<a href="https://lock.cmpxchg8b.com/zenbleed.html#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vpxor.svg" alt="VPXOR xmm0, xmm0, xmm0" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>VPXOR xmm0, xmm0, xmm0</figcaption>
</figure>
<pre><code> > vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Here <code>rdi</code> contains a pointer to our string, so <code>vpcmpeqb</code> will check which bytes in <code>ymm0</code> match our string, and stores the result in <code>ymm1</code>.</p>
<p>As we’ve already set <code>ymm0</code> to all zero bytes, only nul bytes will match.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vpcmpeqb.svg" alt="vpcmpeqb ymm1, ymm0, rdi" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>vpcmpeqb ymm1, ymm0, rdi</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
> vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Now we can extract the result into a general purpose register like <code>eax</code> with <code>vpmovmskb</code>.</p>
<p>Any nul byte will create a 1 bit, and any other value will create a 0 bit.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vpmovmskb.svg" alt="vpmovmskb eax, ymm1" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>vpmovmskb eax, ymm1</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
> vpmovmskb eax, ymm1
tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Finding the first zero byte is now just a case of counting the number of trailing zero bits.</p>
<p>That’s a common enough operation that there’s an instruction for it - <code>tzcnt</code> (Trailing Zero Count).</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-tzcnt.svg" alt="tzcnt eax, eax" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>tzcnt eax, eax</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
> tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Now we have the position of the first nul byte, in just four machine instructions!</p>
<p>You can probably imagine just how often <code>strlen</code> is running on your system right now, but suffice to say, bits and bytes are flowing into these vector registers from all over your system constantly.</p>
<section id="zeroing-registers" class="level4">
<h4>Zeroing Registers</h4>
<p>You might have noticed that I missed one instruction, and that’s <code>vzeroupper</code>.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vzeroupper.svg" alt="vzeroupper" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>vzeroupper</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
tzcnt eax, eax
> vzeroupper</code></pre>
</blockquote>
<p>You guessed it, <code>vzeroupper</code> will zero the upper bits of the vector registers.</p>
<p>The reason we do this is because if you mix <code>XMM</code> and <code>YMM</code> registers, the <code>XMM</code> registers automatically get promoted to full width. It’s a bit like integer promotion in C.</p>
<p>This works fine, but <a href="https://en.wikipedia.org/wiki/Superscalar">superscalar</a> processors need to track dependencies so that they know which operations can be parallelized. This promotion adds a dependency on those upper bits, and that causes unnecessary stalls while the processor waits for results it didn’t really need.</p>
<p>These stalls are what glibc is trying to avoid with <code>vzeroupper</code>. Now any future results won’t depend on what those bits are, so we safely avoid that bottleneck!</p>
</section>
<section id="the-vector-register-file" class="level4">
<h4>The Vector Register File</h4>
<p>Now that we know <em>what</em> <code>vzeroupper</code> does, <em>how</em> does it do it?</p>
<p>Your processor doesn’t have a single physical location where each register lives, it has what’s called a <em><a href="https://en.wikipedia.org/wiki/Register_file">Register File</a></em> and a <em>Register Allocation Table</em>. This is a bit like managing the heap with <code>malloc</code> and <code>free</code>, if you think of each register as a pointer. The RAT keeps track of what space in the register file is assigned to which register.</p>
<p>In fact, when you zero an <code>XMM</code> register, the processor doesn’t store those bits anywhere at all - it just sets a flag called the <a href="https://en.wikichip.org/wiki/amd/microarchitectures/zen_2#Floating_Point_Unit">z-bit</a> in the RAT. This flag can be applied to the upper and lower parts of <code>YMM</code> registers independently, so <code>vzeroupper</code> can simply set the z-bit and then release any resources assigned to it in the register file.</p>
<figure>
<blockquote>
<img src="https://lock.cmpxchg8b.com/img/zb-zbit.svg" alt="Z-Bit" class="noborder" referrerpolicy="no-referrer">
<figcaption class="visible">
A register allocation table (left) and a physical register file (right).
</figcaption>
</blockquote>
</figure>
</section>
<section id="speculation" class="level4">
<h4>Speculation</h4>
<p>Hold on, there’s another complication! Modern processors use <a href="https://en.wikipedia.org/wiki/Speculative_execution">speculative execution</a>, so sometimes operations have to be rolled back.</p>
<p>What should happen if the processor <em>speculatively</em> executed a <code>vzeroupper</code>, but then discovers that there was a branch misprediction? Well, we will have to revert that operation and put things back the way they were… maybe we can just unset that z-bit?</p>
<p>If we return to the analogy of <code>malloc</code> and <code>free</code>, you can see that it can’t be that simple - that would be like calling <code>free()</code> on a pointer, and then changing your mind!</p>
<p>That would be a use-after-free vulnerability, but there is no such thing as a use-after-free in a CPU… or is there?</p>
<p>Spoiler: <strong><em>yes there is</em></strong> 🙂</p>
<figure>
<blockquote>
<img src="https://lock.cmpxchg8b.com/img/zb-leaking.gif" alt="Zenbleed Demo" class="noborder" referrerpolicy="no-referrer">
<figcaption class="visible">
This animation shows why resetting the z-bit is not sufficient.
</figcaption>
</blockquote>
</figure>
</section>
</section>
<section id="vulnerability" class="level2">
<h2>Vulnerability</h2>
<p>It turns out that with precise scheduling, you <em>can</em> cause some processors to recover from a mispredicted <code>vzeroupper</code> incorrectly!</p>
<p>This technique is CVE-2023-20593 and it works on all Zen 2 class processors, which includes at least the following products:</p>
<ul>
<li>AMD Ryzen 3000 Series Processors</li>
<li>AMD Ryzen PRO 3000 Series Processors</li>
<li>AMD Ryzen Threadripper 3000 Series Processors</li>
<li>AMD Ryzen 4000 Series Processors with Radeon Graphics</li>
<li>AMD Ryzen PRO 4000 Series Processors</li>
<li>AMD Ryzen 5000 Series Processors with Radeon Graphics</li>
<li>AMD Ryzen 7020 Series Processors with Radeon Graphics</li>
<li>AMD EPYC “Rome” Processors</li>
</ul>
<p>The bug works like this, first of all you need to trigger something called the <em>XMM Register Merge Optimization</em><a href="https://lock.cmpxchg8b.com/zenbleed.html#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>, followed by a <a href="https://en.wikipedia.org/wiki/Register_renaming">register rename</a> and a mispredicted <code>vzeroupper</code>. This all has to happen within a precise window to work.</p>
<p>We now know that basic operations like <code>strlen</code>, <code>memcpy</code> and <code>strcmp</code> will use the vector registers - so we can effectively spy on those operations happening anywhere on the system! It doesn’t matter if they’re happening in other virtual machines, sandboxes, containers, processes, whatever!</p>
<p>This works because the register file is shared by everything on the same physical core. In fact, two hyperthreads even share the same physical register file.</p>
<p>Don’t believe me? Let’s write an exploit 🙂</p>
</section>
<section id="exploitation" class="level2">
<h2>Exploitation</h2>
<p>There are quite a few ways to trigger this, but let’s examine a very simple example.</p>
<pre><code> vcvtsi2s{s,d} xmm, xmm, r64
vmovdqa ymm, ymm
jcc overzero
vzeroupper
overzero:
nop</code></pre>
<p>Here <code>cvtsi2sd</code> is used to trigger the merge optimization. It’s not important what <code>cvtsi2sd</code> is <em>supposed</em> to do, I’m just using it because it’s one of the instructions the manual says use that optimization<a href="https://lock.cmpxchg8b.com/zenbleed.html#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.</p>
<p>Then we need to trigger a <a href="https://en.wikipedia.org/wiki/Register_renaming">register rename</a>, <code>vmovdqa</code> will work. If the conditional branch<a href="https://lock.cmpxchg8b.com/zenbleed.html#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> is taken but the CPU predicts the not-taken path, the <code>vzeroupper</code> will be mispredicted and the bug occurs!</p>
<section id="optimization" class="level4">
<h4>Optimization</h4>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-exploit.gif" alt="Exploit Running" class="noborder" referrerpolicy="no-referrer"><figcaption>Exploit Running</figcaption>
</figure>
<p>It turns out that mispredicting on purpose is difficult to optimize! It took a bit of work, but I found a variant that can leak about 30 kb per core, per second.</p>
<p>This is fast enough to monitor encryption keys and passwords as users login!</p>
<p>We’re releasing our full technical advisory, along with all the associated code today. Full details will be available in our <a href="https://github.com/google/security-research/tree/master/pocs/cpus">security research repository</a>.</p>
<p>If you want to test the exploit, the code is available <a href="https://lock.cmpxchg8b.com/files/zenbleed-v5.tar.gz">here</a>.</p>
<p>Note that the code is for Linux, but the bug is not dependent on any particular operating system - all operating systems are affected!</p>
</section>
</section>
<section id="discovery" class="level2">
<h2>Discovery</h2>
<p>I found this bug by fuzzing, big surprise 🙂 I’m not the first person to apply fuzzing techniques to finding hardware flaws. In fact, vendors fuzz their own products extensively - the industry term for it is <em>Post-Silicon Validation</em>.</p>
<p>So how come this bug wasn’t found earlier? I think I did a couple of things differently, perhaps with a new perspective as I don’t have an EE background!</p>
<section id="feedback" class="level4">
<h4>Feedback</h4>
<p>The best performing fuzzers are guided by coverage <a href="https://google.github.io/clusterfuzz/reference/coverage-guided-vs-blackbox/">feedback</a>. The problem is that there is nothing really analogous to code coverage in CPUs… However, we do have <a href="https://en.wikipedia.org/wiki/Hardware_performance_counter">performance counters</a>!</p>
<p>These will let us know when all kinds of <a href="https://perfmon-events.intel.com/skylake.html">interesting architectural events</a> happen.</p>
<p>Feeding this data to the fuzzer lets us gently guide it towards exploring interesting features that we wouldn’t have been able to find by chance alone!</p>
<p>It was challenging to get the details right, but I used this to teach my fuzzer to find interesting instruction sequences. This allowed me to discover features like merge optimization automatically, without any input from me!</p>
</section>
<section id="oracle" class="level4">
<h4>Oracle</h4>
<p>When we fuzz software, we’re usually looking for crashes. Software isn’t supposed to crash, so we know something must have gone wrong if it does.</p>
<p>How can we know if a a CPU is executing a randomly generated program correctly? It might be completely correct for it to crash!</p>
<p>Well, a few solutions have been proposed to this problem. One approach is called <a href="https://ieeexplore.ieee.org/abstract/document/4751878">reversi</a>. The general idea is that for every random instruction you generate, you also generate the inverse (e.g. <code>ADD r1, r2</code> → <code>SUB r1, r2</code>). Any deviation from the initial state at the end of execution must have been an error, neat!</p>
<p>The reversi approach is clever, but it makes generating testcases very complicated for a CISC architecture like x86.</p>
<p>A simpler solution is to use an <em>oracle</em>. An oracle is just another CPU or a simulator that we can use to check the result. If we compare the results from our test CPU to our oracle CPU, any mismatch would suggest that something went wrong.</p>
<p>I developed a new approach with a combination of these two ideas, I call it <em>Oracle Serialization</em>.</p>
</section>
<section id="oracle-serialization" class="level4">
<h4>Oracle Serialization</h4>
<p>As developers we monitor the <em>macro-architectural state</em>, that’s just things like register values. There is also the <em>micro-architectural state</em> which is mostly invisible to us, like the branch predictor, <a href="https://en.wikipedia.org/wiki/Out-of-order_execution">out-of-order execution</a> state and the instruction <a href="https://en.wikipedia.org/wiki/Instruction_pipelining">pipeline</a>.</p>
<p>Serialization lets us have <em>some</em> control over that, by instructing the CPU to reset <a href="https://en.wikipedia.org/wiki/Instruction-level_parallelism">instruction-level parallelism</a>. This includes things like store/load barriers, speculation fences, cache line flushes, and so on.</p>
<p>The idea of a Serialized Oracle is to generate a random program, then automatically transform it into a <a href="https://www.felixcloutier.com/x86/serialize#description">serialized</a> form.</p>
<hr>
<div class="noborder">
<table style="width:83%;">
<caption>A randomly generated sequence of instructions, and the same sequence but with randomized alignment, serialization and speculation fences added.</caption>
<colgroup>
<col style="width: 41%">
<col style="width: 41%">
</colgroup>
<tbody>
<tr class="odd">
<td style="text-align: left;"><code>movnti [rbp+0x0],ebx</code></td>
<td style="text-align: left;"><code>movnti [rbp+0x0],ebx</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">sfence</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>rcr dh,1</code></td>
<td style="text-align: left;"><code>rcr dh,1</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">lfence</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>sub r10, rax</code></td>
<td style="text-align: left;"><code>sub r10, rax</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">mfence</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>rol rbx, cl</code></td>
<td style="text-align: left;"><code>rol rbx, cl</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">nop</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>xor edi,[rbp-0x57]</code></td>
<td style="text-align: left;"><code>xor edi,[rbp-0x57]</code></td>
</tr>
</tbody>
</table>
</div>
<hr>
<p>These two program might have very different performance characteristics, but they should produce identical output. The serialized form can now be my oracle!</p>
<p>If the final states don’t match, then there must have been some error in how they were executed micro-architecturally - that could indicate a bug.</p>
<p>This is exactly how we first discovered this vulnerability, the output of the serialized oracle didn’t match!</p>
</section>
</section>
<section id="solution" class="level2">
<h2>Solution</h2>
<p>We reported this vulnerability to AMD on the 15th May 2023.</p>
<p>AMD have <a href="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/commit/?id=0bc3126c9cfa0b8c761483215c25382f831a7c6f">released</a> an microcode update for affected processors. Your BIOS or Operating System vendor may already have an update available that includes it.</p>
<section id="workaround" class="level4">
<h4>Workaround</h4>
<p>It is highly recommended to use the microcode update.</p>
<p>If you can’t apply the update for some reason, there is a software workaround: you can set the <a href="https://en.wiktionary.org/wiki/chicken_bit">chicken bit</a> <code>DE_CFG[9]</code>.</p>
<p>This may have some performance cost.</p>
<section id="linux" class="level5">
<h5>Linux</h5>
<p>You can use <code>msr-tools</code> to set the chicken bit on all cores, like this:</p>
<pre><code># wrmsr -a 0xc0011029 $(($(rdmsr -c 0xc0011029) | (1<<9)))</code></pre>
</section>
<section id="freebsd" class="level5">
<h5>FreeBSD</h5>
<p>On FreeBSD you would use <code>cpucontrol(8)</code>.</p>
</section>
<section id="others" class="level5">
<h5>Others</h5>
<p>If you’re using some other operating system and don’t know how to set <abbr title="Model Specific Registers">MSRs</abbr>, ask your vendor for assistance.</p>
<p>Note that it is <em>not</em> sufficient to disable <abbr title="Simultaneous
Multithreading">SMT</abbr>.</p>
</section>
</section>
<section id="detection" class="level4">
<h4>Detection</h4>
<p>I am not aware of any reliable techniques to detect exploitation. This is because no special system calls or privileges are required.</p>
<p>It is definitely <em>not</em> possible to detect improper usage of <code>vzeroupper</code> statically, please don’t try!</p>
</section>
</section>
<section id="conclusion" class="level2">
<h2>Conclusion</h2>
<p>It turns out that memory management is hard, even in silicon 🙂</p>
<section id="acknowledgements" class="level4">
<h4>Acknowledgements</h4>
<p>This bug was discovered by me, Tavis Ormandy from Google Information Security!</p>
<p>I couldn’t have found it without help from my colleagues, in particular Eduardo Vela Nava and Alexandra Sandulescu. I also had help analyzing the bug from Josh Eads.</p>
</section>
</section>
<section class="footnotes">
<hr>
<ol>
<li id="fn1"><p>You don’t need to set <code>ymm0</code> explicitly, all VEX encoded instructions that write to <code>xmm</code> automatically zero the upper part.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref1" class="footnote-back">↩</a></p></li>
<li id="fn2"><p>See Software Optimization Guide for AMD EPYC™ 7003 Processors, section 2.11.5.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref2" class="footnote-back">↩</a></p></li>
<li id="fn3"><p>See Software Optimization Guide for AMD EPYC™ 7003 Processors, section 2.11.5.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref3" class="footnote-back">↩</a></p></li>
<li id="fn4"><p>In fact, conditional branches are not necessary at all because of <a href="https://grsecurity.net/amd_branch_mispredictor_part_2_where_no_cpu_has_gone_before">SLS</a>.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref4" class="footnote-back">↩</a></p></li>
</ol>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/zenbleed.html</guid>
<link>https://lock.cmpxchg8b.com/zenbleed.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[George Lucas once sued someone over a spreadsheet.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Templates of Doom!</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: a07cf90837a3c4373b82d6724b97593810766af7 $</p>
</header>
<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>In the late 1980s there was - believe it or not - a popular monthly magazine dedicated to spreadsheets. It had a respectable eight year run, along with two companion books.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/lotus-magazine.png" alt="Lotus Magazines" referrerpolicy="no-referrer"><figcaption>Lotus Magazines</figcaption>
</figure>
<p>The entire <a href="https://archive.org/details/pub_lotus">back catalog</a> is on archive.org, although most issues were scanned from microfiche so there’s no color.</p>
<p>I’m interested in Lotus 1-2-3 history, so I’ve been slowly reading through back issues. It’s actually great, there are some really approachable articles on linear regression, forecasting, calculating bond yields, etc… mixed in with some retro computing news!</p>
<p>There’s also advice, tips, reviews, reader questions, and so on.</p>
<blockquote>
<h3 id="why-1-2-3">Why 1-2-3?</h3>
<p><small> I’m sometimes asked what it is I find appealing about Lotus 1-2-3. It’s from an era where there was an expectation that “powerful” software would be designed around keystroke macros. I think I just really appreciate that.</small></p><small>
<p>The moment that Vim first “clicked” for me is when I wrote my first macro. I suddenly understood why there is this huge selection of commands, and why that is so powerful.</p>
</small><p><small>In vim you can record a keystroke macro to a register called <code>x</code> with <code>qx</code>, then run it with <code>@x</code>. In 1-2-3 you can write a keystroke macro to a range called <code>\x</code>, and run it with <kbd>Alt</kbd>-<kbd>x</kbd>. Not so different! </small></p>
</blockquote>
</section>
<section id="lotus" class="level1">
<h1>Lotus</h1>
<p>I was reading the December 1987 issue and read <a href="https://archive.org/details/sim_lotus_1987-12_3_12/page/n147/mode/1up">this review</a> of “Templates of Doom”, a game written in Lotus macros! Hilarious, a real commercially released game you could actually buy for $69.95! Of course, I had to try it.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/templates-review.jpg" alt="Templates of Doom" referrerpolicy="no-referrer"><figcaption>Templates of Doom</figcaption>
</figure>
<p>As far as I can tell, the full game has not been archived anywhere, but I was able to find a demo version from an old shareware archive. It seems to work okay in the <a href="https://github.com/taviso/123elf">UNIX version</a> of 1-2-3.</p>
<p>I contacted the original author and asked him if he still had any old copies. He did, he had some old 5.25" disks but didn’t have any hardware to read them.</p>
<p>Well, I happen to know an <a href="https://scarybeastsecurity.blogspot.com/2021/05/recovering-lost-treasure-filled-floppy.html">expert in 5.25" disks</a>, and with his help I was able to get a disk image!</p>
</section>
<section id="history" class="level1">
<h1>History</h1>
<p>The package I got in the mail looked like this, but there was this page to stuck to the front that was peeling off.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/templatecover.gif" alt="Cover Peeling" referrerpolicy="no-referrer"><figcaption>Cover Peeling</figcaption>
</figure>
<p>The glue had deterioated after 30 years, but there was clearly something underneath…it was loose anyway, so I removed it revealing different cover art.</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/tdoom-secret-front.png" alt="Secret Artwork" style="width:45.0%" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/tdoom-front.png" alt="Normal Artwork" style="width:45.0%" referrerpolicy="no-referrer"></p>
</blockquote>
<p>It turns out that in December 1988 <a href="https://apnews.com/article/958f834f1ec23d92c83d5b0298b08a7e">Lucasfilm sued the author</a> over similarities to “Indiana Jones and the Temple of Doom”, and the author had to change the cover art to appease Lucas’s lawyers!</p>
</section>
<section id="gameplay" class="level1">
<h1>Gameplay</h1>
<p>So how does the game work! It’s a set of 24 puzzles that encourage you to learn how to use 1-2-3 features through problem solving.</p>
<p>You’re timed when you start each puzzle, and scored based on how long it took you to solve and how many hints you needed.</p>
<p>It has a <a href="https://en.wikipedia.org/wiki/Boss_key">boss key</a> (<kbd>Alt</kbd>+<kbd>B</kbd>) and a hint system (<kbd>Alt</kbd>+<kbd>H</kbd>). When you’ve solved the puzzle, you hit <kbd>Alt</kbd>+<kbd>A</kbd> and choose the right answer - if you win it takes you to the score screen.</p>
<p>If you want to see me solve one of the puzzles, there’s a <a href="https://www.youtube.com/watch?v=XdZlLiMUsdI">video</a> here.</p>
</section>
<section id="playing" class="level1">
<h1>Playing</h1>
<p>If you want to play this yourself…</p>
<ul>
<li>Install <a href="https://github.com/taviso/123elf">123elf</a>.</li>
<li>Set your global directory to where the game is, <code>/Worksheet Global Default Dir</code></li>
<li><code>/File Retrieve STARTPRG.WKS</code></li>
<li>You might get the error <code>File and/or extension converted</code>. This is just 1-2-3 informing you it translated something from DOS to UNIX. Just hit <kbd>Enter</kbd>.</li>
<li>When the file is loaded, press <kbd>Alt</kbd>+<kbd>S</kbd> to start.</li>
</ul>
<blockquote>
<h4 id="note">Note</h4>
<p>You don’t have to, but the game assumes you’re using 80x25 (the standard DOS resolution). Some cells you’re not supposed to see will be visible if you don’t change your terminal to match that.</p>
</blockquote>
<p>Now just follow the prompts!</p>
<ul>
<li>Remember to press <kbd>Alt</kbd>+<kbd>S</kbd> when a new level loads.</li>
</ul>
</section>
<section id="archive" class="level1">
<h1>Archive</h1>
<p>I’ve uploaded a <a href="https://archive.org/details/templatesdoom/">disk image and a scan of the manual</a> to archive.org.</p>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/doom.html</guid>
<link>https://lock.cmpxchg8b.com/doom.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I’m looking for a new wrist watch.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Quest for my perfect watch.</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: a07cf90837a3c4373b82d6724b97593810766af7 $</p>
</header>
<section id="intro" class="level1">
<h1>Intro</h1>
<figure>
<img src="https://lock.cmpxchg8b.com/img/prw-3100t.jpg" alt="Casio PRW-3100T" referrerpolicy="no-referrer"><figcaption>Casio PRW-3100T</figcaption>
</figure>
<p>I love my Casio Protrek watch, I won’t leave the house without it. I’ve owned it for years, as well as some earlier Protrek models. Those earlier models didn’t break — these watches are basically indestructible — I just liked them so much I went and bought the new revisions!</p>
<p>It has the standard digital watch features (alarms, timers, stopwatch, world time, calendar, backlight, etc), but this watch is really intended for hikers — it has an altimeter, barometer, thermometer and digital compass built in. I’m not outdoorsy — The only hiking I’ll do is to Starbucks — but I still love this watch. I think the reason is it’s reliable — I never worry that it won’t work.</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/prw-modes.png" alt="Watch Modes" referrerpolicy="no-referrer"> <font size="-2"> The standard watch modes displayed in the manual. <br> <font size="-4"> I think I’ve looked at the barometric pressure graph a total of two times over the years. It is pretty cool though, the theory is you can predict an upcoming weather change based on the direction the graph is trending. If the graph is flat, the current weather is likely to hold for a few hours. </font> </font></p>
</blockquote>
<p>Maybe you’re thinking “hah, unless the battery needs to be replaced” — wrong! The watch face is literally a solar panel, it sips so little power (we’re talking μamps) that a few cumulative minutes exposure to daylight is enough to keep the watch running for months.</p>
<p>I would be astonished if I woke up tomorrow and it wasn’t working, and it’s rare I can say that about any other tech I use. If an unattended update hosed my laptop, or an app update breaks my workflow — oh well, that’s par for the course. Sure, a digital watch is simple in comparison, but it’s nice to have something I can trust to do it’s job.</p>
<section id="smartwatch" class="level2">
<h2>Smartwatch</h2>
<p>Still, I am a nerd — and I hear the siren call of smartwatches. I think I would get frustrated quickly with an Android or iOS smartwatch, but is there some middle ground? A simple, reliable, programmable digital watch?</p>
<p>It doesn’t have to be zero-maintenance, I can tolerate annual battery replacements… but daily or weekly recharging and any dependence on online services really seems unbearable to me after years with my Casio.</p>
<p>The main feature I would like is some sort of sync capability. Ideally, I would like the alarms and <a href="https://dianne.skoll.ca/projects/remind/">reminders</a> from my UNIX <code>~/.reminders</code> file to appear on my watch, perhaps over RF or BLE. I don’t mind writing code to make this happen, so some customizability, automation or programmability is essential.</p>
<p>What options are there for someone like me?</p>
</section>
<section id="go-homebrew" class="level2">
<h2>Go Homebrew?</h2>
<p>There are a few homebrew smartwatches that appeal to me.</p>
<section id="sensorwatch" class="level3">
<h3>Sensorwatch</h3>
<p>Jose Castillo has built <a href="https://www.sensorwatch.net/">SensorWatch</a>, a fully programmable replacement board for the Casio F-91W watch.</p>
<p>This almost meets all my needs, it lasts a full year on a single battery and I could write an app to handle my reminders. The only issue is that sending data to the watch would be difficult once it’s assembled, as only the buttons can be used for input.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch.jpg" alt="Sensor Watch" referrerpolicy="no-referrer"><figcaption>Sensor Watch</figcaption>
</figure>
<p>There is an add-on board that adds GPIO pins, the idea is you can add your own additional sensors… if you can make them fit. This might be beyond my hardware skills, but perhaps exposing the pins externally to add some form of i2c might be good enough — at the expense of water resistance.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch-flexboard.jpg" alt="Sensor Watch Addon" referrerpolicy="no-referrer"><figcaption>Sensor Watch Addon</figcaption>
</figure>
<p>I could ask Jose how he would add sync, perhaps he knows of some small sensor like a magnetometer or IR photodiode that I could use to build a low-bandwidth communication channel.</p>
</section>
<section id="goodwatch" class="level3">
<h3>Goodwatch</h3>
<p>Travis Goodspeed (unfortunately for him, people sometimes confuse us because of our similar names!) has a very impressive project called <a href="https://github.com/travisgoodspeed/goodwatch">goodwatch</a> for amateur radio enthusiasts. It’s another board swap using the MSP430, but for a different Casio shell with far more inputs and a more capable segment display. Travis says a battery can last months, perhaps longer depending on usage. That’s a little lower than I would like, but it sounds tolerable.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/pocsag.jpg" alt="Goodwatch" referrerpolicy="no-referrer"><figcaption>Goodwatch</figcaption>
</figure>
<p>I don’t have much amateur radio knowledge, but it seems plausible I could add some low-bandwidth sync capability with a cheap <abbr title="Software Defined
Radio">SDR</abbr> dongle and a weekend hacking MSP340 assembly. I can absolutely imagine using this, although Travis is a notable hardware hacker and I can barely solder! Assembly looks a little more involved than the sensorwatch, so I worry this might be out of my league!</p>
</section>
</section>
<section id="go-hybrid" class="level2">
<h2>Go Hybrid?</h2>
<p><img src="https://lock.cmpxchg8b.com/img/sony-wena-pro.jpg" alt="Sony Wena Pro" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/wena3.jpg" alt="Sony Wena3" referrerpolicy="no-referrer"></p>
<p>There is an interesting Sony product line called Wena, primarily sold in the Japanese market. Wena is not a smartwatch, it’s a “smartband” that replaces the band on your existing watch. This seems moderately interesting, it needs regular recharging but degrades gracefully into a regular watch if the battery dies.</p>
<p>Of course, there is no built-in functionality to use it for what I want, but it seems totally plausible I could add it — decompiling the companion APK if necessary to figure out the API.</p>
<p>It is not cheap, and I would have to import one to the US. Frankly, <a href="https://www.wareable.com/smartwatches/sony-wena-wrist-pro-active-review-6982">online reviews</a> are not favourable at all — but as I would write my own software, I think I could make it work.</p>
<p>The |
Contributor
|
Successfully generated as following: http://localhost:1200/cmpxchg8b/articles - Success ✔️<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
>
<channel>
<title><![CDATA[cmpxchg8b]]></title>
<link>https://lock.cmpxchg8b.com/#articles</link>
<atom:link href="http://localhost:1200/cmpxchg8b/articles" rel="self" type="application/rss+xml" />
<description><![CDATA[cmpxchg8b - Made with love by RSSHub(https://github.com/DIYgod/RSSHub)]]></description>
<generator>RSSHub</generator>
<webMaster>[email protected] (DIYgod)</webMaster>
<language>zh-cn</language>
<lastBuildDate>Wed, 15 Nov 2023 15:52:05 GMT</lastBuildDate>
<ttl>5</ttl>
<item>
<title><![CDATA[What happens when a CPU goes wrong?]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Reptar</h1>
<p class="author">Tavis Ormandy</p>
</header>
<p>We have a CPU mystery! We found a way to cause some processors to enter a glitch state where the normal rules don’t apply, but what does that mean…?</p>
<p>If you’re interested what can go wrong inside modern CPUs, read on!</p>
<section id="introduction" class="level2">
<h2>Introduction</h2>
<p>If you’ve ever written any x86 assembly at all, you’ve probably used <code>rep movsb</code>. It’s the idiomatic way of moving memory around on x86. You set the <em>source</em>, <em>destination</em>, <em>direction</em> and the <em>count</em> - then just let the processor handle all the details!</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb1-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-1" aria-hidden="true"></a><span class="kw">lea</span> <span class="kw">rdi</span>, [rel dst]</span>
<span id="cb1-2"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-2" aria-hidden="true"></a><span class="kw">lea</span> <span class="kw">rsi</span>, [rel src]</span>
<span id="cb1-3"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-3" aria-hidden="true"></a><span class="kw">std</span></span>
<span id="cb1-4"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-4" aria-hidden="true"></a><span class="kw">mov</span> <span class="kw">rcx</span>, <span class="dv">32</span></span>
<span id="cb1-5"><a href="https://lock.cmpxchg8b.com/reptar.html#cb1-5" aria-hidden="true"></a>rep <span class="kw">movsb</span></span></code></pre></div>
<p>The actual instruction here is <code>movsb</code>, the <code>rep</code> is simply a prefix that changes how the instruction works. In this case, it indicates that you want this operation <strong>rep</strong>eated multiple times.</p>
<p>There are lots of other prefixes too, but they don’t all apply to every instruction.</p>
<section id="prefix-decoding" class="level4">
<h4>Prefix Decoding</h4>
<p>An interesting feature of x86 is that the instruction decoding is generally quite relaxed. If you use a prefix that doesn’t make sense or conflicts with other prefixes nothing much will happen, it will usually just be ignored.</p>
<p>This fact is sometimes useful; compilers can use redundant prefixes to pad a single instruction to a desirable alignment boundary.</p>
<p>Take a look at this snippet, this is exactly the same code as above, just a bunch of useless or redundant prefixes have been added:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb2-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-1" aria-hidden="true"></a> rep <span class="kw">lea</span> <span class="kw">rdi</span>, [rel dst]</span>
<span id="cb2-2"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-2" aria-hidden="true"></a> <span class="kw">cs</span> <span class="kw">lea</span> <span class="kw">rsi</span>, [rel src]</span>
<span id="cb2-3"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-3" aria-hidden="true"></a> <span class="kw">gs</span> <span class="kw">gs</span> <span class="kw">gs</span> <span class="kw">std</span></span>
<span id="cb2-4"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-4" aria-hidden="true"></a> repnz <span class="kw">mov</span> <span class="kw">rcx</span>, <span class="dv">32</span></span>
<span id="cb2-5"><a href="https://lock.cmpxchg8b.com/reptar.html#cb2-5" aria-hidden="true"></a>rep rep rep rep <span class="kw">movsb</span></span></code></pre></div>
<p>Perhaps the most interesting prefixes are <code>rex</code>, <code>vex</code> and <code>evex</code>, all of which change how subsequent instructions are decoded.</p>
<p>Let’s take a look at how they work.</p>
</section>
<section id="the-rex-prefix" class="level4">
<h4>The REX prefix</h4>
<p>The i386 only had 8 general purpose registers, so you could specify which register you want to use in just 3 bits (because 2^3 is 8).</p>
<p>The way that instructions were encoded took advantage of this fact, and reserved <em>just</em> enough bits to specify any of those registers.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/rep-modrm.svg" class="noborder" style="width:100.0%" alt="" referrerpolicy="no-referrer"><figcaption>modr/m example</figcaption>
</figure>
<p>Simple 2-byte instructions that use modr/m might be encoded like this, for example <code>mov eax, ebx</code>.</p>
<p>This is an 8-bit opcode, 2 bit addressing mode (labeled m), and 3 bits each for the source (s) and destination (d).</p>
</blockquote>
<p>Well, this is a problem, because x86-64 added 8 additional general purpose registers. We now have sixteen possible registers..that’s 2^4, so we’re going to need another bit! 😆</p>
<p>The solution to this is the <code>rex</code> prefix, which gives us some spare bits that the next instruction can borrow.</p>
<p>When we’re talking about rex, we usually write it like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb3-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb3-1" aria-hidden="true"></a>rex.rxb</span></code></pre></div>
<p><code>rex</code> is a single-byte prefix, the first four bits are mandatory and the remaining four bits called <code>b</code>, <code>x</code>, <code>r</code> and <code>w</code> are all optional. If you see <code>rex.rb</code> that means only the <code>r</code> and <code>b</code> bits are set, all the others are unset.</p>
<p>These optional bits give us room to encode more general purpose registers in the following instruction.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/rep-rexmodrm.svg" class="noborder" style="width:100.0%" alt="" referrerpolicy="no-referrer"><figcaption>rex example</figcaption>
</figure>
<p>The <code>rex</code> prefix can lend the next instruction extra bits to use for operands, so now we can encode all 16 possible general purpose registers!</p>
</blockquote>
<p>Now we’re fine until someone <a href="https://www.intel.com/content/www/us/en/developer/articles/technical/advanced-performance-extensions-apx.html">adds another register</a>! 😂</p>
</section>
<section id="encoding-rules" class="level4">
<h4>Encoding Rules</h4>
<p>So now we know that <code>rex</code> increases the available space for encoding operands, and that useless or redundant prefixes are usually ignored on x86. So… what should this instruction do?</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode nasm"><code class="sourceCode nasm"><span id="cb4-1"><a href="https://lock.cmpxchg8b.com/reptar.html#cb4-1" aria-hidden="true"></a>rex.rxb rep <span class="kw">movsb</span></span></code></pre></div>
<p>The <code>movsb</code> instruction doesn’t have any operands - they’re all implicit - so any <code>rex</code> bits are meaningless, right?</p>
<p>If you guessed that the processor will just silently ignore the <code>rex</code> prefix, you would be correct!</p>
<p>Well… except on machines that support a new feature called <em>fast short repeat move</em>! We discovered that a bug with redundant <code>rex</code> prefixes could interact with this feature in an unexpected way and introduce a serious vulnerability, oops 🙂</p>
</section>
<section id="fast-short-repeat-move" class="level4">
<h4>Fast Short Repeat Move</h4>
<p>FSRM is a new feature introduced in <a href="https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(client)#New_instructions">Ice Lake</a> that fixes some of the shortcomings of ERMS. Hopefully that clears up any confusion. 😆</p>
<p>Just kidding, let’s quickly look at ERMS.</p>
<p>The hard part of moving strings around efficiently is getting all the buffers aligned so you can use the widest possible stores available. You <em>could</em> do this in software, but if we do it in microcode then the processor can just transparently make your existing code faster for you.</p>
<p>This requires some expensive setup, but once that’s done you get vastly improved throughput. This feature is known as <em>enhanced repeat move/store</em>, ERMS.</p>
<p>If you have a processor with ERMS support, simple <code>rep movsb</code> operations can sometimes perform comparably with more complicated hand-tuned vector move operations.</p>
<p>However, there is a problem with ERMS. That initial setup is so expensive that it just isn’t worth it for very short strings. This is what FSRM is designed to solve, it handles the case of only moving 128 bytes or less and makes that faster too!</p>
<p>I’m not aware of any documentation that explains exactly how FSRM works, but you can check if you have a processor that supports it by looking at the flags line in <code>/proc/cpuinfo</code>:</p>
<pre><code>flags : fpu vme de pse tsc msr pae mce cx8 [...] fsrm</code></pre>
<p>Some of the processors that have this feature include:</p>
<ul>
<li>Ice Lake</li>
<li>Rocket Lake</li>
<li>Tiger Lake</li>
<li>Raptor Lake</li>
<li>Alder Lake</li>
<li>Sapphire Rapids</li>
</ul>
<blockquote>
<p>Note: This list may not be comprehensive, please see Intel advisory INTEL-SA-00950 for a complete list.</p>
</blockquote>
</section>
</section>
<section id="discovery" class="level2">
<h2>Discovery</h2>
<p>I’ve written previously about a processor validation technique called <em>Oracle Serialization</em> that we’ve been using. The idea is to generate two forms of the same randomly generated program and verify their final state is identical.</p>
<blockquote>
<p>You can read more about Oracle Serialization in my <a href="https://lock.cmpxchg8b.com/zenbleed.html">previous writeup</a>.</p>
</blockquote>
<p>In August, our validation pipeline produced an interesting assertion. It had found a case where adding redundant <code>rex.r</code> prefixes to an FSRM optimized <code>rep movs</code> operation seemed to cause unpredictable results.</p>
<p>We observed some very strange behavior while testing. For example, branches to unexpected locations, unconditional branches being ignored and the processor no longer accurately recording the instruction pointer in <code>xsave</code> or <code>call</code> instuctions.</p>
<p>Oddly, when trying to understand what was happening we would see a debugger reporting impossible states!</p>
<p>This already seemed like it could be indicative of a serious problem, but within a few days of experimenting we found that when multiple cores were triggering the same bug, the processor would begin to report machine check exceptions and halt.</p>
<p>We verified this worked even inside an unprivileged guest VM, so this already has serious security implications for cloud providers. Naturally, we reported this to Intel as soon as we confirmed this was a security issue.</p>
<section id="reproduce" class="level4">
<h4>Reproduce</h4>
<p>We’re publishing all of our research today to our <a href="https://github.com/google/security-research/tree/master/pocs/cpus/reptar">security research repository</a>. If you want to reproduce the vulnerability you can use our <code>icebreak</code> tool, I’ve also made a local mirror available <a href="https://lock.cmpxchg8b.com/files/icebreak.tar.gz">here</a>.</p>
<pre><code>$ ./icebreak -h
usage: ./icebreak [OPTIONS]
-c N,M Run repro threads on core N and M.
-d N Sleep N usecs between repro attempts.
-H N Spawn a hammer thread on core N.
icebreak: you must at least specify a core pair with -c! (see -h for help)</code></pre>
<p>The testcase enters what should be an infinite loop, and unaffected systems should see no output at all. On affected systems, a <code>.</code> is printed on each successful reproduction.</p>
<pre><code>$ ./icebreak -c 0,4
starting repro on cores 0 and 4
.........................................................................
.........................................................................
.........................................................................
.........................................................................
.........................................................................</code></pre>
<p>In general, if the cores are <abbr title="Symmetric Multithreading">SMT</abbr> siblings then you may observe random branches and if they’re <abbr title="Symmetric Multiprocessing">SMP</abbr> siblings from the same package then you may observe machine checks.</p>
<p>If you do <em>not</em> specify two different cores, then you might need to use a hammer thread to trigger a reproduction.</p>
</section>
<section id="analysis" class="level4">
<h4>Analysis</h4>
<p>We know something strange is happening, but how microcode works in modern systems is a closely guarded secret. We can only theorize about the root cause based on observations.</p>
<section id="μops" class="level5">
<h5>μops</h5>
<p>The CPU is split in two major components, the <em>frontend</em> and the <em>backend</em>. The frontend is responsible for fetching instructions, decoding them and generating μops to send to the backend for execution.</p>
<p>The backend executes instructions <em>out of order</em>, and uses a unit called the ROB, <em>reorder buffer</em>, to store and organize results.</p>
<p>We believe this bug causes the frontend to miscalculate the size of the <code>movsb</code> instruction, causing subsequent entries in the ROB to be associated with incorrect addresses. When this happens, the CPU enters a confused state that causes the instruction pointer to be miscalculated.</p>
<p>The machine can eventually recover from this state, perhaps with incorrect intermediate results, but becoming internally consistent again. However, if we cause multiple SMT or SMP cores to enter the state simultaneously, we can cause enough microarchitectural state corruption to force a machine check.</p>
</section>
</section>
<section id="questions" class="level4">
<h4>Questions</h4>
<p>I’m sure some readers will have questions about what is possible in this unexpected “glitch” state. Well, so do we!</p>
<p>We know that we can corrupt the system state badly enough to cause machine check errors, and we’ve also observed threads interfere with execution of processes scheduled on SMT siblings.</p>
<p>However, we simply don’t know if we can control the corruption precisely enough to achieve privilege escalation. I suspect that it <em>is</em> possible, but we don’t have any way to debug μop execution!</p>
<p>If you’re interested in studying this, then we would love to get your input!</p>
</section>
<section id="credit" class="level4">
<h4>Credit</h4>
<p>This bug was independently discovered by multiple research teams within Google, including the <a href="https://github.com/google/silifuzz">silifuzz</a> team and Google <a href="https://bughunters.google.com/blog">Information Security Engineering</a>. The bug was analyzed by Tavis Ormandy, Josh Eads, Eduardo Vela Nava, Alexandra Sandulescu and Daniel Moghimi.</p>
</section>
</section>
<section id="solution" class="level2">
<h2>Solution</h2>
<p>Intel have <a href="https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00950.html">published</a> updated microcode for all affected processors. Your operating system or BIOS vendor may already have an update available!</p>
<section id="workaround" class="level4">
<h4>Workaround</h4>
<p>If you can’t update for some reason, you <em>could</em> disable fast strings via the <code>IA32_MISC_ENABLE</code> model specific register.</p>
<p>This will cause a significant performance penalty, and should not be used unless absolutely necessary.</p>
</section>
</section>
<section id="notes" class="level2">
<h2>Notes</h2>
<p>If you’re interested in more CPU bugs, we publish everything we find!</p>
<p>Not all the bugs we discover have security consequences, but they’re usually worth reading! For example, did you know that sometimes <a href="https://github.com/google/security-research/tree/master/pocs/cpus/errata/amd/genoa-lps-hps">movlps just doesn’t work</a>? or that registers can sometimes <a href="https://github.com/google/security-research/tree/master/pocs/cpus/errata/amd/1386">roll back</a> to previous values?</p>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/reptar.html</guid>
<link>https://lock.cmpxchg8b.com/reptar.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[An overview of hacking the Timex m851.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Hacking the Timex m851</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: a07cf90837a3c4373b82d6724b97593810766af7 $</p>
</header>
<p><small> <em>This post is part of a series on my quest to find the perfect watch.</em> </small></p>
<section id="intro" class="level1">
<h1>Intro</h1>
<p><a href="https://lock.cmpxchg8b.com/img/datalink.jpg" title="Timex m851"><img src="https://lock.cmpxchg8b.com/img/datalink.jpg" alt="Timex m851" referrerpolicy="no-referrer"></a></p>
<p>Take a look at this watch, it’s just some boring watch for runners, right?</p>
<p>Nope, I think this might be the best ultra-low power consumer digital watch ever produced!</p>
<p>Let me explain…</p>
<section id="specifications" class="level4">
<h4>Specifications</h4>
<p>This is the Timex m851. It uses an 8-bit Seiko SC188 CPU, has 48KB of ROM, 2KB of RAM and a 42x11 dot matrix main display.</p>
<p>The cpu is designed for ultra-low power operation - a single battery can last 3 <em>years</em>!</p>
<p>This is a big selling point for me, I don’t think they’re making consumer watches like this any more.</p>
<p><img src="https://lock.cmpxchg8b.com/img/datalink-usb.jpg" alt="Timex USB" class="noclear" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/datalink-pins.jpg" alt="Timex USB" class="noclear" referrerpolicy="no-referrer"></p>
<p>Those pins on the side? That’s USB. Naturally, you can synchronize things like appointments, and so on (there’s a neat <a href="https://github.com/HuidaeCho/libdlusb">linux library</a> for that).</p>
<p>Here’s where it get’s interesting… this thing has an SDK, and it is <em>surprisingly</em> good!</p>
<p>You can just <code>$ cc helloworld.c</code>, and upload it to your watch.</p>
<p>I didn’t really think I would be enamored with this watch at first – the Windows XP-era wizard Timex provided for development was… <strong><em>painful</em></strong>. However, it turned out it was just driving a UNIX-like toolchain behind the scenes.</p>
<p>After pulling that out, hacking this started to become pretty fun!</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/datalink-make.gif" alt="Makefile" style="width:70.0%" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/watch.gif" alt="Hello World" style="width:20.0%" referrerpolicy="no-referrer"></p>
</blockquote>
</section>
</section>
<section id="watchapps" class="level1">
<h1>WatchApps</h1>
<p>Just want to see some code? No problem, I’ve uploaded a <em>hello world</em> and a <code>Makefile</code> to build it to github:</p>
<p><a href="https://github.com/taviso/timex/">https://github.com/taviso/timex/</a></p>
<p>If you want to browse the full manual, there are some links below.</p>
<p>You can do some fun things with this, people wrote all kinds of <a href="https://www.youtube.com/watch?v=mitJafrsimw">games</a>, <a href="http://datalinkwristapps.free.fr/index.php5?n=Wristapps.MyWatch">utilities</a>, and <a href="https://rayslogic.com/Software/TimexUSB/WristApps/WristApps.htm">tools</a>.</p>
<p>If you want a TL;DR of development, I’ll try!</p>
<section id="design" class="level4">
<h4>Design</h4>
<section id="states-and-modes" class="level5">
<h5>States and Modes</h5>
<p>You need to split your application into <em>states</em>.</p>
<p>A <em>state</em> is just a way to swap code in and out as needed. When you switch states, the active code is discarded and the new code is swapped in.</p>
<blockquote>
<p>You <em>could</em> write an app that uses up to ~30kb of code and/or data, <em>but</em> there is only ~2kb of RAM. This is why you need to use states, there is no paging and you couldn’t fit that in!</p>
</blockquote>
<p>There is room for some <em>common</em> code that all your states share, and of course there is space for variables, along with a database API for persistent data.</p>
<p>The first few states are reserved for handling common events. The rest you can use for anything you want - you just ask the kernel to switch you whenever you need it!</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb1-1" title="1"><span class="cf">if</span> (foo > bar) {</a>
<a class="sourceLine" id="cb1-2" title="2"> coreRequestStateChange(FOOBAR_STATE);</a>
<a class="sourceLine" id="cb1-3" title="3">}</a></code></pre></div>
<p>A <em>mode</em> is just a foreground application.</p>
<p>Your app is (probably) providing a mode, but you can also add background tasks, periodic tasks, and so on.</p>
<p>Requesting a mode change is sort of like <code>exit()</code>, the next app will gain control.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb2-1" title="1">coreRequestModeChangeNext();</a></code></pre></div>
</section>
<section id="events" class="level5">
<h5>Events</h5>
<p>Each state needs an event handler. A super simple one would be like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb3-1" title="1"><span class="dt">void</span> default_state_manager(<span class="dt">void</span>)</a>
<a class="sourceLine" id="cb3-2" title="2">{</a>
<a class="sourceLine" id="cb3-3" title="3"> <span class="cf">switch</span> (CORECurrentEvent) {</a>
<a class="sourceLine" id="cb3-4" title="4"> <span class="co">// This is called when this state becomes active.</span></a>
<a class="sourceLine" id="cb3-5" title="5"> <span class="cf">case</span> COREEVENT_STATEENTRY:</a>
<a class="sourceLine" id="cb3-6" title="6"> coreEnableSwitchReleaseEvents();</a>
<a class="sourceLine" id="cb3-7" title="7"> coreAllowKeys(COREALLOWALLSWITCHES);</a>
<a class="sourceLine" id="cb3-8" title="8"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-9" title="9"> <span class="co">// This is called when the user pulls the crown out.</span></a>
<a class="sourceLine" id="cb3-10" title="10"> <span class="co">// When they push it back in, you get a CROWN_HOME event.</span></a>
<a class="sourceLine" id="cb3-11" title="11"> <span class="co">// It can be rotated in either home or set positions.</span></a>
<a class="sourceLine" id="cb3-12" title="12"> <span class="cf">case</span> COREEVENT_CROWN_SET:</a>
<a class="sourceLine" id="cb3-13" title="13"> coreRequestStateChange(CORESETBANNERSTATE);</a>
<a class="sourceLine" id="cb3-14" title="14"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-15" title="15"> <span class="co">// You can get button events too, like start/split:</span></a>
<a class="sourceLine" id="cb3-16" title="16"> <span class="cf">case</span> COREEVENT_STARTSPLITDEPRESS:</a>
<a class="sourceLine" id="cb3-17" title="17"> show_message();</a>
<a class="sourceLine" id="cb3-18" title="18"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-19" title="19"> <span class="co">// The mode button probably means the user wants to exit...</span></a>
<a class="sourceLine" id="cb3-20" title="20"> <span class="cf">case</span> COREEVENT_MODEDEPRESS:</a>
<a class="sourceLine" id="cb3-21" title="21"> coreRequestModeChangeNext();</a>
<a class="sourceLine" id="cb3-22" title="22"> <span class="cf">break</span>;</a>
<a class="sourceLine" id="cb3-23" title="23"> }</a>
<a class="sourceLine" id="cb3-24" title="24"></a>
<a class="sourceLine" id="cb3-25" title="25"> <span class="cf">return</span>;</a>
<a class="sourceLine" id="cb3-26" title="26">}</a></code></pre></div>
<p>In general, you can ignore any event you don’t care about.</p>
</section>
<section id="services" class="level5">
<h5>Services</h5>
<p>The kernel takes care of handling the hardware, dispatching events to you and provides various services.</p>
<p>Things like timers, generating tones (beeps), scrolling the display, access to database records, etc.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb4-1" title="1"><span class="dt">uint8_t</span> banner[] = {</a>
<a class="sourceLine" id="cb4-2" title="2"> LCDBANNER_COL10,</a>
<a class="sourceLine" id="cb4-3" title="3"> DM5_H, DM5_E, DM5_L, DM5_L, DM5_O, DM5_EXCLAMATION,</a>
<a class="sourceLine" id="cb4-4" title="4"> LCD_END_BANNER</a>
<a class="sourceLine" id="cb4-5" title="5">};</a>
<a class="sourceLine" id="cb4-6" title="6"></a>
<a class="sourceLine" id="cb4-7" title="7">lcdClearDisplay();</a>
<a class="sourceLine" id="cb4-8" title="8"></a>
<a class="sourceLine" id="cb4-9" title="9"><span class="co">// Draw "hello!" using kernel services.</span></a>
<a class="sourceLine" id="cb4-10" title="10">lcdDispBannerMsg(&banner);</a></code></pre></div>
<p>The watch has a crown - and you can ask the kernel to configure it in a few different ways. For example, you might want pulse mode so you can monitor how quickly the user is turning it.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/crown.gif" alt="Crown Demo" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>Crown Demo</figcaption>
</figure>
</blockquote>
<p>It has a backlight, you can control that from software too.</p>
</section>
</section>
<section id="debugging" class="level4">
<h4>Debugging</h4>
<p>There’s no memory protection or anything, you can just clobber the kernel if you want… so what happens if you crash?</p>
<p>Well, one thing the kernel does is notify a watchdog every 2 seconds that it’s still alive. If the watchdog doesn’t see that notification, it will just reset the watch… so try not to do that! 😀</p>
<p>If you’re doing some heavy computation you could accidentally trigger the watchdog. Just remember to let the watchdog know you’re still alive:</p>
<pre><code> // Let the watchdog know we're not dead.
hwResetWatchdog();</code></pre>
<section id="simulator" class="level5">
<h5>Simulator</h5>
<p>Luckily there’s a really good simulator available, so you don’t have to sit through tedious resets everytime you make a typo. It’s actually an open source 3rd party tool, <a href="http://datalinkwristapps.free.fr/index.php5?n=PC.VirtualDatalink">Virtual Datalink</a> (<a href="https://sourceforge.net/projects/virtualdatalink/">source</a>).</p>
<blockquote>
<p>Sadly it’s for Windows only. I would port it to Linux, but it’s written in Delphi… is it feasible to port it to free pascal? Let me know!</p>
</blockquote>
<p>It has conditional breakpoints, a dissasembler, save states, resource and power analysis. I’ve found it pretty capable.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/vdatalink.gif" alt="Virtual Datalink" class="noborder" referrerpolicy="no-referrer"><figcaption>Virtual Datalink</figcaption>
</figure>
</blockquote>
</section>
</section>
</section>
<section id="conclusion" class="level1">
<h1>Conclusion</h1>
<p>The main app I’m working on right now is integrating my watch with <a href="https://dianne.skoll.ca/projects/remind/">remind</a>.</p>
<p>Hacking this little watch has been a super fun project!</p>
<section id="availability" class="level4">
<h4>Availability</h4>
<p>Now that I’ve told you how much I love this thing - the bad news.</p>
<p>They’re long out of production, and getting hard to come by.</p>
<p>I bought a set of two on eBay, they just needed new batteries and were as good as new.</p>
<p>If this is the sort of thing that appeals to you, setup an alert and then help me hack on it 😀</p>
</section>
<section id="references" class="level4">
<h4>References</h4>
<ul>
<li>The most important doc is the <a href="https://assets.timex.com/developer/developer_downloads/WA_Design_Guide.pdf">Design Guide</a>, it’s very well written.</li>
<li>Then of course, you need the <a href="https://www.rayslogic.com/Software/TimexUSB/Docs/s1c88%20core%20cpu%20manual.pdf">CPU manual</a>. It’s also excellent!</li>
<li>The toolchain also has a thorough manual.</li>
<li>Finally, the complete <a href="https://assets.timex.com/developer/developer_downloads/WA_API_Reference.pdf">API reference</a> lists the services provided by the Kernel.</li>
</ul>
</section>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/timex.html</guid>
<link>https://lock.cmpxchg8b.com/timex.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I found an interesting CPU bug.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Zenbleed</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: 7d85ef516b9682eaf0db09cc9c4e53a523486f3f $</p>
</header>
<p>If you remove the first word from the string <code>"hello world"</code>, what should the result be? This is the story of how we discovered that the answer could be your root password!</p>
<section id="introduction" class="level2">
<h2>Introduction</h2>
<p>All x86-64 CPUs have a set of 128-bit vector registers called the <code>XMM</code> registers. You can never have enough bits, so recent CPUs have extended the width of those registers up to 256-bit and even 512-bits.</p>
<p>The 256-bit extended registers are called <code>YMM</code>, and the 512-bit registers are <code>ZMM</code>.</p>
<p>These big registers are useful in lots of situations, not just number crunching! They’re even used by standard C library functions, like <code>strcmp</code>, <code>memcpy</code>, <code>strlen</code> and so on.</p>
<p>Let’s take a look at an example. Here are the first few instructions of glibc’s AVX2 optimized <code>strlen</code>:</p>
<pre><code>(gdb) x/20i __strlen_avx2
...
<__strlen_avx2+9>: vpxor xmm0,xmm0,xmm0
...
<__strlen_avx2+29>: vpcmpeqb ymm1,ymm0,YMMWORD PTR [rdi]
<__strlen_avx2+33>: vpmovmskb eax,ymm1
...
<__strlen_avx2+41>: tzcnt eax,eax
<__strlen_avx2+45>: vzeroupper
<__strlen_avx2+48>: ret</code></pre>
<p>The full routine is complicated and handles lots of cases, but let’s step through this simple case. Bear with me, I promise there’s a point!</p>
<p>The first step is to initialize <code>ymm0</code> to zero, which is done by just <code>xor</code>ing <code>xmm0</code> with itself<a href="https://lock.cmpxchg8b.com/zenbleed.html#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vpxor.svg" alt="VPXOR xmm0, xmm0, xmm0" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>VPXOR xmm0, xmm0, xmm0</figcaption>
</figure>
<pre><code> > vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Here <code>rdi</code> contains a pointer to our string, so <code>vpcmpeqb</code> will check which bytes in <code>ymm0</code> match our string, and stores the result in <code>ymm1</code>.</p>
<p>As we’ve already set <code>ymm0</code> to all zero bytes, only nul bytes will match.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vpcmpeqb.svg" alt="vpcmpeqb ymm1, ymm0, rdi" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>vpcmpeqb ymm1, ymm0, rdi</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
> vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Now we can extract the result into a general purpose register like <code>eax</code> with <code>vpmovmskb</code>.</p>
<p>Any nul byte will create a 1 bit, and any other value will create a 0 bit.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vpmovmskb.svg" alt="vpmovmskb eax, ymm1" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>vpmovmskb eax, ymm1</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
> vpmovmskb eax, ymm1
tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Finding the first zero byte is now just a case of counting the number of trailing zero bits.</p>
<p>That’s a common enough operation that there’s an instruction for it - <code>tzcnt</code> (Trailing Zero Count).</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-tzcnt.svg" alt="tzcnt eax, eax" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>tzcnt eax, eax</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
> tzcnt eax, eax
vzeroupper</code></pre>
</blockquote>
<p>Now we have the position of the first nul byte, in just four machine instructions!</p>
<p>You can probably imagine just how often <code>strlen</code> is running on your system right now, but suffice to say, bits and bytes are flowing into these vector registers from all over your system constantly.</p>
<section id="zeroing-registers" class="level4">
<h4>Zeroing Registers</h4>
<p>You might have noticed that I missed one instruction, and that’s <code>vzeroupper</code>.</p>
<blockquote>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-vzeroupper.svg" alt="vzeroupper" class="noborder" style="width:100.0%" referrerpolicy="no-referrer"><figcaption>vzeroupper</figcaption>
</figure>
<pre><code> vpxor xmm0, xmm0, xmm0
vpcmpeqb ymm1, ymm0, [rdi]
vpmovmskb eax, ymm1
tzcnt eax, eax
> vzeroupper</code></pre>
</blockquote>
<p>You guessed it, <code>vzeroupper</code> will zero the upper bits of the vector registers.</p>
<p>The reason we do this is because if you mix <code>XMM</code> and <code>YMM</code> registers, the <code>XMM</code> registers automatically get promoted to full width. It’s a bit like integer promotion in C.</p>
<p>This works fine, but <a href="https://en.wikipedia.org/wiki/Superscalar">superscalar</a> processors need to track dependencies so that they know which operations can be parallelized. This promotion adds a dependency on those upper bits, and that causes unnecessary stalls while the processor waits for results it didn’t really need.</p>
<p>These stalls are what glibc is trying to avoid with <code>vzeroupper</code>. Now any future results won’t depend on what those bits are, so we safely avoid that bottleneck!</p>
</section>
<section id="the-vector-register-file" class="level4">
<h4>The Vector Register File</h4>
<p>Now that we know <em>what</em> <code>vzeroupper</code> does, <em>how</em> does it do it?</p>
<p>Your processor doesn’t have a single physical location where each register lives, it has what’s called a <em><a href="https://en.wikipedia.org/wiki/Register_file">Register File</a></em> and a <em>Register Allocation Table</em>. This is a bit like managing the heap with <code>malloc</code> and <code>free</code>, if you think of each register as a pointer. The RAT keeps track of what space in the register file is assigned to which register.</p>
<p>In fact, when you zero an <code>XMM</code> register, the processor doesn’t store those bits anywhere at all - it just sets a flag called the <a href="https://en.wikichip.org/wiki/amd/microarchitectures/zen_2#Floating_Point_Unit">z-bit</a> in the RAT. This flag can be applied to the upper and lower parts of <code>YMM</code> registers independently, so <code>vzeroupper</code> can simply set the z-bit and then release any resources assigned to it in the register file.</p>
<figure>
<blockquote>
<img src="https://lock.cmpxchg8b.com/img/zb-zbit.svg" alt="Z-Bit" class="noborder" referrerpolicy="no-referrer">
<figcaption class="visible">
A register allocation table (left) and a physical register file (right).
</figcaption>
</blockquote>
</figure>
</section>
<section id="speculation" class="level4">
<h4>Speculation</h4>
<p>Hold on, there’s another complication! Modern processors use <a href="https://en.wikipedia.org/wiki/Speculative_execution">speculative execution</a>, so sometimes operations have to be rolled back.</p>
<p>What should happen if the processor <em>speculatively</em> executed a <code>vzeroupper</code>, but then discovers that there was a branch misprediction? Well, we will have to revert that operation and put things back the way they were… maybe we can just unset that z-bit?</p>
<p>If we return to the analogy of <code>malloc</code> and <code>free</code>, you can see that it can’t be that simple - that would be like calling <code>free()</code> on a pointer, and then changing your mind!</p>
<p>That would be a use-after-free vulnerability, but there is no such thing as a use-after-free in a CPU… or is there?</p>
<p>Spoiler: <strong><em>yes there is</em></strong> 🙂</p>
<figure>
<blockquote>
<img src="https://lock.cmpxchg8b.com/img/zb-leaking.gif" alt="Zenbleed Demo" class="noborder" referrerpolicy="no-referrer">
<figcaption class="visible">
This animation shows why resetting the z-bit is not sufficient.
</figcaption>
</blockquote>
</figure>
</section>
</section>
<section id="vulnerability" class="level2">
<h2>Vulnerability</h2>
<p>It turns out that with precise scheduling, you <em>can</em> cause some processors to recover from a mispredicted <code>vzeroupper</code> incorrectly!</p>
<p>This technique is CVE-2023-20593 and it works on all Zen 2 class processors, which includes at least the following products:</p>
<ul>
<li>AMD Ryzen 3000 Series Processors</li>
<li>AMD Ryzen PRO 3000 Series Processors</li>
<li>AMD Ryzen Threadripper 3000 Series Processors</li>
<li>AMD Ryzen 4000 Series Processors with Radeon Graphics</li>
<li>AMD Ryzen PRO 4000 Series Processors</li>
<li>AMD Ryzen 5000 Series Processors with Radeon Graphics</li>
<li>AMD Ryzen 7020 Series Processors with Radeon Graphics</li>
<li>AMD EPYC “Rome” Processors</li>
</ul>
<p>The bug works like this, first of all you need to trigger something called the <em>XMM Register Merge Optimization</em><a href="https://lock.cmpxchg8b.com/zenbleed.html#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>, followed by a <a href="https://en.wikipedia.org/wiki/Register_renaming">register rename</a> and a mispredicted <code>vzeroupper</code>. This all has to happen within a precise window to work.</p>
<p>We now know that basic operations like <code>strlen</code>, <code>memcpy</code> and <code>strcmp</code> will use the vector registers - so we can effectively spy on those operations happening anywhere on the system! It doesn’t matter if they’re happening in other virtual machines, sandboxes, containers, processes, whatever!</p>
<p>This works because the register file is shared by everything on the same physical core. In fact, two hyperthreads even share the same physical register file.</p>
<p>Don’t believe me? Let’s write an exploit 🙂</p>
</section>
<section id="exploitation" class="level2">
<h2>Exploitation</h2>
<p>There are quite a few ways to trigger this, but let’s examine a very simple example.</p>
<pre><code> vcvtsi2s{s,d} xmm, xmm, r64
vmovdqa ymm, ymm
jcc overzero
vzeroupper
overzero:
nop</code></pre>
<p>Here <code>cvtsi2sd</code> is used to trigger the merge optimization. It’s not important what <code>cvtsi2sd</code> is <em>supposed</em> to do, I’m just using it because it’s one of the instructions the manual says use that optimization<a href="https://lock.cmpxchg8b.com/zenbleed.html#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.</p>
<p>Then we need to trigger a <a href="https://en.wikipedia.org/wiki/Register_renaming">register rename</a>, <code>vmovdqa</code> will work. If the conditional branch<a href="https://lock.cmpxchg8b.com/zenbleed.html#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> is taken but the CPU predicts the not-taken path, the <code>vzeroupper</code> will be mispredicted and the bug occurs!</p>
<section id="optimization" class="level4">
<h4>Optimization</h4>
<figure>
<img src="https://lock.cmpxchg8b.com/img/zb-exploit.gif" alt="Exploit Running" class="noborder" referrerpolicy="no-referrer"><figcaption>Exploit Running</figcaption>
</figure>
<p>It turns out that mispredicting on purpose is difficult to optimize! It took a bit of work, but I found a variant that can leak about 30 kb per core, per second.</p>
<p>This is fast enough to monitor encryption keys and passwords as users login!</p>
<p>We’re releasing our full technical advisory, along with all the associated code today. Full details will be available in our <a href="https://github.com/google/security-research/tree/master/pocs/cpus">security research repository</a>.</p>
<p>If you want to test the exploit, the code is available <a href="https://lock.cmpxchg8b.com/files/zenbleed-v5.tar.gz">here</a>.</p>
<p>Note that the code is for Linux, but the bug is not dependent on any particular operating system - all operating systems are affected!</p>
</section>
</section>
<section id="discovery" class="level2">
<h2>Discovery</h2>
<p>I found this bug by fuzzing, big surprise 🙂 I’m not the first person to apply fuzzing techniques to finding hardware flaws. In fact, vendors fuzz their own products extensively - the industry term for it is <em>Post-Silicon Validation</em>.</p>
<p>So how come this bug wasn’t found earlier? I think I did a couple of things differently, perhaps with a new perspective as I don’t have an EE background!</p>
<section id="feedback" class="level4">
<h4>Feedback</h4>
<p>The best performing fuzzers are guided by coverage <a href="https://google.github.io/clusterfuzz/reference/coverage-guided-vs-blackbox/">feedback</a>. The problem is that there is nothing really analogous to code coverage in CPUs… However, we do have <a href="https://en.wikipedia.org/wiki/Hardware_performance_counter">performance counters</a>!</p>
<p>These will let us know when all kinds of <a href="https://perfmon-events.intel.com/skylake.html">interesting architectural events</a> happen.</p>
<p>Feeding this data to the fuzzer lets us gently guide it towards exploring interesting features that we wouldn’t have been able to find by chance alone!</p>
<p>It was challenging to get the details right, but I used this to teach my fuzzer to find interesting instruction sequences. This allowed me to discover features like merge optimization automatically, without any input from me!</p>
</section>
<section id="oracle" class="level4">
<h4>Oracle</h4>
<p>When we fuzz software, we’re usually looking for crashes. Software isn’t supposed to crash, so we know something must have gone wrong if it does.</p>
<p>How can we know if a a CPU is executing a randomly generated program correctly? It might be completely correct for it to crash!</p>
<p>Well, a few solutions have been proposed to this problem. One approach is called <a href="https://ieeexplore.ieee.org/abstract/document/4751878">reversi</a>. The general idea is that for every random instruction you generate, you also generate the inverse (e.g. <code>ADD r1, r2</code> → <code>SUB r1, r2</code>). Any deviation from the initial state at the end of execution must have been an error, neat!</p>
<p>The reversi approach is clever, but it makes generating testcases very complicated for a CISC architecture like x86.</p>
<p>A simpler solution is to use an <em>oracle</em>. An oracle is just another CPU or a simulator that we can use to check the result. If we compare the results from our test CPU to our oracle CPU, any mismatch would suggest that something went wrong.</p>
<p>I developed a new approach with a combination of these two ideas, I call it <em>Oracle Serialization</em>.</p>
</section>
<section id="oracle-serialization" class="level4">
<h4>Oracle Serialization</h4>
<p>As developers we monitor the <em>macro-architectural state</em>, that’s just things like register values. There is also the <em>micro-architectural state</em> which is mostly invisible to us, like the branch predictor, <a href="https://en.wikipedia.org/wiki/Out-of-order_execution">out-of-order execution</a> state and the instruction <a href="https://en.wikipedia.org/wiki/Instruction_pipelining">pipeline</a>.</p>
<p>Serialization lets us have <em>some</em> control over that, by instructing the CPU to reset <a href="https://en.wikipedia.org/wiki/Instruction-level_parallelism">instruction-level parallelism</a>. This includes things like store/load barriers, speculation fences, cache line flushes, and so on.</p>
<p>The idea of a Serialized Oracle is to generate a random program, then automatically transform it into a <a href="https://www.felixcloutier.com/x86/serialize#description">serialized</a> form.</p>
<hr>
<div class="noborder">
<table style="width:83%;">
<caption>A randomly generated sequence of instructions, and the same sequence but with randomized alignment, serialization and speculation fences added.</caption>
<colgroup>
<col style="width: 41%">
<col style="width: 41%">
</colgroup>
<tbody>
<tr class="odd">
<td style="text-align: left;"><code>movnti [rbp+0x0],ebx</code></td>
<td style="text-align: left;"><code>movnti [rbp+0x0],ebx</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">sfence</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>rcr dh,1</code></td>
<td style="text-align: left;"><code>rcr dh,1</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">lfence</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>sub r10, rax</code></td>
<td style="text-align: left;"><code>sub r10, rax</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">mfence</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>rol rbx, cl</code></td>
<td style="text-align: left;"><code>rol rbx, cl</code></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;"><code color="green">nop</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;"><code>xor edi,[rbp-0x57]</code></td>
<td style="text-align: left;"><code>xor edi,[rbp-0x57]</code></td>
</tr>
</tbody>
</table>
</div>
<hr>
<p>These two program might have very different performance characteristics, but they should produce identical output. The serialized form can now be my oracle!</p>
<p>If the final states don’t match, then there must have been some error in how they were executed micro-architecturally - that could indicate a bug.</p>
<p>This is exactly how we first discovered this vulnerability, the output of the serialized oracle didn’t match!</p>
</section>
</section>
<section id="solution" class="level2">
<h2>Solution</h2>
<p>We reported this vulnerability to AMD on the 15th May 2023.</p>
<p>AMD have <a href="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/commit/?id=0bc3126c9cfa0b8c761483215c25382f831a7c6f">released</a> an microcode update for affected processors. Your BIOS or Operating System vendor may already have an update available that includes it.</p>
<section id="workaround" class="level4">
<h4>Workaround</h4>
<p>It is highly recommended to use the microcode update.</p>
<p>If you can’t apply the update for some reason, there is a software workaround: you can set the <a href="https://en.wiktionary.org/wiki/chicken_bit">chicken bit</a> <code>DE_CFG[9]</code>.</p>
<p>This may have some performance cost.</p>
<section id="linux" class="level5">
<h5>Linux</h5>
<p>You can use <code>msr-tools</code> to set the chicken bit on all cores, like this:</p>
<pre><code># wrmsr -a 0xc0011029 $(($(rdmsr -c 0xc0011029) | (1<<9)))</code></pre>
</section>
<section id="freebsd" class="level5">
<h5>FreeBSD</h5>
<p>On FreeBSD you would use <code>cpucontrol(8)</code>.</p>
</section>
<section id="others" class="level5">
<h5>Others</h5>
<p>If you’re using some other operating system and don’t know how to set <abbr title="Model Specific Registers">MSRs</abbr>, ask your vendor for assistance.</p>
<p>Note that it is <em>not</em> sufficient to disable <abbr title="Simultaneous
Multithreading">SMT</abbr>.</p>
</section>
</section>
<section id="detection" class="level4">
<h4>Detection</h4>
<p>I am not aware of any reliable techniques to detect exploitation. This is because no special system calls or privileges are required.</p>
<p>It is definitely <em>not</em> possible to detect improper usage of <code>vzeroupper</code> statically, please don’t try!</p>
</section>
</section>
<section id="conclusion" class="level2">
<h2>Conclusion</h2>
<p>It turns out that memory management is hard, even in silicon 🙂</p>
<section id="acknowledgements" class="level4">
<h4>Acknowledgements</h4>
<p>This bug was discovered by me, Tavis Ormandy from Google Information Security!</p>
<p>I couldn’t have found it without help from my colleagues, in particular Eduardo Vela Nava and Alexandra Sandulescu. I also had help analyzing the bug from Josh Eads.</p>
</section>
</section>
<section class="footnotes">
<hr>
<ol>
<li id="fn1"><p>You don’t need to set <code>ymm0</code> explicitly, all VEX encoded instructions that write to <code>xmm</code> automatically zero the upper part.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref1" class="footnote-back">↩</a></p></li>
<li id="fn2"><p>See Software Optimization Guide for AMD EPYC™ 7003 Processors, section 2.11.5.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref2" class="footnote-back">↩</a></p></li>
<li id="fn3"><p>See Software Optimization Guide for AMD EPYC™ 7003 Processors, section 2.11.5.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref3" class="footnote-back">↩</a></p></li>
<li id="fn4"><p>In fact, conditional branches are not necessary at all because of <a href="https://grsecurity.net/amd_branch_mispredictor_part_2_where_no_cpu_has_gone_before">SLS</a>.<a href="https://lock.cmpxchg8b.com/zenbleed.html#fnref4" class="footnote-back">↩</a></p></li>
</ol>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/zenbleed.html</guid>
<link>https://lock.cmpxchg8b.com/zenbleed.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[George Lucas once sued someone over a spreadsheet.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Templates of Doom!</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: a07cf90837a3c4373b82d6724b97593810766af7 $</p>
</header>
<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>In the late 1980s there was - believe it or not - a popular monthly magazine dedicated to spreadsheets. It had a respectable eight year run, along with two companion books.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/lotus-magazine.png" alt="Lotus Magazines" referrerpolicy="no-referrer"><figcaption>Lotus Magazines</figcaption>
</figure>
<p>The entire <a href="https://archive.org/details/pub_lotus">back catalog</a> is on archive.org, although most issues were scanned from microfiche so there’s no color.</p>
<p>I’m interested in Lotus 1-2-3 history, so I’ve been slowly reading through back issues. It’s actually great, there are some really approachable articles on linear regression, forecasting, calculating bond yields, etc… mixed in with some retro computing news!</p>
<p>There’s also advice, tips, reviews, reader questions, and so on.</p>
<blockquote>
<h3 id="why-1-2-3">Why 1-2-3?</h3>
<p><small> I’m sometimes asked what it is I find appealing about Lotus 1-2-3. It’s from an era where there was an expectation that “powerful” software would be designed around keystroke macros. I think I just really appreciate that.</small></p><small>
<p>The moment that Vim first “clicked” for me is when I wrote my first macro. I suddenly understood why there is this huge selection of commands, and why that is so powerful.</p>
</small><p><small>In vim you can record a keystroke macro to a register called <code>x</code> with <code>qx</code>, then run it with <code>@x</code>. In 1-2-3 you can write a keystroke macro to a range called <code>\x</code>, and run it with <kbd>Alt</kbd>-<kbd>x</kbd>. Not so different! </small></p>
</blockquote>
</section>
<section id="lotus" class="level1">
<h1>Lotus</h1>
<p>I was reading the December 1987 issue and read <a href="https://archive.org/details/sim_lotus_1987-12_3_12/page/n147/mode/1up">this review</a> of “Templates of Doom”, a game written in Lotus macros! Hilarious, a real commercially released game you could actually buy for $69.95! Of course, I had to try it.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/templates-review.jpg" alt="Templates of Doom" referrerpolicy="no-referrer"><figcaption>Templates of Doom</figcaption>
</figure>
<p>As far as I can tell, the full game has not been archived anywhere, but I was able to find a demo version from an old shareware archive. It seems to work okay in the <a href="https://github.com/taviso/123elf">UNIX version</a> of 1-2-3.</p>
<p>I contacted the original author and asked him if he still had any old copies. He did, he had some old 5.25" disks but didn’t have any hardware to read them.</p>
<p>Well, I happen to know an <a href="https://scarybeastsecurity.blogspot.com/2021/05/recovering-lost-treasure-filled-floppy.html">expert in 5.25" disks</a>, and with his help I was able to get a disk image!</p>
</section>
<section id="history" class="level1">
<h1>History</h1>
<p>The package I got in the mail looked like this, but there was this page to stuck to the front that was peeling off.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/templatecover.gif" alt="Cover Peeling" referrerpolicy="no-referrer"><figcaption>Cover Peeling</figcaption>
</figure>
<p>The glue had deterioated after 30 years, but there was clearly something underneath…it was loose anyway, so I removed it revealing different cover art.</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/tdoom-secret-front.png" alt="Secret Artwork" style="width:45.0%" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/tdoom-front.png" alt="Normal Artwork" style="width:45.0%" referrerpolicy="no-referrer"></p>
</blockquote>
<p>It turns out that in December 1988 <a href="https://apnews.com/article/958f834f1ec23d92c83d5b0298b08a7e">Lucasfilm sued the author</a> over similarities to “Indiana Jones and the Temple of Doom”, and the author had to change the cover art to appease Lucas’s lawyers!</p>
</section>
<section id="gameplay" class="level1">
<h1>Gameplay</h1>
<p>So how does the game work! It’s a set of 24 puzzles that encourage you to learn how to use 1-2-3 features through problem solving.</p>
<p>You’re timed when you start each puzzle, and scored based on how long it took you to solve and how many hints you needed.</p>
<p>It has a <a href="https://en.wikipedia.org/wiki/Boss_key">boss key</a> (<kbd>Alt</kbd>+<kbd>B</kbd>) and a hint system (<kbd>Alt</kbd>+<kbd>H</kbd>). When you’ve solved the puzzle, you hit <kbd>Alt</kbd>+<kbd>A</kbd> and choose the right answer - if you win it takes you to the score screen.</p>
<p>If you want to see me solve one of the puzzles, there’s a <a href="https://www.youtube.com/watch?v=XdZlLiMUsdI">video</a> here.</p>
</section>
<section id="playing" class="level1">
<h1>Playing</h1>
<p>If you want to play this yourself…</p>
<ul>
<li>Install <a href="https://github.com/taviso/123elf">123elf</a>.</li>
<li>Set your global directory to where the game is, <code>/Worksheet Global Default Dir</code></li>
<li><code>/File Retrieve STARTPRG.WKS</code></li>
<li>You might get the error <code>File and/or extension converted</code>. This is just 1-2-3 informing you it translated something from DOS to UNIX. Just hit <kbd>Enter</kbd>.</li>
<li>When the file is loaded, press <kbd>Alt</kbd>+<kbd>S</kbd> to start.</li>
</ul>
<blockquote>
<h4 id="note">Note</h4>
<p>You don’t have to, but the game assumes you’re using 80x25 (the standard DOS resolution). Some cells you’re not supposed to see will be visible if you don’t change your terminal to match that.</p>
</blockquote>
<p>Now just follow the prompts!</p>
<ul>
<li>Remember to press <kbd>Alt</kbd>+<kbd>S</kbd> when a new level loads.</li>
</ul>
</section>
<section id="archive" class="level1">
<h1>Archive</h1>
<p>I’ve uploaded a <a href="https://archive.org/details/templatesdoom/">disk image and a scan of the manual</a> to archive.org.</p>
</section>
]]></description>
<guid isPermaLink="false">https://lock.cmpxchg8b.com/doom.html</guid>
<link>https://lock.cmpxchg8b.com/doom.html</link>
<author><![CDATA[Tavis Ormandy]]></author>
</item>
<item>
<title><![CDATA[I’m looking for a new wrist watch.]]></title>
<description><![CDATA[<header id="title-block-header">
<h1 class="title">Quest for my perfect watch.</h1>
<p class="author">Tavis Ormandy</p>
<p class="date">$Id: a07cf90837a3c4373b82d6724b97593810766af7 $</p>
</header>
<section id="intro" class="level1">
<h1>Intro</h1>
<figure>
<img src="https://lock.cmpxchg8b.com/img/prw-3100t.jpg" alt="Casio PRW-3100T" referrerpolicy="no-referrer"><figcaption>Casio PRW-3100T</figcaption>
</figure>
<p>I love my Casio Protrek watch, I won’t leave the house without it. I’ve owned it for years, as well as some earlier Protrek models. Those earlier models didn’t break — these watches are basically indestructible — I just liked them so much I went and bought the new revisions!</p>
<p>It has the standard digital watch features (alarms, timers, stopwatch, world time, calendar, backlight, etc), but this watch is really intended for hikers — it has an altimeter, barometer, thermometer and digital compass built in. I’m not outdoorsy — The only hiking I’ll do is to Starbucks — but I still love this watch. I think the reason is it’s reliable — I never worry that it won’t work.</p>
<blockquote>
<p><img src="https://lock.cmpxchg8b.com/img/prw-modes.png" alt="Watch Modes" referrerpolicy="no-referrer"> <font size="-2"> The standard watch modes displayed in the manual. <br> <font size="-4"> I think I’ve looked at the barometric pressure graph a total of two times over the years. It is pretty cool though, the theory is you can predict an upcoming weather change based on the direction the graph is trending. If the graph is flat, the current weather is likely to hold for a few hours. </font> </font></p>
</blockquote>
<p>Maybe you’re thinking “hah, unless the battery needs to be replaced” — wrong! The watch face is literally a solar panel, it sips so little power (we’re talking μamps) that a few cumulative minutes exposure to daylight is enough to keep the watch running for months.</p>
<p>I would be astonished if I woke up tomorrow and it wasn’t working, and it’s rare I can say that about any other tech I use. If an unattended update hosed my laptop, or an app update breaks my workflow — oh well, that’s par for the course. Sure, a digital watch is simple in comparison, but it’s nice to have something I can trust to do it’s job.</p>
<section id="smartwatch" class="level2">
<h2>Smartwatch</h2>
<p>Still, I am a nerd — and I hear the siren call of smartwatches. I think I would get frustrated quickly with an Android or iOS smartwatch, but is there some middle ground? A simple, reliable, programmable digital watch?</p>
<p>It doesn’t have to be zero-maintenance, I can tolerate annual battery replacements… but daily or weekly recharging and any dependence on online services really seems unbearable to me after years with my Casio.</p>
<p>The main feature I would like is some sort of sync capability. Ideally, I would like the alarms and <a href="https://dianne.skoll.ca/projects/remind/">reminders</a> from my UNIX <code>~/.reminders</code> file to appear on my watch, perhaps over RF or BLE. I don’t mind writing code to make this happen, so some customizability, automation or programmability is essential.</p>
<p>What options are there for someone like me?</p>
</section>
<section id="go-homebrew" class="level2">
<h2>Go Homebrew?</h2>
<p>There are a few homebrew smartwatches that appeal to me.</p>
<section id="sensorwatch" class="level3">
<h3>Sensorwatch</h3>
<p>Jose Castillo has built <a href="https://www.sensorwatch.net/">SensorWatch</a>, a fully programmable replacement board for the Casio F-91W watch.</p>
<p>This almost meets all my needs, it lasts a full year on a single battery and I could write an app to handle my reminders. The only issue is that sending data to the watch would be difficult once it’s assembled, as only the buttons can be used for input.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch.jpg" alt="Sensor Watch" referrerpolicy="no-referrer"><figcaption>Sensor Watch</figcaption>
</figure>
<p>There is an add-on board that adds GPIO pins, the idea is you can add your own additional sensors… if you can make them fit. This might be beyond my hardware skills, but perhaps exposing the pins externally to add some form of i2c might be good enough — at the expense of water resistance.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/sensor-watch-flexboard.jpg" alt="Sensor Watch Addon" referrerpolicy="no-referrer"><figcaption>Sensor Watch Addon</figcaption>
</figure>
<p>I could ask Jose how he would add sync, perhaps he knows of some small sensor like a magnetometer or IR photodiode that I could use to build a low-bandwidth communication channel.</p>
</section>
<section id="goodwatch" class="level3">
<h3>Goodwatch</h3>
<p>Travis Goodspeed (unfortunately for him, people sometimes confuse us because of our similar names!) has a very impressive project called <a href="https://github.com/travisgoodspeed/goodwatch">goodwatch</a> for amateur radio enthusiasts. It’s another board swap using the MSP430, but for a different Casio shell with far more inputs and a more capable segment display. Travis says a battery can last months, perhaps longer depending on usage. That’s a little lower than I would like, but it sounds tolerable.</p>
<figure>
<img src="https://lock.cmpxchg8b.com/img/pocsag.jpg" alt="Goodwatch" referrerpolicy="no-referrer"><figcaption>Goodwatch</figcaption>
</figure>
<p>I don’t have much amateur radio knowledge, but it seems plausible I could add some low-bandwidth sync capability with a cheap <abbr title="Software Defined
Radio">SDR</abbr> dongle and a weekend hacking MSP340 assembly. I can absolutely imagine using this, although Travis is a notable hardware hacker and I can barely solder! Assembly looks a little more involved than the sensorwatch, so I worry this might be out of my league!</p>
</section>
</section>
<section id="go-hybrid" class="level2">
<h2>Go Hybrid?</h2>
<p><img src="https://lock.cmpxchg8b.com/img/sony-wena-pro.jpg" alt="Sony Wena Pro" referrerpolicy="no-referrer"> <img src="https://lock.cmpxchg8b.com/img/wena3.jpg" alt="Sony Wena3" referrerpolicy="no-referrer"></p>
<p>There is an interesting Sony product line called Wena, primarily sold in the Japanese market. Wena is not a smartwatch, it’s a “smartband” that replaces the band on your existing watch. This seems moderately interesting, it needs regular recharging but degrades gracefully into a regular watch if the battery dies.</p>
<p>Of course, there is no built-in functionality to use it for what I want, but it seems totally plausible I could add it — decompiling the companion APK if necessary to figure out the API.</p>
<p>It is not cheap, and I would have to import one to the US. Frankly, <a href="https://www.wareable.com/smartwatches/sony-wena-wrist-pro-active-review-6982">online reviews</a> are not favourable at all — but as I would write my own software, I think I could make it work.</p>
<p>The |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Involved Issue / 该 PR 相关 Issue
Close #
Example for the Proposed Route(s) / 路由地址示例
New RSS Route Checklist / 新 RSS 路由检查表
PuppeteerNote / 说明