10 interesting stories served every morning and every evening.

Gmail Thinks I'm Stupid, So I Left

moddedbear.com

Let me tell you a story

I go to check my email in Gmail’s web UI. I see a few new mes­sages re­gard­ing feed­back on a pro­ject I’m work­ing on. I click through to read one of them and the first thing I’m greeted with is a mes­sage sum­mary I did­n’t ask for gen­er­ated by a lan­guage model.

I fo­cus the mes­sage box to draft a re­ply, but there’s al­ready one there. It was also gen­er­ated by the lan­guage model. I delete it, re­plac­ing it with my own.

Afterward, I go to com­pose a new mes­sage. A col­or­ful an­i­ma­tion steals my fo­cus for a sec­ond high­light­ing a new help me write” but­ton. I ig­nore it and move on to fill­ing in the re­cip­i­ents and sub­ject line.

I fo­cus the mes­sage body area and un­der­neath my cur­sor ap­pears the mes­sage Press / for Help me write”. Again, I ig­nore it and be­gin writ­ing.

A few mo­ments later, I start a new para­graph and pause. There’s a new mes­sage un­der my cur­sor now: Tab to im­prove”. What I’ve writ­ten so far is­n’t up to Gmail’s stan­dards, it seems.

What mes­sage are you try­ing to send?

Look, I’m pretty prag­matic when it comes to gen­er­a­tive AI fea­tures in soft­ware. I see very lit­tle wrong with in­clud­ing an op­tional AI writ­ing as­sis­tant for those who want it.

But when you nag and nag, when you sum­ma­rize my mes­sages and write my replies with­out my ask­ing, when you re­peat­edly in­ter­rupt me to beg and plead that I rewrite my drafts, you’re send­ing the wrong mes­sage.

The mes­sage you’re send­ing is that you think I’m not ca­pa­ble of read­ing and writ­ing my own emails. That the peo­ple I’m ex­chang­ing mes­sages with don’t de­serve my time and en­ergy. That I’m do­ing some­thing wrong by not out­sourc­ing my com­mu­ni­ca­tion skills to a to­ken pre­dic­tion ma­chine.

I’ve looked into it. Some of these fea­tures can be turned off. Others can’t. Or if they can, it means also turn­ing off use­ful long-stand­ing fea­tures like au­to­matic thread cat­e­go­riza­tion. I have very lit­tle doubt that this is in­ten­tional, that the un­so­licited sum­maries and auto replies are a means of ar­ti­fi­cially in­flat­ing the us­age met­rics for the lan­guage model fea­tures.

I think we’re all used to user-hos­tile soft­ware these days, but this is the first time I’ve ex­pe­ri­enced soft­ware that feels like it’s ac­tively try­ing to be dis­re­spect­ful. Sure, I could switch to a dif­fer­ent mail client and never see any of these lan­guage model fea­tures, but my ex­pe­ri­ence these past months has left such a bad taste that all I’m look­ing for now is a clean break.

A 16 year breakup

I’ve had my Gmail ac­count for 16 years. It’s by far my old­est in­ter­net ac­count that I still use. Or used to use. I’ve al­ready started the long process of mov­ing away.

This time I’m do­ing things the right way by con­nect­ing my own do­main to a mail host. I’m cur­rently with Fastmail since they were by far the most pop­u­lar op­tion when I asked for sug­ges­tions on the fe­di­verse. I’m still early on in the trial pe­riod, but so far first im­pres­sions are great. It seems re­ally flex­i­ble, and af­ter con­nect­ing mul­ti­ple do­mains and set­ting up a few aliases I’m start­ing to wish I had tried it sooner.

I haven’t set­tled on whether or not I should im­port my Gmail data. I’ll al­most surely im­port my con­tacts, but there’s some­thing nice about start­ing fresh as far as every­thing else goes. I’m in­ter­ested in what other peo­ple in a sim­i­lar po­si­tion have done.

Congrats to Google, re­ally. They’ve done a de­cent job at keep­ing Gmail sta­ble over the many years I’ve used it. Which is why even I am im­pressed by how quickly they were able to get me to pack up and leave.

JP

1-Click GitHub Token Stealing via a VSCode Bug

blog.ammaraskar.com

Just by click­ing a link, it’s pos­si­ble for an at­tacker to steal a GitHub to­ken that can read and write to your re­pos, in­clud­ing pri­vate ones.

Table of Contents

Background

VSCode Webview Security Model

The Bug

The Bug

PoC and Protecting Yourself

What VSCode Did Well

Why Full Disclosure

Timeline

Background

Did you know GitHub has this re­ally cool fea­ture called github.dev?

On any repos­i­tory you have ac­cess to, if you can change the url from github.com to github.dev or you click this lit­tle menu item:

You’ll be launched into a lit­tle light-weight ver­sion of VSCode that runs en­tirely in your browser (I guess that’s one ad­van­tage of hav­ing your app writ­ten with elec­tron).

This browser in­stance of VSCode is pretty pow­er­ful, you can view all the files in the repo (even if it’s a pri­vate one), you can send out pull re­quests and even make com­mits.

This func­tion­al­ity is achieved by github.com POSTing over an OAuth to­ken to github.dev that al­lows it to in­ter­act with GitHub on your be­half. The to­ken is not scoped to the par­tic­u­lar repo you in­ter­acted with, mean­ing it has full ac­cess to every other repo that you have ac­cess to.

The pres­ence of this to­ken and the fact that this web-app is run­ning al­most the en­tire brunt of VSCode’s mil­lion line Typescript code­base makes it a great tar­get for any­one look­ing into VSCode bugs. That sort of bug is what we’ll ex­plore here and show how an at­tacker can use it to ex­fil­trate your GitHub to­ken.

VSCode Webview Security Model

Being an elec­tron app on the desk­top, ex­e­cut­ing ar­bi­trary Javascript in­side of VSCode would be tan­ta­mount to full re­mote code ex­e­cu­tion. This is why VSCode im­ple­ments some sand­box­ing ap­proaches, the one we’ll fo­cus on here is VSCode’s we­b­views.

Webviews use an <iframe> with a dif­fer­ent ori­gin to the main VSCode win­dow to en­sure that any JavaScript ex­e­cuted in­side of them is fully iso­lated. These we­b­views are used for fea­tures such as Markdown pre­views or edit­ing Jupyter note­books:

The out­put of the cell is ren­dered into an <iframe> from the ori­gin vs­code-we­b­view://…, as op­posed to the main elec­tron win­dow which has the ori­gin vs­code-file://…. This means that even if the Jupyter note­book uses the built-in fea­tures of dis­play­ing HTML or us­ing Javascript for in­ter­ac­tive wid­gets, the ac­tual core VScode ap­pli­ca­tion is pro­tected from it. One can­not use Electron’s in­te­gra­tion with Node.js APIs in­side this iframe or call into VSCode’s APIs from this frame.

Great, that gives us the abil­ity to ren­der con­tent, but just sta­tic con­tent is bor­ing. How do we im­ple­ment fea­tures like hav­ing the Markdown pre­view show you which source line you cur­rently have high­lighted or up­dat­ing the pre­view live as we edit it?

The same cross-ori­gin pol­icy that gives us se­cu­rity also pre­vents our main ed­i­tor win­dow from in­ter­act­ing with the DOM in the vs­code-we­b­view://… frame. After all, you would­n’t want some­one who used an <iframe src=“google.com”> to be able to in­ter­act with the google page to steal your cook­ies or change that web­site’s be­hav­ior.

> doc­u­ment.getEle­ments­By­Tag­Name(‘iframe’)[0].con­tentWin­dow.find­Ele­ment­ById(‘foo’) Uncaught SecurityError: Failed to read a named prop­erty findElementById’ from Window’: Blocked a frame with ori­gin vscode-file://vscode-app” from ac­cess­ing a cross-ori­gin frame.

The only way to al­low this be­hav­ior is to have the two web pages in the dif­fer­ent ori­gins co­op­er­ate with each other us­ing the Window.postMessage() API. This method al­lows send­ing JavaScript ob­jects across the dif­fer­ent win­dows. So in that ex­am­ple of show­ing which ren­dered Markdown line cor­re­sponds to what ed­i­tor line, the main ed­i­tor win­dow posts a lit­tle mes­sage like this:

{ type: onDidChangeTextEditorSelection”, line: 31 }

and then the cor­re­spond­ing code run­ning in­side of the we­b­view has a lis­tener for this mes­sage that adds the high­light:

