Timo Tijhof
banner
timotijhof.net
Timo Tijhof
@timotijhof.net
17 followers 2 following 89 posts
Dutch geek living in London. Principal Engineer at Wikimedia Foundation, QUnit project lead @qunit, jQuery Infra Team @jquery, W3C Web Perf WG. Avatar: I look […] [bridged from https://fosstodon.org/@krinkle on the fediverse by https://fed.brid.gy/ ]
Posts Media Videos Starter Packs
Reposted by Timo Tijhof
THIS 👉🏻 "Wikipedia has proven itself to be incredibly resilient because it is a project that specifically leans into the shared wisdom and collaboration of humanity, our shared weirdness and ways of processing information." - @jasonkoebler

Let's keep the web weird and wonderful and human!

From […]
Original post on wikimedia.social
wikimedia.social
Reposted by Timo Tijhof
Reposted by Timo Tijhof
On this day last year, #libcurl celebrated its 18th anniversary of not breaking the ABI.

That makes it 19 years now.

https://daniel.haxx.se/blog/2024/10/30/eighteen-years-of-abi-stability/
Eighteen years of ABI stability
Exactly eighteen years ago today, on October 30 2006, we shipped curl 7.16.0 that among a whole slew of new features and set of bugfixes bumped the libcurl SONAME number from 3 to 4. ## ABI breakage This bump meant that libcurl 7.16.0 was not binary compatible with the previous releases. Users could not just easily and transparently bump up to this version from the previous, but they had to check their use of libcurl and in some cases adjust source code. This was not the first ABI breakage in the curl project, but at this time our use base was larger than at any of the previous bumps and this time people complained about the pains and agonies such a break brought them. ## We took away FTP features In the 7.16.0 release we removed a few FTP related features and their associated options. Before this release, you could use curl to do “third party” transfers over FTP, and in this release you could no longer do that. That is a feature when the client (curl) connects to server A and instructs that server to communicate with server B and do file transfers among themselves, without sending data to and from the client. This is an FTP feature that was not implemented well in curl and it was poorly tested. It was also a feature that barely no FTP server allowed and subsequently this was not used by many users. We ripped it out. ## A near pitchfork situation Because so few people used the removed features, barely anyone actually noticed the ABI breakage. It remained theoretical to most users and I believe that detail only made people more upset over the SONAME bump because they did not even see the necessity: we just made their lives more complicated for no benefit (to them). The Debian project even decided to override our decision _“no, that is not an ABI breakage”_ and added a local patch in their build that lowered the SONAME number back to 3 again in their builds. A patch they would stick to for many years to come. The obvious friction this bump caused, even when in reality it actually did not affect many users and the loud feedback we received, made a huge impact on me. It had not previously dawned on me exactly how important this was. I decided there and then to do the utmost to never go through this again. To put ABI compatibility at the top of the priority list. Make it one of the most fundamental key properties of libcurl. **Do. Not. Break. The. ABI** (we don’t break the API either) ## A never-breaking ABI The decision was initially made to avoid the negativity the bump brought, but I have since over time much more come to appreciate the upsides. _Application authors everywhere can always and without risk keep upgrading to the latest libcurl._ It sounds easy and simple, but the impact is huge. The examples, the documentation, the applications, everything can just always upgrade and continue. As libcurl over time has become even more popular and compared to 2006, used in many magnitudes more installations, it has grown into an even more important aspect of the curl life. Possibly _the_ single most important properly of curl. There is a small caveat here and that is that we occasionally of course have bugs and regressions, so when I say that users can always upgrade, that is true in the sense that we have not broken the ABI since. We have however had a few regressions that sometimes have triggered some users to downgrade again or wait a little longer for the next release that has the bug fixed. When we took that decision in 2006 we had less than 50,000 lines of product code. Today we are approaching 180,000 lines. ## Effects of never breaking ABI We know that once we adopt a change, we are stuck with it for decades to come. It makes us double-check every knot before we accept new changes. Once accepted and shipped, we keep supporting code and features that we otherwise could have reconsidered and perhaps removed. Sometimes we think of a better way to do something _after_ the initial merge, but by then it is too late to change. We can then always introduce new and better ways to do things, but we have to keep supporting the old way as well. A most fundamental effect is that we can never shrink the list of options we support. We can never actually rename something. Doing new things and features consistently over this long time is hard if not impossible, as we learn new things and paradigms vary through the decades. ## How The primary way we maintain this is by manual code view and code inspection of every change. Followed of course by a large range of tests that make sure that assumptions remain. Occasionally we have (long) discussions around subtle details when someone proposes a change that potentially might be considered an ABI break. Or not. What exactly is covered by _ABI compatibility_ is not always straight forward or easy to have carved in stone. In particular since the project can be built and run on such a wide range of systems and architectures. ## Deprecating We _can_ still remove functionality if the conditions are right. Some features and options are documented and work in a way so that something is _requested_ or _asked for_ and libcurl then tries to satisfy that ask. Like for example libcurl once supported HTTP/1 pipelining like that. libcurl still provides the option to enable pipelining and applications can still ask for it so it is still ABI and API compatible, but a modern libcurl simply will never do it because that functionality has been removed. Example two: we dropped support for NPN a few years back. NPN being a TLS extension called Next Protocol Negotiation that was used briefly in the early days of HTTP/2 development before ALPN was introduced and replaced NPN. Virtually nothing requires NPN anymore, and users can still set the option asking for it, but it will never actually happen over the wire. Furthermore, a typical libcurl build involves multiple third party libraries that provide features it needs. For things like TLS, SSH, compression and binary HTTP protocol management. Over the years, we have removed support for several such libraries and introduced support for new, in ways that was never visible in the API or ABI. Some users just had to switch to building curl with different helper libraries. In reality, libcurl is typically more stable than most existing servers and URLs. The libcurl examples you wrote in 2006 can still be built with the modern libcurl, but the servers and URLs you used back then most probably cannot be used anymore. ## If no one can spot it, it did not happen As blunt as it may sound, it has came down to this fundamental statement several times to judge if a change is an ABI breakage or not: _If no one can spot an ABI change, it is not an ABI change_ Of course what makes it harder than it sounds is that it is extremely difficult to actually know if someone will notice something ahead of time. libcurl is used in so ridiculously many installations and different setups, second-guessing whatever everyone does and wants is darned close to impossible. Adding to the challenge is the crazy long upgrade cycles some of our users seem to sport. It is not unusual to see questions appear on the mailing lists from users bumping from curl versions from eight or ten years ago. The fact that we have not heard users comment on a particular change might just mean that they are still stuck on ancient versions. Getting frustrated comments from users today about a change we landed five years ago is hard to handle. ## Forwards compatible I should emphasize that all this means that users can always upgrade to a _later_ release. It does not necessarily mean that they can switch back to an older version without problems. We do add new features over time and if you start using a new feature, the application of course will not work, or even still compile, if you would switch to a libcurl version from before that feature was added. ## How long is never What I have laid out here is our plan and ambition. We have managed to stick to this for eighteen years now and there is no particular known blockers in the known future either. I cannot rule out that we might at some point in the future run into an obstacle so huge or complicated that we will be forced to do the unthinkable. To break the ABI. But until we see absolutely no other way forward, it is not going to happen.
daniel.haxx.se
Reposted by Timo Tijhof
Another great music breakdown by Captain Pikant. This time about Nine Inch Nails.

https://www.youtube.com/watch?si=zBwSykzJjGSUazXa

#captainpikant #nineinchnails
@cdevroe

Hehe, not quite. I edited the URL to the video to remove the tracking 'si' parameter as I usually do. Except YT ordered the parameters the other way on this one and I mistakenly stripped the 'v' parameter instead. Fixed.

Thank you.
Reposted by Timo Tijhof
The Serial Port made this lovely IRC documentary

(and yes, I got a "thanks" in the ending credits as I contributed with facts)

https://youtu.be/6UbKenFipjo?si=IPDJKfm9FHpao_-u
Another great music breakdown by Captain Pikant. This time about Nine Inch Nails.

https://www.youtube.com/watch?si=zBwSykzJjGSUazXa

#captainpikant #nineinchnails
Reposted by Timo Tijhof
NaN, the not-a-number number that isn’t NaN

We're pretty aware, generally that JavaScript is weird, but did you know Not-A-Number (NaN) is a type of number? Mat Marquis walks us through why that is and how to deal with NaN well in your codebases […]
Original post on front-end.social
front-end.social
Post-mortem on the 14h AWS outage:

"""
The root cause was a latent race condition that resulted in an empty DNS record [..]. [During] this clean-up, [the] first Enactor applied its older plan, overwriting the newer plan. The second Enactor [..] then deleted all IP addresses. The system was […]
Original post on fosstodon.org
fosstodon.org
Reading through old cases that mention robots.txt... you know it gets good when a Judge is party to the case.

TLDR: Judge stores "funny or bizare" sexually explicit images on a family server, then connects said server to the Internet.

"""
His son suggested installing a robots.txt file. The […]
Original post on fosstodon.org
fosstodon.org
The Making of Fox News:

"""
It's not enough that conservatives like us, it's important that liberals hate us.
"""

Excellent documentary by Fern & Hoog. Divisive politics is by design. Not surprising but quite something to see it laid bare.

Reminds me of CGPGrey about how "thought germs" in […]
Original post on fosstodon.org
fosstodon.org
Reposted by Timo Tijhof
Reposted by Timo Tijhof
Reposted by Timo Tijhof
Lol looks like this astrophotography catalog has some unexpected superstar images.
Reposted by Timo Tijhof
Today is nine years ago since I learned how a single fixed byte write outside a heap buffer could be used in a sequence to execute code as root on Chrome OS:

https://daniel.haxx.se/blog/2016/10/14/a-single-byte-write-opened-a-root-execution-exploit/
a single byte write opened a root execution exploit
Thursday, September 22nd 2016. An email popped up in my inbox. > **Subject: ares_create_query OOB write** As one of the maintainers of the c-ares project I’m receiving mails for suspected security problems in c-ares and this was such a one. In this case, the email with said subject came from an individual who had reported a ChromeOS exploit to Google. It turned out that this particular c-ares flaw was one important step in a sequence of necessary procedures that when followed _**could let the user execute code on ChromeOS from JavaScript – as the root user**_. I suspect that is pretty much the worst possible exploit of ChromeOS that can be done. I presume the reporter will get a fair amount of bug bounty reward for this. (Update: he got 100,000 USD for it.) The setup and explanation on how this was accomplished is very complicated and I am deeply impressed by how this was figured out, tracked down and eventually exploited in a repeatable fashion. But bear with me. Here comes a very simplified explanation on how a single byte buffer overwrite with a fixed value could end up aiding running exploit code as root. _The main Google bug for this problem is still not open since they still have pending mitigations to perform, but since the c-ares issue has been fixed I’ve been told that it is fine to talk about this publicly._ ## c-ares writes a 1 outside its buffer c-ares has a function called ares_create_query. It was added in 1.10 (released in May 2013) as an updated version of the older function ares_mkquery. This detail is mostly interesting because Google uses an older version than 1.10 of c-ares so in their case the flaw is in the old function. This is the two functions that contain the problem we’re discussing today. It used to be in the ares_mkquery function but was moved over to ares_create_query a few years ago (and the new function got an additional argument). The code was mostly unchanged in the move so the bug was just carried over. This bug was actually already present in the original ares project that I forked and created c-ares from, back in October 2003. It just took this long for someone to figure it out and report it! I won’t bore you with exactly what these functions do, but we can stick to the simple fact that they take a name string as input, allocate a memory area for the outgoing packet with DNS protocol data and return that newly allocated memory area and its length. Due to a logic mistake in the function, you could trick the function to allocate a too short buffer by passing in a string with an escaped trailing dot. An input string like “one.two.three\\.” would then cause the allocated memory area to be one byte too small and the last byte would be written outside of the allocated memory area. A buffer overflow if you want. The single byte written outside of the memory area is most commonly a 1 due to how the DNS protocol data is laid out in that packet. This flaw was given the name CVE-2016-5180 and was fixed and announced to the world in the end of September 2016 when c-ares 1.12.0 shipped. The actual commit that fixed it is here. ## What to do with a 1? Ok, so a function can be made to write a single byte to the value of 1 outside of its allocated buffer. How do you turn that into your advantage? The Redhat security team deemed this problem to be of “Moderate security impact” so they clearly do not think you can do a lot of harm with it. But behold, with the right amount of imagination and luck you certainly can! Back to ChromeOS we go. First, we need to know that ChromeOS runs an internal HTTP proxy which is very liberal in what it accepts – this is the software that uses c-ares. This proxy is a key component that the attacker needed to tickle really badly. So by figuring out how you can send the correctly crafted request to the proxy, it would send the right string to c-ares and write a 1 outside its heap buffer. ChromeOS uses dlmalloc for managing the heap memory. Each time the program allocates memory, it will get a pointer back to the request memory region, and dlmalloc will put a small header of its own just before that memory region for its own purpose. If you ask for N bytes with malloc, dlmalloc will use ( header size + N ) and return the pointer to the N bytes the application asked for. Like this: With a series of cleverly crafted HTTP requests of various sizes to the proxy, the attacker managed to create a hole of freed memory where he then reliably makes the c-ares allocated memory to end up. He knows exactly how the ChromeOS dlmalloc system works and its best-fit allocator, how big the c-ares malloc will be and thus where the overwritten 1 will end up. When the byte 1 is written after the memory, it is written into the header of the next memory chunk handled by dlmalloc: The specific byte of that following dlmalloc header that it writes to, is used for flags and the lowest bits of size of that allocated chunk of memory. Writing 1 to that byte clears 2 flags, sets one flag and clears the lowest bits of the chunk size. The important flag it sets is called prev_inuse and is used by dlmalloc to tell if it can merge adjacent areas on free. (so, if the value 1 simply had been a 2 instead, this flaw could not have been exploited this way!) When the c-ares buffer that had overflowed is then freed again, dlmalloc gets fooled into consolidating that buffer with the subsequent one in memory (since it had toggled that bit) and thus the larger piece of assumed-to-be-free memory is partly still being in use. Open for manipulations! ## Using that memory buffer mess This freed memory area whose end part is actually still being used opened up the play-field for more “fun”. With doing another creative HTTP request, that memory block would be allocated and used to store new data into. The attacker managed to insert the right data in that further end of the data block, the one that was still used by another part of the program, mostly since the proxy pretty much allowed anything to get crammed into the request. The attacker managed to put his own code to execute in there and after a few more steps he ran whatever he wanted as root. Well, the user would have to get tricked into running a particular JavaScript but still… I cannot even imagine how long time it must have taken to make this exploit and how much work and sweat that were spent. The report I read on this was 37 very detailed pages. And it was one of the best things I’ve read in a long while! When this goes public in the future, I hope at least parts of that description will become available for you as well. ## A lesson to take away from this? No matter how limited or harmless a flaw may appear at a first glance, it can serve a malicious purpose and serve as one little step in a long chain of events to attack a system. And there are skilled people out there, ready to figure out all the necessary steps. **Update:** A detailed write-up about this flaw (pretty much the report I refer to above) by the researcher who found it was posted on Google’s Project Zero blog on December 14: Chrome OS exploit: one byte overflow and symlinks.
daniel.haxx.se
Reposted by Timo Tijhof
Unbekannte haben mehrere Hühner in einer S-Bahn Richtung Köln ausgesetzt 🐔
Reposted by Timo Tijhof
Reposted by Timo Tijhof
A hostile takeover of RubyGems is one thing. This is a new level of something I better don’t spell out or their lawyer might send me a letter for defamation.

https://andre.arko.net/2025/10/09/the-rubygems-security-incident/
Reposted by Timo Tijhof
🆕 blog! “Quick and dirty bar-charts using HTML's meter element”

"If it's stupid but it works, it's not stupid."

I want to draw some vertical bar charts. I don't want to use a 3rd party library, or bundle someone else's CSS, or learn how to build SVGs.

HTML contains a <meter> element. It is […]
Original post on mastodon.social
mastodon.social