win­dow.ad­dE­ventLis­tener(‘mes­sage’, async event => { const data = event.data as ToWebviewMessage.Type; switch (data.type) { … case onDidChangeTextEditorSelection’: marker.on­Did­Change­TextE­d­i­torS­e­lec­tion(data.line, doc­u­mentVer­sion); re­turn;

Note: VSCode in the browser uses a sim­i­lar sand­box­ing model. VSCode de­vel­oper Matt Bierner has a great blog­post about the chal­lenges of port­ing it over from Electron worth check­ing out.

Note: VSCode in the browser uses a sim­i­lar sand­box­ing model. VSCode de­vel­oper Matt Bierner has a great blog­post about the chal­lenges of port­ing it over from Electron worth check­ing out.

The Bug

So our se­cu­rity bound­ary for we­b­views roughly looks like this:

but in terms of UI, our we­b­view sits right here in the win­dow. People ex­pect ba­sic things like click­ing links, drag and or press­ing Ctrl+F to work in­side of them:

Hence, VSCode im­ple­ments a bunch of ba­sic func­tion­al­ity through the mes­sage pass­ing mech­a­nism to en­able these fea­tures. Speaking of key­board short­cuts, the as­tute reader who has dealt with <iframe>s may have al­ready picked up on the is­sue.

As with most things cross-ori­gin, the browser of­fers a good amount of iso­la­tion be­tween the two frames. If you had a page on hack­er­man.com and you iframed google.com/​lo­gin, you would not want the hack­er­man page to be able to at­tach a key­board lis­tener onto the iframe. That would let them see all your key­strokes on google.com, al­low­ing them snoop your pass­word.

Okay given that in­for­ma­tion, try click­ing in­side a VSCode we­b­view and then press­ing Ctrl+Shift+P to bring up the com­mand palette.

Oh yay, that works. Wait. Oh. Oh no. So, to avoid the ter­ri­ble user ex­pe­ri­ence of your key­board short­cuts not work­ing when you hap­pen to be clicked in­side of a we­b­view, the de­fault set of we­b­view mes­sage han­dlers have an event called did-key­down. When you load a we­b­view, the fol­low­ing code runs in­side the we­b­view to reg­is­ter a han­dler for it:

con­tentWin­dow.ad­dE­ventLis­tener(‘key­down’, han­dleIn­nerKey­down);

/** * @param {KeyboardEvent} e */ const han­dleIn­nerKey­down = (e) => { // … hostMes­sag­ing.postMes­sage(‘did-key­down’, { key: e.key, key­Code: e.key­Code, code: e.code, shiftKey: e.shiftKey, al­tKey: e.al­tKey, ctr­lKey: e.ctr­lKey, metaKey: e.metaKey, re­peat: e.re­peat }); };

How con­ve­nient, so we­b­views just bub­ble up key­down events so the main VSCode win­dow can treat them seam­lessly as user key­board events.

But…there’s noth­ing pre­vent­ing our script run­ning in the un­trusted web view from pre­tend­ing like it’s the user and press­ing a bunch of keys on their be­half.

We could, say, bring up the com­mand palette and start run­ning dan­ger­ous com­mands such as in­stalling an at­tacker-con­trolled ex­ten­sion. All we’d need is a bit of javascript that emits the cor­rect events to sim­u­late the key­strokes…

Ctrl+Shift+P

de­vel­oper: in­stall ex­ten­sion from lo­ca­tion

Enter

<attacker con­trolled ex­ten­sion>

Enter

In re­al­ity it’s not quite that sim­ple. While we can cer­tainly send the key­down events cor­re­spond­ing to that se­quence, the browser will not treat it as if it’s the user typ­ing it in. So VSCode will pop up the com­mand palette but un­less VScode is in­ter­cept­ing all key­down events to han­dle each char­ac­ter be­ing typed man­u­ally, our events will not ac­tu­ally type text into the palette. Unfortunately, in this case here, it is not lis­ten­ing to key­down events, the com­mand palette wid­get just uses an HTML <input> tag.

We can scroll up and down in the com­mand palette if we emit up-ar­row ↑, down-ar­row ↓ presses and can press Enter to se­lect com­mands but ar­bi­trary key­strokes are off the table.

Luckily, VSCode comes with a mas­sive set of de­fault key­board short­cuts, all of which lis­ten di­rectly on key­down that we can try to make use of. After a bunch of tin­ker­ing, the eas­i­est way I found is to make use of the Notifications: Accept Notification Primary Action” ac­tion. This de­fault key­bind of Ctrl+Shift+A will hit the pri­mary but­ton on what­ever no­ti­fi­ca­tion popped up last in VSCode.

Which no­ti­fi­ca­tion are we ac­cept­ing?

VSCode has this fea­ture where your work­space can rec­om­mend ex­ten­sions by putting them in a file called .vscode/extensions.json that looks some­thing like

{ recommendations”: [ HackerMan.my-malicious-extension” ] }

And then we can use Ctrl+Shift+A to ac­cept that no­ti­fi­ca­tion and in­stall the ma­li­cious ex­ten­sion giv­ing us full code ex­e­cu­tion? Shrimple as?

Again, not quite, VSCode as of 1.97 has this new pub­lisher trust sys­tem whereby in­stalling an ex­ten­sion from a new pub­lisher for the first time gives you this di­a­log, even if we hit the Install but­ton in that no­ti­fi­ca­tion:

While we can send Tab key presses to nav­i­gate the but­tons here, press­ing Enter on the Trust Publisher & Install but­ton is im­pos­si­ble as it lis­tens for key­down events specif­i­cally on the but­ton and not the en­tire win­dow.

Instead, we can make use of an­other VSCode fea­ture called lo­cal work­space ex­ten­sions. As long as you are in­side of a trusted work­space (which github.dev/​web work­spaces al­ways are), then it’s pos­si­ble to in­stall an ex­ten­sion di­rectly pre­sent in .vscode/extensions. Extensions in­stalled in this way skip the trusted pub­lisher check with the trusted work­space check act­ing as the trust check. So now we can just put our evil pay­load in .vscode/extensions/extension.js and ex­e­cute our own code, right?

Well al­most, do­ing this causes a Content Security Policy (CSP) er­ror be­cause the ex­ten­sion worker that loads ex­ten­sions is ex­pect­ing them to be from vs­code-cdn.net. Local work­space ex­ten­sions prob­a­bly weren’t well tested with the web ver­sion of VSCode.

This is just a small hic­cup though, one of the things that ex­ten­sions can do as part of their pack­age.json is to con­tribute ex­tra key­bind­ings to VSCode. Since we can re­li­ably trig­ger key­bind­ings, we can just add a key­bind for whatver VSCode com­mand we want. Such as…in­stalling an ex­ten­sion while skip­ping the trusted pub­lisher check. So our pack­age.json ends up look­ing like this to call into work­bench.ex­ten­sions.in­stallEx­ten­sion while skip­ping the pub­lisher trust check.

contributes”: { keybindings”: [ { key”: ctrl+f1″, command”: runCommands”, args”: { commands”: [ { command”: workbench.extensions.installExtension”, args”: [ AmmarTest.hello-ammar-github”, { donotSync”: true, context”: { skipPublisherTrust”: true } } ] } ] } } ] }

To put it all to­gether, what we need is a repo with a Jupyter note­book and a lo­cal work­space ex­ten­sion. The Jupyter note­book needs to ex­e­cute a lit­tle bit of Javascript which we can do with a mark­down cell con­tain­ing the fol­low­ing:

<img src=“data:foo­bar” on­error=“javascript(); goes(); here();“>

For our Javascript pay­load, we need to do the fol­low­ing:

Wait a lit­tle bit for VSCode to pop-up ask­ing us if we want to in­stall the rec­om­mended ex­ten­sions.

Emit a key­down event for Ctrl+Shift+A to ac­cept the no­ti­fi­ca­tion.

Wait a lit­tle bit for the ex­ten­sion to in­stall and ac­tive, putting in our cus­tom key­bind.

Emit a key­down event for Ctrl+F1 trig­ger­ing the in­stal­la­tion of our cho­sen ex­ten­sion.

This pay­load ends up look­ing like:

// Wait for VSCode to load and pop open the no­ti­fi­ca­tion. await sleep(10 * 1000);

// ctrl+shift+a, ac­cept the pri­mary no­ti­fi­ca­tion ask­ing if we want to in­stall // the rec­om­mended ex­ten­sion win­dow.dis­patchEvent( new KeyboardEvent(“keydown”, {key: a”, code: KeyA”, key­Code: 65, ctr­lKey: true, shiftKey: true}) ); // Wait a lit­tle for the ex­ten­sion to in­stall… await sleep(500);

// ctrl+f1, the cus­tom key­bind to in­stall the cho­sen ex­ten­sion. win­dow.dis­patchEvent( new KeyboardEvent(“keydown”, {key: F1″, code: F1, key­Code: 112, ctr­lKey: true}) );

PoC and Protecting Yourself

Now that we’ve seen the de­tails, let’s take a look at the proof-of-con­cept. For the bravest among you, go ahead and just di­rectly click:

https://​github.dev/​am­maraskar/​github-dev-to­ken-steal-poc/​blob/​main/​README.ipynb

This will launch the github.dev ed­i­tor di­rectly to the note­book. You’ll see a lit­tle sta­tus mes­sage of what the Javascript pay­load is do­ing.

Once the pay­load runs, the newly in­stalled ex­ten­sion will grab your GitHub API to­ken and then query https://​api.github.com/​user/​re­pos to get pri­vate re­pos you have ac­cess to. It then prints them out and your to­ken in a lit­tle in­for­ma­tion box.

The code for both the re­pos used is here:

Installed ex­ten­sion: https://​github.com/​am­maraskar/​vs­code-github-to­ken-grab-ex­ten­sion/​blob/​main/​src/​ex­ten­sion.ts

Notebook JS: https://​github.com/​am­maraskar/​github-dev-to­ken-steal-poc/​blame/​main/​README.ipynb

If you run the PoC, re­mem­ber to ei­ther clear your github.dev data (see be­low) or at the very least unin­stall the proof-of-con­cept ex­ten­sion oth­er­wise it will fol­low you on all github.dev pages.

This vul­ner­a­bil­ity also ex­ists in the desk­top ver­sion of VSCode, though it’s a bit harder to ex­ploit since you would need to con­vince the vic­tim to clone your repo and open the note­book with the we­b­view script pay­load. Of course, if you had some other XSS in a we­b­view that you can get a vic­tim to open, you get ef­fec­tively full RCE on their com­puter.

Protecting Yourself

By a stroke of luck, if you have never used github.dev in the past, there is one di­a­log to click through when land­ing on the web­site. This did­n’t used to hap­pen be­fore but some chang­ing of VSCode’s GitHub plu­g­ins has caused this.

This means that if you clear your cook­ies and lo­cal site data for github.dev, you can take ac­tion and nav­i­gate away from the page if some­one tries to use this at­tack on you. I strongly rec­om­mend you clear site data for github.dev, in Chrome this can be done by click­ing the lit­tle icon in the URL bar, click­ing Cookies and site data > Manage on-de­vice site data.

and then delet­ing data for all the do­mains with the trash can icons:

Unfortunately, if you’ve ever been past that di­a­log on github.dev and haven’t cleared your browser’s lo­cal stor­age, you’re com­pletely screwed. There are no CSRF to­kens or any­thing for github.dev so any link on the in­ter­net can redi­rect you to this at­tack.

What VSCode Did Well

VSCode’s ap­proach of not just solely re­ly­ing on the <iframe> but us­ing de­fense-in-depth se­cu­rity mea­sures like a strict Content Security Policy and us­ing DOMPurify for ren­dered mark­down pays div­i­dends here. If there was a way to ex­e­cute ar­bi­trary Javascript in­side the Markdown pre­view shown on an ex­ten­sion’s page, you can imag­ine how this vul­ner­a­bil­ity could have even more im­pact (1-click RCE on desk­top by link­ing some­one your ex­ten­sion). However, by us­ing script-src none’ this is ef­fec­tively nipped in the bud.

Why Full Disclosure?

To sum­ma­rize the last time I in­ter­acted with MSRC re­gard­ing re­port­ing a VSCode bug, it was a hor­ri­ble ex­pe­ri­ence where they silently fixed the bug I pointed out with­out any credit. They also marked it as not hav­ing any se­cu­rity im­pact. As I men­tioned in that post, go­ing for­ward I would be do­ing full pub­lic dis­clo­sure for any se­cu­rity bugs I found in VSCode. Taking a look at a re­cent re­port by Starlabs on a VSCode XSS bug marked as in­el­i­gi­ble and low sever­ity, it does­n’t look like MSRC has got­ten any bet­ter about VSCode bugs.

I’m sure the VSCode team would have ap­pre­ci­ated a longer heads up on this to come up with so­lu­tions. There is le­git­i­mately a UI/UX bal­ance here that needs to be struck with the se­cu­rity con­cerns. To those folks, I am sorry, but this is one of the few levers I have to try to in­flu­ence MSRC and the se­cu­rity pos­ture of VSCode. Finding and fully de­vel­op­ing se­cu­rity bugs into proof-of-con­cepts like this takes time and ef­fort on the part of se­cu­rity re­searchers that should not be dis­re­spected or taken for granted.

Timeline

Jun 2, 2026 - An hour be­fore post­ing I gave a heads up to an old con­tact at GitHub se­cu­rity that I would be dis­clos­ing this bug.

Jun 2, 2026 - I dis­closed the bug here and on the VSCode is­sue tracker.

Jun 3, 2026 - Microsoft ap­plies a stop­gap fix by adding a con­fir­ma­tion when open­ing note­books in web VSCode and not al­low­ing trusted pub­lisher to be skipped by com­mands.

MAI-Code-1-Flash

microsoft.ai

The lat­est break­throughs and up­dates from within our team

Turn noisy au­dio into pre­cise, do­main-spe­cific tran­scripts, with lead­ing FLEURS and Artificial Analysis ac­cu­racy scores.

Create stun­ning, de­sign-ready im­ages from any text or photo prompt, with best-in-class Arena ELO scores at a lower price.

Helps your en­gi­neer­ing team write bet­ter code faster, with a light­weight, agen­tic model built into GitHub Copilot and VS Code.

Built for the com­plex prob­lems that mat­ter most, with com­pet­i­tive rea­son­ing and top SWE-Bench Pro re­sults at a mid-weight price.

The lat­est break­throughs and up­dates from within our team

Turn noisy au­dio into pre­cise, do­main-spe­cific tran­scripts, with lead­ing FLEURS and Artificial Analysis ac­cu­racy scores.

Create stun­ning, de­sign-ready im­ages from any text or photo prompt, with best-in-class Arena ELO scores at a lower price.

Helps your en­gi­neer­ing team write bet­ter code faster, with a light­weight, agen­tic model built into GitHub Copilot and VS Code.

Built for the com­plex prob­lems that mat­ter most, with com­pet­i­tive rea­son­ing and top SWE-Bench Pro re­sults at a mid-weight price.

MAI-Code-1-Flash plans and rea­sons through com­plex cod­ing tasks from start to fin­ish, so you spend less time de­bug­ging and more time build­ing.

Takes ini­tia­tive across multi-step work­flows, mak­ing de­ci­sions and adapt­ing au­tonomously with­out wait­ing for in­put.

Optimized for GitHub Copilot in VS Code

Custom-trained for na­tive VS Code in­te­gra­tion, work­ing bet­ter to­gether with GitHub Copilot.

From strat­egy to shipped code, keep every pro­ject mov­ing for­ward.

Coming Soon to VS Code

Introducing MAI-Code-1-Flash  | Microsoft AI

microsoft.ai

Build for de­vel­op­ers, not bench­marks

Coding mod­els are most use­ful when they per­form well in the same en­vi­ron­ment de­vel­op­ers use every day. That is why we built MAI-Code-1-Flash with pro­duc­tion work­flows at the cen­ter, rather than op­ti­miz­ing only for bench­marks. The model was trained di­rectly with GitHub Copilot har­nesses used in pro­duc­tion. This al­lows it to learn how to in­ter­act with sur­round­ing tools and sys­tems in agen­tic cod­ing tasks, mak­ing it uniquely well suited to real-world Copilot work­flows com­pared to other avail­able mod­els.

During train­ing, we eval­u­ated check­points across core soft­ware en­gi­neer­ing tasks, repos­i­tory ques­tion an­swer­ing, refac­tor­ing, and teleme­try-grounded tasks adapted from real GitHub Copilot us­age. This align­ment be­tween train­ing, eval­u­a­tion, and pro­duc­tion helps of­fline im­prove­ments trans­late into real-world de­vel­oper qual­ity.

Designed to max­i­mize value per to­ken

MAI-Code-1-Flash was trained with adap­tive so­lu­tion length con­trol, which helps the model ad­just the depth of its re­sponse to the task. It can stay con­cise for sim­pler re­quests and spend more rea­son­ing bud­get when a prob­lem re­quires deeper analy­sis or broader code changes. In prac­tice, this means de­vel­op­ers start see­ing use­ful out­put sooner. We see MAI-Code-1-Flash solv­ing harder prob­lems with up to 60% fewer to­kens. This helps re­duce la­tency, lower cost, im­prove re­turn on to­ken, and make in­ter­ac­tive work­flows feel smoother.

Benchmark re­sults in the pro­duc­tion har­ness

To un­der­stand both qual­ity and ef­fi­ciency, we eval­u­ated MAI-Code-1-Flash against Claude Haiku 4.5 on SWE-Bench Verified, SWE-Bench Pro, SWE-Bench Multilingual, and Terminal Bench 2 us­ing the same pro­duc­tion har­ness that de­vel­op­ers use for their every­day cod­ing tasks. We mea­sured task suc­cess and the av­er­age num­ber of so­lu­tion to­kens re­quired to com­plete each task.

MAI-Code-1-Flash out­per­forms Claude Haiku 4.5 across all core cod­ing bench­marks tested, with higher pass rates on all 4 eval­u­a­tions, in­clud­ing a +16-point lead on the di­verse, real-world tasks of SWE-Bench Pro (51.2% vs. 35.2%). It’s not just smarter; it’s leaner, solv­ing harder prob­lems with up to 60% fewer to­kens on SWE-Bench Verified, prov­ing that higher ac­cu­racy and greater ef­fi­ciency are no longer a trade-off.

BYD

www.lumafield.com

Design to Reality

Evolution of the Plastic Bottle

In the dark nights of my soul, I fret about how in­con­sis­tently en­gi­neered my life is. The cof­fee table I made a year or two ago was in­tended to look like the din­ing room table I built a few years ear­lier, but in re­al­ity the two bear only a vague re­sem­blance to each other. Open a drawer of my tool chest at ran­dom, and per­haps you’ll find a the­mat­i­cally-aligned col­lec­tion of well-loved hand tools, metic­u­lously cut into a nest of Kaizen foam, or maybe you’ll find a ran­dom as­sort­ment of half-for­got­ten spe­cialty wrenches. My book­shelf is nicely sorted and stacked, but my mag­a­zines are dumped into a bas­ket this way and that. We man­age to in­vest em­bar­rass­ing amounts of en­gi­neer­ing and in­fra­struc­ture into phys­i­cal ob­jects that are barely worth men­tion­ing. So when I look out at the world out­side of my own home, I am re­as­sured to find that even our most dis­pos­able ob­jects are the re­sult of stag­ger­ing quan­ti­ties of se­ri­ous and earnest en­gi­neer­ing work. You’ve got to give it to hu­man­ity: We don’t just put all of our de­sign cy­cles on the big, im­pres­sive pro­jects—pyra­mids, bridges, and semi­con­duc­tor fabs. No: We man­age to in­vest em­bar­rass­ing amounts of en­gi­neer­ing and in­fra­struc­ture into phys­i­cal ob­jects that are barely worth men­tion­ing. Stuffed an­i­mals, given away as car­ni­val prizes, are the ben­e­fi­cia­ries of un­told lo­gis­ti­cal and sup­ply-chain man­age­ment ef­forts. A pair of panty­hose might con­tain ma­te­ri­als that re­quired eight or nine fig­ures’ worth of R&D work to de­velop. A plas­tic wa­ter bot­tle, whose en­tire us­able lifes­pan is mea­sured in sec­onds, is the re­sult of decades upon decades of en­gi­neer­ing across a range of func­tions. From glass to plas­tic I stand up, put on my shoes, and walk over to the gro­cery store. The walk to the gro­cery store takes maybe 120 sec­onds, and I walk it about once a day. I rec­og­nize that this is ab­surdly fre­quent and revel in treat­ing the gro­cery store as an ex­ten­sion of my pantry. Today, I get ketchup and crack­ers then scoot around to the dairy aisle for un­salted but­ter. Walking past the bot­tled wa­ter I pause—the se­lec­tion there is hon­estly in­cred­i­ble, a lit­tle Darwinian com­pe­ti­tion play­ing out on the shelves. I stand there, reg­is­ter­ing the dif­fer­ent phe­no­types and think­ing about how each species and sub-species of wa­ter bot­tle evolved. A guy in his thir­ties reaches in front of me to grab a gal­lon-sized jug of Poland Spring from the shelf. I make room for him, con­sider my op­tions, and for some rea­son end up with a liter each of Pellegrino, Evian, and Smartwater. As weird as it sounds, wa­ter from the Evian source was bot­tled in earth­en­ware jugs from 1826 all the way un­til 1908. Glass and glass­blow­ing were not all that re­li­able in the belly of the nine­teenth cen­tury, but around the turn of the twen­ti­eth, glass tech­nol­ogy had trick­led down from lenses and light­bulbs to pro­lif­er­ate within bev­er­age pack­ag­ing. If you were start­ing a bot­tling com­pany in 1900, you prob­a­bly started in glass. Coca-Cola was first bot­tled (in glass) in 1899, the same year that Pellegrino, with their dis­tinc­tive green glass bot­tle, was founded. Evian switched to glass in 1908. Coke’s acry­loni­trile mis­ad­ven­ture While syn­thetic plas­tics were first de­vel­oped in the 1880s, and Dustin Hoffman was get­ting lec­tured about the ma­te­ri­al’s busi­ness po­ten­tial in 1967, it was­n’t un­til the mid-’70s that food-safe (or at least vaguely food-com­pat­i­ble) for­mu­la­tions be­gan to roll out. One of the most no­table of these was acry­loni­trile copoly­mer, which was brought to mar­ket in the form of Coca-Cola’s Easy-Goer” bot­tle in 1975. Coke’s acry­loni­trile bot­tles lasted less than two years on the mar­ket. From an en­gi­neer­ing per­spec­tive, acry­loni­trile copoly­mer was a great fit for soda bot­tles. It was trans­par­ent, tough, and im­per­vi­ous to gas. Coca-Cola ex­ec­u­tives touted its environmental ad­van­tages” (namely its lower shipped weight) and its re­sis­tance to biodegra­da­tion, claim­ing that the bot­tles, which were man­u­fac­tured by Monsanto, would cost essentially the same as glass.” Pepsi, who had also been work­ing on plas­tic bot­tles, fumed on the side­lines. While Coke was camped out at a ho­tel launch­ing the Easy-Goer, Pepsi held a com­pet­ing PR event, down the hall at the same ho­tel, to un­veil a cham­pagne from the Soviet Union.” The short ca­reer (1975 – 1977) of Coke’s Monsanto-designed Easy-Goer acry­loni­trile bot­tle. This au­thor was un­able to de­fin­i­tively iden­tify im­agery of Pepsi’s Soviet cham­pagne, but this state-owned Russian site seems to in­di­cate it was Nazdorovya. The Easy-Goer bot­tles were, to my taste, a bit on the chunky side. Coke’s acry­loni­trile bot­tles lasted less than two years on the mar­ket. It turns out acry­loni­trile bot­tles will leach acry­loni­trile into what­ever liq­uids they con­tain; fur­ther­more, test an­i­mals who were fed large amounts of acry­loni­trile in their drink­ing wa­ter” de­vel­oped significantly lower body weight and other ad­verse ef­fects, in­clud­ing le­sions in the cen­tral ner­vous sys­tem and growths in the ear ducts.” The FDA banned acry­loni­trile bev­er­age con­tain­ers in March of 1977; Monsanto sued and lost; Coke looked to other ma­te­ri­als. Injection Stretch Blow Molding (ISBM) Here’s how most plas­tic bev­er­age bot­tles are made to­day: A bot­tle pre­form, also known as a pari­son, is typ­i­cally in­jec­tion-molded out of PET. The pre­form looks kind of like a test tube, with threads at its mouth and a disc-like col­lar just be­low. Its walls are thick. Maybe it’s stored for a while, still de­void of cap, but even­tu­ally it’s in­stalled onto a stretch blow mold­ing ma­chine where it’s heated, stretched length­wise in­ter­nally with a metal rod, and in­jected with com­pressed air, blow­ing up rapidly like a bal­loon be­fore be­ing cooled and spat out. The same pre­form might be blown into a va­ri­ety of dif­fer­ent bot­tle de­signs, each with dif­fer­ent vol­umes and wall thick­nesses and de­sign de­tails, but their thread pro­files and necks will re­main iden­ti­cal to the pre­form from which they were made. Coke’s Easy-Goers had metal caps, but to­day vir­tu­ally all plas­tic bot­tles are also capped in plas­tic. Plastic caps are in­jec­tion or com­pres­sion molded, with their tam­per-ev­i­dent rings at­tached. The in­jec­tion molds are hon­estly beau­ti­ful—pol­ished, multi-part as­sem­blies, with twelve or twenty-four or forty-eight caps all be­ing molded at the same time. Watching caps be­ing com­pres­sion molded, mean­while, is mes­mer­iz­ing: semi-soft blobs of plas­tic goop be­ing ex­truded, cut, and squished into a ro­tat­ing tool that then dumps a fin­ished cap as­sem­bly off of its back­side. Either way, when caps meet their bot­tles the bot­tles will have been filled with some fluid, and in some cases pres­sur­ized with car­bon diox­ide gas (for that bub­bly siz­zle) or liq­uid ni­tro­gen (for struc­tural and preser­v­a­tive rea­sons). This all hap­pens at stag­ger­ingly high speed, dozens of bot­tles per sec­ond, tens of thou­sands of bot­tles per hour, frankly un­fath­omable num­bers of bot­tles per day. Injection stretch blow mold­ing forms bot­tles in two stages: a heated PET pre­form is stretched and blown in­side a mold, align­ing the poly­mer chains to cre­ate a light­weight con­tainer with high strength and clar­ity. The rise of PET Again, I’m struck by the stu­pidly ob­vi­ous fact that hu­man be­ings in­vented all of this stuff. Real peo­ple, with dreams and fears and fam­i­lies to sup­port, spent big chunks of their lives in­vent­ing not only the bev­er­age pack­ag­ing it­self but the ma­chin­ery re­quired to make, fill, cap, and pack­age these un­fath­omable num­bers of bot­tles. Disposable wa­ter bot­tle en­gi­neer­ing is a ca­reer path that you could choose, and if you did choose it then you would not be alone in hav­ing done so. While Monsanto had been toil­ing away on their yet-un­proven acry­loni­trile copoly­mer bot­tles, there was an en­tirely dif­fer­ent group, at DuPont, work­ing on poly­eth­yl­ene tereph­tha­late. Even more in­cred­i­ble is the fact that some of Dustin Hoffman’s con­tem­po­raries—in­deed lots of them—chose ca­reers in plas­tic bot­tle en­gi­neer­ing, even be­fore plas­tic bot­tles had been proven vi­able. While Monsanto had been toil­ing away on their yet-un­proven acry­loni­trile copoly­mer bot­tles, there was an en­tirely dif­fer­ent group, at DuPont, work­ing on poly­eth­yl­ene tereph­tha­late. Polyethylene Terephthalate, PET.” So many eth­yl­enes! Take a bunch of gaseous eth­yl­ene mol­e­cules, and cat­alyze them with metal salts such that they form long, cater­pil­lar-like solid mol­e­cules, with each seg­ment con­tain­ing one car­bon atom and two hy­dro­gen atoms. In this form, bulk poly­eth­yl­ene can be in­cred­i­bly strong and durable, es­pe­cially when the cater­pil­lar-like mol­e­cules get re­ally long. (Ultra-high-molecular-weight poly­eth­yl­ene, whose chained-to­gether eth­yl­enes can be hun­dreds of thou­sands of units long, has yield strengths com­pa­ra­ble to steel—at dra­mat­i­cally lower den­si­ties. Lots of high-end sail­ing rig­ging is made from this stuff, and also ul­tra­light camp­ing gear.) Polyethylene is also en­vi­ron­men­tally sta­ble, op­ti­cally clear, and does­n’t, like acry­loni­trile, leach into food or bev­er­ages that it’s put into con­tact with. People have been cat­alyz­ing poly­eth­yl­ene this way for about 75 years now, and be­cause of its re­mark­able phys­i­cal prop­er­ties, we now make more of the stuff than any other poly­mer; to­day, global an­nual poly­eth­yl­ene pro­duc­tion is some­thing on the or­der of a hun­dred mil­lion met­ric tons—equiv­a­lent in mass to al­most eight years’ worth of New York City’s solid trash pro­duc­tion. Within two years of the Easy-Goer’s down­fall, DuPont was in full pro­duc­tion, mak­ing two-liter PET bot­tles for the Coca-Cola com­pa­ny’s caramel-col­ored sugar wa­ter. I can just imag­ine the ex­cite­ment at DuPont’s poly­eth­yl­ene team when the FDA put an end to Coke’s acry­loni­trile ad­ven­tures. DuPont had been work­ing on soda bot­tles since at least 1967, when Nathaniel Wyeth (a DuPont engineering fel­low” who was also the other brother of painter Andrew Wyeth) be­gan tin­ker­ing with polypropy­lene. By this time the younger Wyeth had a paint­ing in the per­ma­nent col­lec­tion at MoMA; I imag­ine Nathaniel, the less fa­mous Wyeth, crawl­ing around in the chem­i­cal weeds, grasp­ing for some way to make his own name. Finally he found his path through the un­der­growth: A hollow ther­mo­plas­tic ar­ti­cle,” which he patented in 1973. Within two years of the Easy-Goer’s down­fall, DuPont was in full pro­duc­tion, mak­ing two-liter PET bot­tles for the Coca-Cola com­pa­ny’s caramel-col­ored sugar wa­ter. Wyeth’s 1990 obit­u­ary show­cases his in­ven­tion of the now-ubiq­ui­tous PET plas­tic soda bot­tle. Source: New York Times. I ac­tu­ally re­mem­ber these bot­tles from the birth­day par­ties of my youth. Produced from the late 70s un­til the early 90s, the first gen­er­a­tion of enor­mous PET bev­er­age con­tain­ers, with their opaque, glued-on bases, arose in tan­dem with the soda in­dus­try’s shift to high fruc­tose corn syrup. Both New” Coke and Crystal” Pepsi were pack­aged in these thick-walled, two-liter bot­tles, our par­ents us­ing two hands to pour them into our trem­bling plas­tic cups. These bot­tles were totems to American ex­cess, their con­tents slowly go­ing flat in the fridge if they weren’t spilled all over the din­ing room table first. Looking back at these beefy con­tain­ers, one can’t help but feel that it’s all too much. Too much sugar, too much plas­tic, too much overt prod­uct place­ment in our hol­i­day movies. The walls on Coke’s early two-liter bot­tles were around 0.3 to 0.4 mm thick, and their glued-on bases (which were nec­es­sary be­cause the bot­tles them­selves had round bot­toms—good for re­sist­ing in­ter­nal pres­sure, but ter­ri­ble at stand­ing up­right) mea­sured up to 0.6 mm. As a re­sult, the to­tal mass of an empty two-liter bot­tle was up to 96 grams—ex­actly dou­ble that of mod­ern two-liter bot­tles. This was, from to­day’s stand­point, a low-vol­ume prod­uct, not re­ally op­ti­mized for cost or trans­porta­tion. The bev­er­age in­dus­try had fig­ured out how to get the pub­lic to buy their drinks in dis­pos­able plas­tic bot­tles, but they had­n’t fig­ured out how to ef­fi­ciently pro­duce and sell bil­lions of them every year. Industrial CT scans show a re­duc­tion in wall thick­ness that al­lowed pack­ag­ing en­gi­neers to cut the to­tal mass of the 2L bot­tle in half since the in­tro­duc­tion of PET bev­er­age bot­tles. For more on the orig­i­nal vs. pre­sent day Coke bot­tle, check out Scan of the Month. But you can be sure that cor­po­rate chem­i­cal en­gi­neers (and mar­keters) were work­ing hard on just that prob­lem. By the early 1990s, both Coke and Pepsi fig­ured out just what bev­er­age they could sell us bil­lions of dis­pos­able plas­tic bot­tles of. The so­lu­tion did­n’t come from a moun­tain spring, or a Soviet vine­yard, or the con­cen­trated car­bo­hy­drates ex­tracted from in­dus­tri­ally-farmed corn. No, the killer ap­pli­ca­tion for the dis­pos­able plas­tic bot­tle in­dus­try was a mu­nic­i­pal wa­ter tap in Wichita, Kansas. Bottled wa­ter boom Looking back on it now, the bot­tled wa­ter boom feels like a ridicu­lous—yet un­der­stand­able—evo­lu­tion of our early 90s milk-car­tons-and-two-liter-soda-bot­tles cul­ture. The signs were there in 1992, when af­ter a bid­ding war, Nestlé ac­quired Perrier, gain­ing not only the dis­tinc­tively bub­bly French brand but also Poland Spring, Arrowhead, and Great Bear in the same trans­ac­tion. Then in 1994, Pepsi in­tro­duced Aquafina, with its clear half-liter bot­tles and un­re­mark­able brand­ing sketch­ing out the de­cid­edly mid­dle­brow aes­thetic that would de­fine the emerg­ing mass-mar­ket bot­tled wa­ter in­dus­try. Not to be left be­hind, Coke launched Dasani (a di­rect com­peti­tor to Aquafina, al­beit with slightly more dis­tinc­tive brand­ing) in 1999. These brands’ yup­pie ap­peal never re­ally spoke to me per­son­ally; they felt gauche, cor­po­rate, su­per­flu­ous. But I do re­call buy­ing bot­tles of Vitaminwater (the Glacéau-owned sis­ter-brand to Smartwater) and think­ing of my­self (then a teenager) as so­phis­ti­cated, and vaguely alternative.” This feel­ing lasted roughly un­til the pre­cise mo­ment when Glacéau was ac­quired by Coca-Cola, in May of 2007. In the years that fol­lowed I pur­chased their prod­ucts only in times of dis­tress. Today’s light­weight half-liter wa­ter bot­tles use 75% less plas­tic than those on the mar­ket in the mid-2000s. Regardless of my own feel­ings, I must ad­mit that brands like Aquafina, Dasani, and Smartwater did good work in help­ing Pepsi and Coke re­place their de­clin­ing soda sales in the late 90s and the early 00s. They also gave the soda gi­ants an op­por­tu­nity to re­ally cost-en­gi­neer their bot­tling op­er­a­tions, tweak­ing their bot­tle and cap de­signs to re­duce mass and shorten man­u­fac­tur­ing cy­cle times. Petaloid” bot­tle bases, which came to promi­nence in the 90s, elim­i­nated the need for glued-on bases—re­duc­ing ma­te­r­ial us­age while dis­trib­ut­ing stress more evenly across the bot­tle’s walls. Thinner bot­tle walls (Aquafina’s were around .2 mm) and shorter caps meant faster bot­tle pro­duc­tion; spi­ral rib­bing on the bot­tles’ walls meant that they could be stacked higher and would re­sist dam­age dur­ing ship­ping. Dasani- and Aquafina-branded vend­ing ma­chines, stocked by ex­ist­ing soft drink dis­trib­u­tors, kept prod­ucts mov­ing through sup­ply chains ef­fi­ciently. Eventually, many wa­ter bot­tlers—Coke, Pepsi, Evian, Nestlé—switched por­tions of their pro­duc­tion to 100% re­cy­cled poly­eth­yl­ene, which has proven to be durable, com­mer­cially de­sir­able, and food-safe. Lightweighting and ef­fi­ciency Once bot­tled wa­ter proved it­self as a high-vol­ume con­sumer prod­uct, its vari­a­tions pro­lif­er­ated. Look in al­most any bev­er­age sec­tion, in any store in the US, and you’ll find wa­ter pack­aged not only in PET bot­tles but also in glass, alu­minum cans, and multi-lay­ered pa­per­board boxes. My tiny ur­ban gro­cery store al­lo­cates about as much shelf space to bot­tled wa­ter as they do to bread. Even tiny, outer-bor­ough NYC bode­gas usu­ally carry broad ar­rays of bot­tled wa­ter brands, many of which are shipped in from halfway around the world. Niagara (a pri­vately-held com­pany with around 7,500 em­ploy­ees work­ing in more than a dozen bot­tling fa­cil­i­ties) claims to have re­duced the amount of plas­tic in their half-liter bot­tle by 60% since 1998, with sim­i­larly im­pres­sive re­duc­tions in their car­bon foot­print. As the mar­ket evolved, a stag­ger­ing amount of work was done to re­duce the mass of com­mod­ity-grade dis­pos­able wa­ter bot­tles. Today, even white-la­beled wa­ter bot­tles—bland, bot­tom-of-the-bar­rel brands, mostly de­void of char­ac­ter and sold only in racks of twenty-four or greater—ben­e­fit from decades upon decades of op­ti­miza­tion. An ex­cel­lent ex­am­ple of this is the Niagara Eco-Air” half-liter bot­tle, vari­a­tions of which are sold un­der house-la­bel brands like Walgreens’ Nice!, Costco’s Kirkland, and Albertson’s Signature Select. Niagara (a pri­vately-held com­pany with around 7,500 em­ploy­ees work­ing in more than a dozen bot­tling fa­cil­i­ties) claims to have re­duced the amount of plas­tic in their half-liter bot­tle by 60% since 1998, with sim­i­larly im­pres­sive re­duc­tions in their car­bon foot­print. Flimsy in the hand even when full of wa­ter, their bot­tles have wall thick­nesses of less than 0.17 mm. PET bot­tles of­fer one of the most ef­fi­cient pack­ag­ing-to-prod­uct ra­tios, com­bin­ing min­i­mal ma­te­r­ial use with strong pro­tec­tion and prod­uct safety. Both the bot­tles and caps are fully re­cy­clable and con­tain no added BPA. Source: Niagara Bottling. Even so, these fly­weight bot­tles are sur­pris­ingly strong, their phys­i­cal prop­er­ties tuned to the needs of mod­ern lo­gis­ti­cal and com­mer­cial in­fra­struc­ture. Bottles like Niagara’s Eco-Air (which is sim­i­lar to Poland Spring’s half-liter bot­tle) are typ­i­cally shrink-wrapped into 32-bottle packs, which are then shipped hun­dreds or thou­sands of miles be­fore they’re dumped on our gro­cery stores’ load­ing ar­eas. These brick-like bun­dles of plas­ti­cized wa­ter are not han­dled with a ton of care en route, and in the case of my gro­cery store they’re piled in chest-high stacks near the check-out aisles. This is what man­u­fac­tur­ers like Niagara cares about: Their bot­tles need to be just strong enough to sur­vive the trip to my gro­cery store, and then the sub­se­quent jaunt to what­ever block party or school potluck they might be ripped open at. Because once their caps are un­screwed, these bot­tles’ half-lives are mea­sured in sec­onds. Recycling and reuse Half-liter bot­tles like the Eco-Air are ubiq­ui­tous in my neigh­bor­hood. There are hun­dreds of them at each of the cor­ner stores within crawl­ing dis­tance of my stoop, and ad­di­tional dozens of them (emptied of their orig­i­nal con­tents, and then some­times filled with some­thing less re­fresh­ing) on the side­walks and curbs nearby. We are lucky if these bot­tles end up in land­fills; they cer­tainly end up in worse places much of the time. After I had drunk my liter of San Pellegrino straight from its green glass bot­tle, I tossed the bot­tle into the re­cy­cling bin with a con­fus­ing mix­ture of pride and shame. A few days later, the city’s Sanitation Department picked it up; I know from ex­pe­ri­ence that it was bound to be bro­ken up into lit­tle green glass chips at a trans­fer fa­cil­ity on the shore of the New York Harbor. But my crushed Pellegrino bot­tle is­n’t sorted into a big pile of pure green glass; it’s mixed with other col­ored glass, which is dif­fi­cult to sort into its con­stituent parts and can’t eas­ily be re-melted into new con­tain­ers. More or less use­less at that point, this mul­ti­col­ored melange is likely to be sold as fill ma­te­r­ial for an in­fra­struc­ture pro­ject—if it’s not land­filled di­rectly. What’s next for pack­ag­ing? It’s harder to say where the plas­tic bot­tles I pur­chased will end up. After drink­ing the Evian and the Smartwater, I found my­self re­fill­ing both of their PET bot­tles with NYC tap wa­ter, and over the fol­low­ing weeks I proudly—and re­peat­edly—lugged one or the other of them with me as I biked to the climb­ing gym, hop­ing se­cretly that some­one there would rec­og­nize them as some of the most pop­u­lar wa­ter con­tain­ers among the ul­tra­light hik­ing com­mu­nity But at some point even the luck­i­est and most long-lived poly­eth­yl­ene bot­tles will be trashed. But, who knows. If you wait around long enough, some­one’s bound to start work­ing on solv­ing that prob­lem too.

Pwnd Blaster: Hacking your PC using your speaker without ever touching it

blog.nns.ee

In my last post, I talked about re­verse en­gi­neer­ing my new Creative Sound Blaster Katana V2Xs firmware.

What ini­tially started as sim­ply want­ing to write a Linux tool for com­mu­ni­cat­ing with my speaker ended up with me dis­cov­er­ing vul­ner­a­bil­i­ties which al­low any at­tacker within a ~15M range of any Katana V2X to turn it into a covert spy­ing tool and Rubber Ducky - all with­out ever hav­ing to pair with or phys­i­cally touch the de­vice.

CTprotocol back­ground

As I ex­plained in my pre­vi­ous post, the Katana V2X is a USB-connected PC sound bar. Being USB-connected, Creative has an app which al­lows you to change the set­tings of the speaker - the DSP, the LED con­fig­u­ra­tion, the out­put source, and so on.

To do this, they use a cus­tom pro­to­col called CTP (short for Creative Transport Protocol would be my guess). Basically, it seems to be a fairly sim­ple pro­pri­etary pro­to­col for send­ing var­i­ous com­mands and read­ing the re­sponses to that. I won’t go into much de­tail here, but if you’re in­ter­ested, I de­scribed how it works in my last post.

What’s im­por­tant to note, how­ever, is that in or­der to do any­thing with CTP over USB, you first have to do chal­lenge-re­sponse au­then­ti­ca­tion with the de­vice. The key is sta­tic and can be de­rived from the bi­na­ries that ship with the Creative App, and I’m un­sure why this is even the case, but the speaker won’t ac­cept any com­mands un­til you’ve per­formed au­then­ti­ca­tion. Fine.

Another thing that’ll be­come im­por­tant later is that firmware up­dates are also per­formed over CTP. That’s how I ini­tially got my hands on a firmware im­age - I sniffed the USB traf­fic us­ing Wireshark and ex­tracted the data from the cap­tures.

Firmware analy­sis

The firmware con­tainer, which is also pro­pri­etary but is es­sen­tially a prim­i­tive Zip file, con­tains three parts that are of sig­nif­i­cant value.

First, there’s FBOOT, which I pre­vi­ously pre­sumed to be a boot­loader (hence the name), but also con­tains a sort of re­cov­ery mode for the speaker. This re­cov­ery mode can be en­tered by hold­ing down the SOURCE but­ton while pow­er­ing the de­vice on, and al­lows you to re­cover from a bad state. This saved my de­vice from be­ing bricked many times, which I’m pretty grate­ful for.

The sec­ond part is FMAIN, which is the main firmware of the de­vice. This runs when you boot the de­vice normally”. While FBOOT im­ple­ments a lot of the same func­tion­al­ity as FMAIN (they both han­dle CTP com­mands, for ex­am­ple), FMAIN is about ~6.5x larger than FBOOT.

Both FBOOT and FMAIN are based on a (fairly heav­ily-mod­i­fied) ver­sion of FreeRTOS, as hinted by a string pre­sent in the bi­na­ries: /home/jieyi/mcuos2.5/kernel/freertos-8.2.3/.

The last part of note is CHK2, which is a SHA-256 check­sum over the en­tire firmware con­tainer ap­pended to the very end.

While not ex­actly shock­ing, con­sid­er­ing the amount of ef­fort that went into CTP au­then­ti­ca­tion, I was a bit sur­prised to see that be­sides this CHK2 SHA-256 check­sum, which was triv­ial to patch, there was no other pro­tec­tion in place for flash­ing firmwares. I would’ve ex­pected to find sig­na­ture checks here or at the very least a hash­sum(se­cret_­value + con­tain­er_­con­tents) type of pro­tec­tion, but af­ter reim­ple­ment­ing the firmware up­grade func­tion­al­ity in my own tool v2x-ctl, I found that the de­vice hap­pily ac­cepts patched firmwares as long as CHK2 is cor­rect.

To test this, I made a pretty sim­ple mod­i­fi­ca­tion - I re­placed the string WELCOME, which is shown on the seg­ment dis­play on the de­vice when boot­ing up, with PATCHED. After flash­ing the firmware and re­boot­ing the de­vice, I was happy to see my string be­ing shown to me:

The hacker part of me thinks this is great - peo­ple should be able to do what they want with the de­vices they’ve bought and own. The se­cu­rity pro­fes­sional part of me thinks that hav­ing ab­solutely no pro­tec­tion in place (like hav­ing to un­lock a boot­loader for mo­bile de­vices) is pretty bad prac­tice. But it’s not ex­actly the end of the world if you need phys­i­cal ac­cess to up­date the de­vice over USB.

If.

Everybody loves Bluetooth

Like all self-respecting” speak­ers these days, of course the Katana V2X also needs to have Bluetooth, even though it’s most likely go­ing to spend most of its life wired up to a PC or gam­ing con­sole.

And of course Creative needs to have an app which lets you con­trol the speak­er’s set­tings and fancy LED lights from your phone over Bluetooth.

The way BLE (Bluetooth Low Energy) works is that each de­vice has var­i­ous reg­is­ters (called GATT char­ac­ter­is­tics) that, if you’re con­nected to the de­vice, you can write to, read, sub­scribe to no­ti­fi­ca­tions for, and so on. What’s im­por­tant to note is that to con­nect to a de­vice, you don’t need to (necessarily) pair with it. You can of­ten just con­nect with a de­vice and im­me­di­ately start read­ing and writ­ing data to char­ac­ter­is­tics. Pairing es­tab­lishes en­cryp­tion, but a con­nec­tion can be made with­out it.

While dig­ging through the Katana’s firmware, I dis­cov­ered that the in­ter­nal CTP han­dler is bridged to both USB and ap­par­ently Bluetooth:

Intrigued by this, I down­loaded the Creative mo­bile app and tried con­nect­ing to my speaker.

Please press the POWER but­ton to pair.”

I won­dered how this pair­ing process worked, ex­actly. Maybe it used the same au­then­ti­ca­tion scheme as for USB and maybe I could just use the shared se­cret to au­then­ti­cate with any speaker over Bluetooth, as was the case with my e-scooter.

I set up a Bluetooth sniff­ing en­vi­ron­ment and ob­served that in or­der to ini­ti­ate the pair­ing process, the phone wrote a pay­load like 5a 0b… to a char­ac­ter­is­tic 9e9daaec-3a10 – 4fe8-b69f-7397aff77886, and read a re­sponse from char­ac­ter­is­tic 9e9daaeb-3a10 – 4fe8-b69f-7397aff77886.

5a had me very, very sus­pi­cious, as it’s the same byte that all CTP com­mands start with. Out of a hunch, I con­nected to the de­vice over Bluetooth from my lap­top and wrote the pay­load 5a 09 01 02, which is the CTP com­mand for read­ing the firmware ver­sion, and re­quires au­then­ti­ca­tion to send over USB.

To my sur­prise, upon read­ing the char­ac­ter­is­tic 9e9daaeb-3a10 – 4fe8-b69f-7397aff77886, I was greeted with the full ver­sion string. This means any­one can just con­nect to any Katana V2X over Bluetooth and start send­ing CTP com­mands to it, read­ing in­for­ma­tion, chang­ing set­tings, etc.

Over-the-air up­dates (the bad kind)

It did­n’t take me too long to con­nect the dots that firmware up­grades were also per­formed over CTP. Combined with the fact that any­one can con­struct valid cus­tom firmware, I won­dered if it was pos­si­ble for an at­tacker to sim­ply up­load a cus­tom firmware over Bluetooth with­out ever hav­ing to au­then­ti­cate or pair.

After wrestling with a few BLE quirks (which I’ll de­scribe in de­tail later in this ar­ti­cle), I wrote a rel­a­tively sim­ple Python script that does ex­actly what my v2x-ctl tool does to up­grade firmware, but over Bluetooth in­stead. Using that, I at­tempted to up­load the mod­i­fied firmware I had crafted ear­lier to my speaker. Since BLE is quite slow, it took around 10 min­utes to fin­ish, but af­ter it was done, I was once again greeted with my lovely PATCHED wel­come mes­sage.

I thought of the im­pli­ca­tions for a bit. The speaker has a mi­cro­phone. An at­tacker could, the­o­ret­i­cally, up­load a cus­tom firmware that ef­fec­tively turns the speaker into a covert mon­i­tor­ing de­vice, lis­ten­ing in on con­ver­sa­tions and for­ward­ing them to a re­ceiver over Bluetooth.

What was more in­ter­est­ing to me was the fact that the speaker is, in a stan­dard setup, con­nected to a PC over USB. It’s by all means a trusted USB de­vice.

What if we wrote cus­tom firmware that forced the speaker into act­ing as a key­board, send­ing key­strokes for open­ing up the ter­mi­nal and ex­e­cut­ing ar­bi­trary com­mands? We would turn the speaker into a Rubber Ducky, but re­motely, with­out ever hav­ing to plug any­thing into ei­ther the speaker or the PC.

Living off the ker­nel land

At first, I thought this would be a her­culean task. Since I don’t have ac­cess to the source code of the firmware, I would have to some­how jury-rig in an en­tire sec­tion of code that sets the de­vice up as a HID (human in­ter­face de­vice) USB de­vice (if that’s even pos­si­ble for this SoC), a pro­ce­dure for then us­ing this to send key­strokes to the PC over USB, and con­tin­u­ing to run the rest of the code in the firmware so the speaker would still be­have as nor­mal.

However, af­ter dig­ging around some more in the firmware, I re­al­ized it’s likely not as dif­fi­cult as it seems.

First off, it turns out the speaker al­ready sets it­self up as a HID de­vice. Not as a full key­board, mind you, but as a Consumer Control de­vice - ba­si­cally let­ting the speaker change the vol­ume and me­dia sta­tus (play/pause) on the PC, but not much else.

This could be seen in the ker­nel logs:

The way this is done with USB de­vices is that the de­vice pre­sents the PC with a USB de­scrip­tor set, which is ba­si­cally a re­port of its ca­pa­bil­i­ties, what it can do, how many in­ter­faces to enu­mer­ate, and so on.

The re­port de­scrip­tor in the firmware was pretty easy to lo­cate and to my luck, it had enough space to ap­pend a sec­ond re­port de­scrip­tor en­try that also pre­sented the de­vice as a key­board. Running dmesg now shows that the de­vice also re­ports be­ing a key­board:

The sec­ond is­sue was send­ing ac­tual HID data and em­u­lat­ing key­strokes. Much to my luck, the firmware al­ready had a neatly us­able rou­tine for send­ing HID data, all I had to do was pro­vide it with data (the key to press or un­press) and call it.

The third is­sue I strug­gled with quite a bit. It was dif­fi­cult to find enough free space that I could write in (which would get prop­erly mapped in mem­ory or would­n’t im­me­di­ately crash the de­vice when boot­ing), find­ing a tram­po­line that worked prop­erly and did­n’t crash re­turn­ing back to the nor­mal in­struc­tion flow, etc.

I even­tu­ally re­al­ized that if this is run­ning on FreeRTOS, there’s likely nu­mer­ous tasks be­ing ex­e­cuted on boot any­ways. I don’t need to write a tram­po­line and jug­gle the ex­e­cu­tion flow, I can just over­write an ex­ist­ing task and let the firmware spawn it for me. I ended up find­ing a di­ag­nos­tic task, which did­n’t seem to do any­thing in nor­mal use - from what I could tell, it was only used for gath­er­ing di­ag­nos­tic data from a DSP co­proces­sor.

I over­wrote that task with a task that:

Waits ~20 sec­onds for the speaker to boot and bring up the USB sub­sys­tem

Types in echo pwned and hits en­ter, with ~20ms be­tween each key­stroke

Ends the task, leav­ing the rest of the speak­er’s func­tion­al­ity in­tact

This would be ex­e­cuted every time the de­vice booted up.

The patches ended up be­ing pretty min­i­mal - only 83 bytes for the USB re­port and 102 bytes of hand-writ­ten ARM/Thumb as­sem­bly for the key­stroke in­jec­tor, plus 2 bytes for every key­stroke I wanted to send.

The re­sult

Chaining it all to­gether, I was able to to­tally re­motely, over the air, up­load a cus­tom firmware to my speaker which I had­n’t paired with, which would re­boot, flash the cus­tom firmware, and af­ter re­boot­ing type in the com­mand echo pwned and ex­e­cute it.

In a real at­tack sce­nario, I would ex­e­cute the key­strokes for open­ing pow­er­shell.exe or sim­i­lar and paste an ac­tu­ally ma­li­cious one-liner into that, but as a proof of con­cept, this was more than enough for me. A real at­tacker would also likely dis­able the rou­tine for up­dat­ing the firmware in both nor­mal and re­cov­ery mode, mak­ing it im­pos­si­ble to wipe the ma­li­cious firmware from the de­vice or patch it in the fu­ture.

This is wors­ened by the fact that Bluetooth is al­ways on for the speaker, even in sleep mode, with no ap­par­ent way to dis­able it.

Remediation

Getting in touch with Creative was a frus­trat­ing process.

They do not have any se­cu­rity con­tacts. In fact, I was­n’t even able to find reg­u­lar con­tacts that was­n’t just a sup­port form on their web­site. I tried (two times) to get in con­tact with them via the web form be­fore giv­ing up and con­tact­ing SingCERT to act as an in­ter­me­di­ary, hop­ing they would have bet­ter luck reach­ing Creative.

Initially, SingCERT did­n’t seem to be able to get in con­tact with Creative ei­ther. It took Creative nearly two months to re­spond to SingCERT. Unfortunately, their re­sponse was that they do not con­sider this to be a vul­ner­a­bil­ity, as it does not pre­sent a cy­ber­se­cu­rity risk”. I don’t know how they reached this con­clu­sion, but it be­came clear that Creative had no in­ter­est in re­spond­ing to or ad­dress­ing this is­sue.

Due to this, there are no patches cur­rently avail­able via Creative them­selves. The lat­est firmware is vul­ner­a­ble.

As a par­tial rem­edy, to en­sure that peo­ple are still able to use these de­vices se­curely, I wrote a patch for the firmware that blocks CTP-over-Bluetooth. This likely breaks the Creative mo­bile app, but with­out the source code, it’s fairly hard to patch the firmware with proper au­then­ti­ca­tion in-place.

If you’re in­ter­ested in us­ing this patch, I’ve cre­ated a tool that down­loads the of­fi­cial firmware from Creative’s servers, patches it in mem­ory, and up­loads it to your USB-connected Katana V2X. You can get it from the re­leases page here: https://​git.dog/​xx/​v2x-patcher (or build it your­self with cargo if you want to in­spect the patches be­fore­hand).

The nitty gritty

What fol­lows are a few tech­ni­cal de­tails of the re­verse en­gi­neer­ing process and the bi­nary patches in no spe­cific or­der.

Memory lay­out woes

For Ghidra’s (or any other RE toolk­it’s) au­to­matic analy­sis to work prop­erly, the bi­nary needs to have the cor­rect base ad­dress. Otherwise, point­ers cal­cu­lated us­ing the base ad­dress will point to the wrong data and you’ll just get dis­as­sem­bly that does­n’t make much sense.

With FMAIN.bin, I strug­gled quite a bit. It was­n’t enough to sim­ply load the firmware with what I as­sumed to be the cor­rect base (0x10000000). When I loaded the bi­nary us­ing this base, the auto-analy­sis seemed to pro­duce valid re­sults, the startup code and FreeRTOS core seemed cor­rect, but af­ter that brief sec­tion in the be­gin­ning, auto-analy­sis seemed to fail and pro­duce garbage.

As it turns out, FMAIN.bin is not a mono­lithic im­age and is in­stead scat­ter-loaded, with dif­fer­ent sec­tions of the firmware loaded at dif­fer­ent ad­dresses.

I did­n’t find any easy way to read what the cor­rect mem­ory map should be, but I de­duced (and later ver­i­fied by read­ing mem­ory right off the de­vice, when I was able to patch and up­load firmware) the fol­low­ing lay­out:

Using this mem­ory map in Ghidra seemed to ac­tu­ally pro­duce valid analy­sis re­sults.

String x-refs for ARM firmware

Even though my mem­ory map was cor­rect, I was still not get­ting many X-refs de­fined for my strings. Some strings were ref­er­enced by some func­tions, but this seemed in­con­sis­tent and most strings seemed to be wholly un­ref­er­enced, which did­n’t make any sense.

Working back from what I as­sumed to be the log method in the firmware, I re­al­ized that string point­ers weren’t be­ing loaded di­rectly. Instead, string point­ers were loaded us­ing a pair of movw and movt in­struc­tions:

movw r0, #0x29A4  ; low 16 bits movt r0, #0x400A  ; high 16 bits, r0 = 0x400A29A4

I tried search­ing on­line, but did­n’t find much in­for­ma­tion on why ex­actly Ghidra’s analy­sis seems to not rec­og­nize these as point­ers to strings (perhaps the scat­ter-load­ing?), but I wrote a script that went over all movw/​movt pairs which loaded into the same reg­is­ter, fil­tered out the ones point­ing to valid mem­ory, and set up DATA ref­er­ences to those. This cre­ated ~13k ref­er­ences and made my life so much eas­ier.

Firmware patches for read­ing, writ­ing and ex­e­cut­ing mem­ory

After I fig­ured out how to mod­ify the firmware and in­ject my own code, the first or­der of busi­ness was set­ting up a method of read­ing, writ­ing and ex­e­cut­ing mem­ory. This was im­por­tant for a few rea­sons, but most im­por­tantly for ver­i­fy­ing the ac­tual mem­ory lay­out, read­ing what was go­ing on in the heap, and be­ing able to write and ex­e­cute pay­loads on the fly with­out hav­ing to patch the firmware it­self and flash it. Flashing the firmware was sloooow, and a lot of my RE time was taken up sim­ply wait­ing for the firmware to up­load to the de­vice, the de­vice to re­boot, re­al­ize that my patches were wrong and the de­vice is boot­loop­ing or has been bricked, re­boot­ing into re­cov­ery mode (which re­quired pulling the power), and re­peat­ing the whole process again.

To set up these han­dlers, I de­cided that the best way to im­ple­ment this would to over­write a CTP han­dler that al­ready ex­ists and is prop­erly routed, but which does­n’t do any­thing im­por­tant. The CTP op­code 0x54 seemed like a pretty good can­di­date, all it did was echo back the data it was sent, and the han­dler was about 106 bytes long. This seemed a bit tight to fit three com­mands into, but ended up be­ing just barely enough room to work with - my fi­nal han­dler with all three com­mands im­ple­mented ended up be­ing 96 bytes long.

On the host side, I sim­ply mod­i­fied my v2x-ctl tool to sup­port this cus­tom CTP com­mand. With this, I was able to ex­e­cute ar­bi­trary code over USB with­out hav­ing to re­flash the whole firmware, which made test­ing patches etc so much more con­ve­nient.

Watchdogs do­ing their jobs

While writ­ing the pay­load for send­ing HID com­mands, I kept run­ning into an is­sue where my code, which was seem­ingly fine and worked for send­ing sin­gu­lar key­presses, re­booted the de­vice when­ever I tried to im­ple­ment send­ing mul­ti­ple key­presses.

This was be­fore I came up with the replace an ex­ist­ing task” ap­proach, and was sim­ply run­ning my pay­load us­ing mem-exec as I de­scribed above. The weird­est thing was that the de­vice seemed to crash when I called a be­nign func­tion vTaskDe­lay built into FreeRTOS to add a small de­lay be­tween each key­press event.

It turns out that Creative had im­ple­mented per-task watch­dog timers, and if a crit­i­cal task was tak­ing too long, the OS would panic and re­boot (my best guess). When I called vTaskDe­lay through mem-exec, I was call­ing it in the USB han­dling task con­text. The de­lays for each char­ac­ter added up, the watch­dog timer was­n’t be­ing kicked in time, and the sys­tem re­booted.

This is­sue fixed it­self when I in­jected my code into the di­ag­nos­tic ser­vice task in­stead of call­ing it from the USB task di­rectly.

All tests and re­verse en­gi­neer­ing was per­formed on the firmware ver­sion 1.3.230619.1820.

Timeline

01/04/2026 - Attempt 1 to get in con­tact with ven­dor via their sup­port form (vendor lacks any pub­lic se­cu­rity con­tacts)

07/04/2026 - Attempt 2 to get in con­tact with ven­dor via their sup­port form

09/04/2026 - Submission of vul­ner­a­bil­i­ties to SingCERT

16/04/2026 - Response from SingCERT re­quest­ing fur­ther in­for­ma­tion

16/04/2026 - Sent ad­di­tional de­tails to SingCERT

20/04/2026 - Response from SingCERT re­quest­ing fur­ther in­for­ma­tion

20/04/2026 - Sent ad­di­tional de­tails to SingCERT

20/04/2026 - Response from SingCERT ac­knowl­edg­ing the re­port and con­firm­ing they’ve reached out to ven­dor

08/05/2026 - Email from SingCERT stat­ing they’ve been un­able to reach the ven­dor and ask­ing whether they should con­tinue at­tempt­ing to fol­low up

08/05/2026 - Sent con­fir­ma­tion to SingCERT

25/05/2026 - Email from SingCERT stat­ing ven­dor has re­sponded and is aware of the case

03/06/2026 - Email from SingCERT stat­ing ven­dor do not con­sider this to be a vul­ner­a­bil­ity, as it does not pre­sent a cy­ber­se­cu­rity risk.”

03/06/2026 - Write-up pub­lished

GitHub - c0deJedi/nbd-vram: Use your NVIDIA GPU's VRAM as swap space on Linux. Built for laptops with soldered memory and no upgrade path. If you have an RTX card sitting there with 8GB of VRAM and you're getting swapped to SSD, this puts that VRAM to work

github.com

Use your NVIDIA GPUs VRAM as swap space on Linux.

Built for hy­brid graph­ics lap­tops with sol­dered mem­ory and no up­grade path. The dis­play runs off the in­te­grated AMD/ATI GPU. The NVIDIA card sits idle most of the time, its VRAM com­pletely un­used. This puts that VRAM to work as high-pri­or­ity swap.

Tested on: AMD/ATI + RTX 3070 Laptop (GA104M, 16 GB RAM, 8 GB VRAM), dri­ver 580.159.03, ker­nel 6.17, Pop!_OS. Allocated 7 GB for swap. End re­sult in­clud­ing zram and SSD swap: ~46 GB to­tal ad­dress­able mem­ory, tripled from stock. Overflow or­der: RAM fills, then VRAM ab­sorbs the spill (PCIe), then zram com­presses the rest (CPU), then SSD only if every­thing else is ex­hausted.

How it works

A small dae­mon al­lo­cates VRAM via the CUDA dri­ver API, then serves it as a block de­vice us­ing the NBD (Network Block Device) pro­to­col over a Unix socket. The ker­nel’s built-in nbd dri­ver con­nects to it and ex­poses /dev/nbdX. From there it’s a nor­mal swap de­vice.

Data path: ker­nel swap sub­sys­tem - /dev/nbdX - nbd ker­nel dri­ver - Unix socket - nbd-vram dae­mon - cuMem­cpy­H­toD/​DtoH - GPU VRAM.

No ker­nel mod­ule to write or main­tain. No NVIDIA ker­nel sym­bols. Survives ker­nel and dri­ver up­dates with­out re­build­ing any­thing.

Why not the NVIDIA P2P API?

The obvious” ap­proach is nvidi­a_p2p_get_­pages_per­sis­tent, which pins VRAM pages in BAR1 so the CPU can ac­cess them di­rectly via ioremap_wc. Every ex­ist­ing pro­ject that tried this route hits the same wall: the NVIDIA dri­ver re­turns EINVAL on con­sumer GeForce GPUs. Both the per­sis­tent and non-per­sis­tent vari­ants, both flag val­ues. It’s gated at the RM level for Quadro/datacenter SKUs only, re­gard­less of dri­ver ver­sion.

The other ap­proach - di­rectly ioremap_wc the BAR1 phys­i­cal ad­dress with­out go­ing through the P2P API - also does­n’t work. The GPUs in­ter­nal page ta­bles only have ~16 MiB of BAR1 mapped (just the dis­play frame­buffer). Reads from the rest re­turn ze­ros. mk­swap ap­pears to suc­ceed, then swapon fails be­cause the swap header is­n’t ac­tu­ally there.

The NBD ap­proach side­steps all of this. cuMem­cpy­H­toD and cuMem­cpy­D­toH work on any CUDA GPU with­out any spe­cial per­mis­sions.

Requirements

NVIDIA GPU with CUDA sup­port (any con­sumer RTX/GTX card)

NVIDIA dri­ver with libcuda.so.1 (no CUDA toolkit needed)

Linux ker­nel 3.0+ (nbd mod­ule, built into most dis­tros)

nbd-client pack­age

gcc, make

Install

git clone https://​github.com/​c0de­jedi/​nbd-vram cd nbd-vram sudo ./install.sh sudo sys­tem­ctl start vram-swap-nbd

Verify:

swapon –show # NAME TYPE SIZE USED PRIO # /dev/nbd0 par­ti­tion 7G 0B 1500

The ser­vice is en­abled on in­stall, so it comes up au­to­mat­i­cally on every boot.

Configuration

Edit /etc/systemd/system/vram-swap-nbd.service:

Environment=VRAM_SETUP_SIZE_MB=7168 # how much VRAM to use Environment=VRAM_SWAP_PRIORITY=1500 # swap pri­or­ity (higher = used first)

The dae­mon tries the re­quested size first and backs off in 512 MiB steps if the GPU is short on mem­ory - so it will grab as much as it can even if the dis­play com­pos­i­tor is al­ready loaded. VRAM_SETUP_SIZE_MB is the ceil­ing, not a hard re­quire­ment.

After chang­ing, run sudo sys­tem­ctl dae­mon-re­load && sudo sys­tem­ctl restart vram-swap-nbd.

Power man­age­ment

The in­staller asks whether to en­able power-aware man­age­ment on first in­stall. If en­abled, the ser­vice au­to­mat­i­cally stops when you un­plug from AC (or when bat­tery drops be­low a thresh­old), and restarts when power is re­stored. Manual sys­tem­ctl stop is al­ways re­spected and won’t be over­rid­den.

To change set­tings af­ter in­stall, edit /etc/nbd-vram.conf. Changes take ef­fect on the next poll (within 60 sec­onds) or im­me­di­ately on the next AC plug/​un­plug event.

Smoke test (without in­stalling)

sudo bash test-nbd.sh

Allocates VRAM, con­nects the NBD de­vice, does a 1 MiB write/​read­back check, ac­ti­vates swap, then prints tear­down in­struc­tions. in­stall.sh han­dles tear­down au­to­mat­i­cally if a test in­stance is run­ning.

To stress the full par­ti­tion af­ter the smoke test passes:

sudo bash test-fill.sh

Writes the en­tire VRAM par­ti­tion with ze­ros, ver­i­fies a sam­ple read back, then auto-re­stores swap on exit.

Performance

Tested on RTX 3070 Laptop (8 GB VRAM), ker­nel 6.17, Pop!_OS. Compared against NVMe cryptswap (dm-crypt, PCIe 4.0). All bench­marks run with O_DIRECT to by­pass page cache.

Three bench­marks are in bench­marks/. Each runs NVMe first, then starts the VRAM ser­vice and runs the same test against the block de­vice. State is re­stored on exit.

sudo bash bench­marks/​bench-through­put.sh # se­quen­tial read/​write (dd, 2 GiB, O_DIRECT) sudo bash bench­marks/​bench-iops.sh # 4K ran­dom IOPS (fio, libaio, iodepth=32) sudo bash bench­marks/​bench-la­tency.sh # per-op­er­a­tion la­tency (ioping, 20 re­quests)

fio and iop­ing are in­stalled au­to­mat­i­cally if miss­ing.

Sequential through­put (dd, 2 GiB)

VRAM is slower for large se­quen­tial trans­fers. The bot­tle­neck is the NBD + CUDA user­space round-trip - every block crosses a Unix socket and a cuMem­cpy call, which adds over­head that NVMe’s di­rect ker­nel block path does­n’t pay. Sequential through­put is not the pri­mary swap work­load (the ker­nel swaps in­di­vid­ual 4K pages, not 4 MiB streams) - see the IOPS and la­tency bench­marks be­low.

4K ran­dom IOPS (fio, libaio, iodepth=32)

NVMe wins for sus­tained ran­dom I/O. At iodepth=32, NVMe can have 32 re­quests gen­uinely in flight si­mul­ta­ne­ously; the NBD+CUDA path se­ri­alises them through the dae­mon, so the depth ad­van­tage is re­duced. The VRAM dae­mon also adds CPU over­head that the NVMe path does not pay. For con­tin­u­ous high-through­put swap pres­sure, NVMe is faster.

The pic­ture changes for spo­radic ac­cess - see the la­tency bench­mark be­low.

Per-operation la­tency (ioping, 4K reads, 1 re­quest/​sec)

VRAM is 27x faster av­er­age la­tency. The NVMe drive is phys­i­cally ca­pa­ble of ~112 us (visible on the warmup re­quest) but APST (Autonomous Power State Transitions) puts it to sleep be­tween re­quests. At 1 re­quest per sec­ond - the rate of spo­radic swap ac­cess - it wakes cold al­most every time and pays a ~9 ms penalty. VRAM has no power states and re­sponds in 133 – 490 us con­sis­tently.

This is the sce­nario that mat­ters most in prac­tice. Memory pres­sure on a lap­top is rarely a sus­tained GB/s flood - it is in­di­vid­ual 4K page faults ar­riv­ing sec­onds apart. Every one of those faults stalls wait­ing for the swap de­vice to re­spond. At 9 ms per fault, NVMe swap is felt. At 335 us, VRAM swap is not.

Uninstall

sudo bash unin­stall.sh

License

MIT - Sean Lobjoit (c0dejedi)

AI Outperforms Law Professors in Stanford Law Study | Stanford Law School

law.stanford.edu

A ground­break­ing study led by Stanford Law School Professor Julian Nyarko re­veals that law pro­fes­sors over­whelm­ingly pre­fer AI-generated an­swers to stu­dent ques­tions over re­sponses writ­ten by their fel­low in­struc­tors—a find­ing that could re­shape how le­gal ed­u­ca­tion is de­liv­ered.

The study, ti­tled Law Professors Prefer AI Over Peer Answers,” was con­ducted with 16 law pro­fes­sors across U.S. law schools and tested whether large lan­guage mod­els could serve as ef­fec­tive tu­tors for con­tract law courses.In a blind eval­u­a­tion of nearly 3,000 anonymized com­par­isons, pro­fes­sors rated AI re­sponses sig­nif­i­cantly higher than an­swers writ­ten by other pro­fes­sors, with AI win­ning 75% of head-to-head matchups.

This study chal­lenges im­por­tant as­sump­tions about AIs role in le­gal ed­u­ca­tion,” said Nyarko, who leads Stanford Law School’s Legal Innovation through Frontier Technology Lab, or lift­lab. He co-au­thored the pa­per with col­leagues from Yale, NYU, University of Chicago, and other lead­ing in­sti­tu­tions. We fo­cused on law pre­cisely be­cause it re­quires judg­ment, nu­anced rea­son­ing, and the abil­ity to nav­i­gate am­bi­gu­ity—not just fac­tual re­call.”

Can LLMs Reason?

The study is par­tic­u­larly no­table be­cause pre­vi­ous AI eval­u­a­tions have fo­cused pri­mar­ily on sub­jects with clear right-or-wrong an­swers. Legal rea­son­ing, by con­trast, de­mands care­ful analy­sis of com­pet­ing ar­gu­ments and de­fen­si­ble con­clu­sions.

We were frankly sur­prised by the mag­ni­tude of the re­sults,” Nyarko added. These weren’t just sim­ple ques­tions with ob­vi­ous an­swers. Many of them re­quired syn­the­siz­ing com­plex ma­te­r­ial, ap­ply­ing it to new sit­u­a­tions, and ex­plain­ing le­gal con­cepts in ways that would help stu­dents de­velop their own an­a­lyt­i­cal skills.”

Participants cre­ated 40 rep­re­sen­ta­tive con­tracts law ques­tions that stu­dents might ask af­ter class or dur­ing of­fice hours, wrote their own an­swers, and then eval­u­ated re­sponses with­out know­ing whether they came from AI or other par­tic­i­pat­ing pro­fes­sors. The AI sys­tems per­formed com­pa­ra­bly to the best hu­man in­struc­tor in the study.

Perhaps most strik­ing: pro­fes­sors flagged AI re­sponses as ped­a­gog­i­cally harm­ful only 3.5% of the time, com­pared to 12% for peer-writ­ten an­swers.

In most fields where AI gets tested, there’s a right an­swer. In law, there of­ten is­n’t.” said Sarath Sanga, co-au­thor and pro­fes­sor at Yale Law School. Two op­pos­ing ar­gu­ments can both be good. What we wanted to know is whether AI can meet the la­tent pro­fes­sional stan­dard that lawyers use to eval­u­ate each oth­er’s ar­gu­ments. In this case, the an­swer was yes.”

The re­search team took ex­ten­sive pre­cau­tions to en­sure the study’s va­lid­ity. They cal­i­brated AI re­sponses to match the length and struc­ture of hu­man an­swers, used mul­ti­ple eval­u­a­tion meth­ods, and had pro­fes­sors as­sess whether re­sponses might mis­lead or con­fuse stu­dents.

Transforming Legal Education

We de­signed this study to be as rig­or­ous as pos­si­ble be­cause the stakes are so high,” Nyarko ex­plained. Legal ed­u­ca­tion is about train­ing fu­ture lawyers to think crit­i­cally, ar­gue per­sua­sively, and nav­i­gate eth­i­cal com­plex­i­ties. Our study makes im­por­tant steps to­wards find­ing out whether AI could sup­port that mis­sion.”

Alejandro Salinas, first au­thor of the study and a re­searcher at Nyarko’s lift­lab, em­pha­sized the ed­u­ca­tional im­pli­ca­tions: Our study shifts at­ten­tion to what AI tu­tor­ing can con­tribute to learn­ing in judg­ment-rich fields like law. We find that, when eval­u­ated by le­gal ed­u­ca­tors, AI tu­tors can of­fer high-qual­ity, on-de­mand sup­port that com­ple­ments class­room in­struc­tion, and may broaden ac­cess to ex­pert guid­ance.”

The study also ex­am­ined spe­cific AI mod­els, in­clud­ing com­mer­cial tu­tor­ing sys­tems and Google’s NotebookLM, find­ing vary­ing lev­els of per­for­mance. However, even when con­text lim­i­ta­tions af­fected AI re­sponses, pro­fes­sors still fre­quently pre­ferred them to hu­man-writ­ten al­ter­na­tives.

The find­ings ar­rive as law schools na­tion­wide grap­ple with in­te­grat­ing AI tools into le­gal ed­u­ca­tion while main­tain­ing rig­or­ous aca­d­e­mic stan­dards. Some in­sti­tu­tions have em­braced AI ex­per­i­men­ta­tion, while oth­ers re­main cau­tious about po­ten­tial risks in­clud­ing hal­lu­ci­na­tions, over­re­liance, and the ero­sion of crit­i­cal think­ing skills.

Our study eval­u­ates the qual­ity of an­swers given by AI tools. But how to im­ple­ment these tools to most ef­fec­tively im­prove stu­dent learn­ing is still an open ques­tion. So we’re not ad­vo­cat­ing for whole­sale adop­tion of AI tu­tors,” Nyarko cau­tioned. But our data sug­gests that blan­ket skep­ti­cism may be equally un­war­ranted. The con­ver­sa­tion should shift from whether AI can give ac­cu­rate, high qual­ity re­sponses to how we can de­ploy it re­spon­si­bly to the ben­e­fit of our stu­dents.”

View the Publication Link to SSRN

About lift­lab

Liftlab is among the first aca­d­e­mic ef­forts in le­gal AI to unite re­search, pro­to­typ­ing, and real-time col­lab­o­ra­tion with in­dus­try. Its mis­sion is to in­crease ac­cess to high qual­ity le­gal ser­vices in the pri­vate sec­tor by lever­ag­ing AI and other fron­tier tech­nolo­gies. To bridge the gap be­tween the­ory and prac­tice, lift­lab’s work ex­tends be­yond con­cep­tu­al­iza­tion and en­com­passes the build­ing of pro­to­types that help ex­plore the util­ity of AI-based so­lu­tions.

About Stanford Law School

Stanford Law School is one of the world’s lead­ing in­sti­tu­tions for le­gal schol­ar­ship and ed­u­ca­tion. Its alumni are among the most in­flu­en­tial de­ci­sion mak­ers in law, pol­i­tics, busi­ness, and high tech­nol­ogy. Faculty mem­bers ar­gue be­fore the Supreme Court, tes­tify be­fore Congress, pro­duce out­stand­ing le­gal schol­ar­ship and em­pir­i­cal analy­sis, and con­tribute reg­u­larly to the na­tion’s press as le­gal and pol­icy ex­perts. Stanford Law School has es­tab­lished a model for le­gal ed­u­ca­tion that pro­vides rig­or­ous in­ter­dis­ci­pli­nary train­ing, hands-on ex­pe­ri­ence, global per­spec­tive and a fo­cus on pub­lic ser­vice.

Meta scales back plan to track workers' clicks and keystrokes to train AI

www.bbc.com

Meta work­ers can opt out of be­ing tracked at work - but only for half an hour at a time

6 hours ago

Laura Cress,technology re­porterand

Osmond Chia,business re­porter

Getty Images

Meta is scal­ing back its plan to start track­ing its em­ploy­ees’ com­puter ac­tiv­ity, ac­cord­ing to an in­ter­nal memo sent on Tuesday.

In April the com­pany re­ceived crit­i­cism from its own staff af­ter it an­nounced a new tool would log their key­strokes and mouse clicks to train its AI mod­els.

Now, ac­cord­ing to Reuters, new con­trols will al­low em­ploy­ees to pause the data col­lec­tion for up to 30 min­utes at a time” as well as re­quest ex­emp­tions from the ini­tia­tive al­to­gether.

Meta de­clined to com­ment on the record.

It fol­lows weeks of back­lash from em­ploy­ees, in­clud­ing some who started a pe­ti­tion against the move which now has more than 1,500 sig­na­tures.

During the ini­tial an­nounce­ment of the tool, called the Model Capability Initiative (MCI), Meta told the BBC: If we’re build­ing agents to help peo­ple com­plete every­day tasks us­ing com­put­ers, our mod­els need real ex­am­ples of how peo­ple ac­tu­ally use them.”

It added that the data was not used for any other pur­pose,” and the tool had safeguards in place to pro­tect sen­si­tive con­tent”.

But work­ers were not im­pressed, with one Meta em­ployee, who asked not to be iden­ti­fied, telling the BBC that hav­ing their ac­tions train AI mod­els felt very dystopian” - as work­ers ex­pected a slew of ad­di­tional job cuts.

Another per­son who re­cently left the com­pany told the BBC the track­ing tool was just the lat­est way they’re shov­ing AI down every­one’s throat”.

An in­ter­nal memo - seen by Reuters - was re­port­edly au­thored by Stephane Kasriel, a vice pres­i­dent in Meta’s Superintelligence Labs unit.

In it, he said the team be­hind the MCI had in­tro­duced several op­ti­miza­tions” to re­duce its im­pact on lap­top bat­tery life.

This change came af­ter re­ports that em­ploy­ees were find­ing the tool con­sumed so much data it was caus­ing their in­ter­net us­age to surge when work­ing from home.

While we re­main con­fi­dent in the pri­vacy pro­tec­tions we put in place at launch, which went through sev­eral lay­ers of risk re­view, we have heard your con­cerns about per­sonal data on work de­vices, bat­tery life, and want­ing more con­trol over when cap­tur­ing hap­pens,” Kasriel said in the memo.

Quote of the day by Oracle co-founder Larry Ellison: "Citizens will be on their best behavior, because we&rsquo;re constantly recording and reporting everything that is going on" &mdash; a dire warning on the erosion of privacy

www.techradar.com

Co-founder of Oracle, Larry Ellison, who serves as the cloud gi­ant’s CTO, has been part of the tech in­dus­try’s fur­ni­ture for decades now. Looking ahead, he pro­jects the rise of tech­nolo­gies such as AI, drones, and ad­di­tional mon­i­tor­ing sys­tems.

The mod­ern sur­veil­lance state

Ellison’s warn­ing came dur­ing an hour-long Q&A at an Oracle fi­nan­cial an­a­lyst meet­ing in September 2024.

Quote of the day

This ar­ti­cle is part of TechRadar Pro’s QOTD pro­ject to pro­vide an in­sight into the minds of the bright­est and most rec­og­nized fig­ures in the tech­nol­ogy in­dus­try to­day and in years gone by. Read the full se­ries here.

This world that Ellison de­scribes re­volves around AI tech­nolo­gies pro­cess­ing huge amounts of video footage from the ex­plo­sion of cam­eras in the streets, cars, front doors, and even po­lice of­fi­cers. AI will, he added, au­to­mat­i­cally re­port is­sues that it de­tects while it’s an­a­lyz­ing footage cap­tured in real time.

With so much op­por­tu­nity to scan and de­tect wrong­do­ing across so­ci­ety, and AI re­duc­ing the pro­cess­ing and de­ci­sion-mak­ing bur­den, Ellison posited that cit­i­zens will, in kind, re­spond by ad­just­ing their be­hav­ior. This vi­sion is eerily sim­i­lar to that George Orwell de­scribed in his novel Nineteen Eighty-Four, in which Big Brother over­saw the daily ac­tions of cit­i­zens.

Wrangling with an AI-fueled dystopia

The move­ment against AI play­ing a role in sur­veil­lance is vast, with plenty of com­men­tary and re­search iden­ti­fy­ing ways this is hap­pen­ing. There are, for ex­am­ple, con­cerns over the Department of Homeland Security (DHS) mon­i­tor­ing so­cial me­dia with AI used to scan and sum­ma­rize find­ings.

Other re­ports sug­gest that big com­pa­nies are en­gag­ing in work­place sur­veil­lance. Meta CEO Mark Zuckerberg, for ex­am­ple, re­cently ad­mit­ted on an em­ployee call that AI is be­ing used to study and process the day-to-day ac­tions of em­ploy­ees to gather data to train fu­ture mod­els and agents. It comes shortly af­ter re­ports that the com­pany will track clicks and key­strokes on de­vices.

Whether in the work­place — or so­ci­ety at large — the di­rec­tion of travel for the last cou­ple of decades has fa­vored in­creased mon­i­tor­ing and sur­veil­lance, with Ellison clearly con­cerned that emerg­ing tech­nolo­gies will sim­ply add more fuel to this fire.

Sign up to the TechRadar Pro newslet­ter to get all the top news, opin­ion, fea­tures and guid­ance your busi­ness needs to suc­ceed!

Keumars Afifi-Sabet is a free­lance con­trib­u­tor for Tech Radar and the Technology Editor for Live Science. He has writ­ten for a va­ri­ety of pub­li­ca­tions in­clud­ing ITPro, The Week Digital and ComputerActive. He has worked as a tech­nol­ogy jour­nal­ist for more than five years, hav­ing pre­vi­ously held the role of fea­tures ed­i­tor with ITPro. In his pre­vi­ous role, he over­saw the com­mis­sion­ing and pub­lish­ing of long form in ar­eas in­clud­ing AI, cy­ber se­cu­rity, cloud com­put­ing and dig­i­tal trans­for­ma­tion.

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

Visit pancik.com for more.