If you work in software, you've likely heard of the latest hilarious bug - Linux glibc getaddrinfo() stack buffer overflow (https://isc.sans.edu/diary/CVE-2015-7547%3A+Critical+Vulnerability+in+glibc+getaddrinfo/20737). It was jointly found by redhat and google (https://googleonlinesecurity.blogspot.ca/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html), and it's been under investigation for a while. There are also some proof of concepts out there (eg https://github.com/fjserna/CVE-2015-7547).
I'm not sure if Android or OpenWRT devices are vulnerable - they don't use glibc out of the box, but they may use the relevant pieces of the NSS resolver library. But anything based on a linux distribution (centos, debian, ubuntu, redhat, etc) - ie, web services, docker installs, virtual machines, a heck of a lot of firewall/email/web gateway appliances, even some router management planes (hi Cisco?) may be vulnerable to this attack.
This means, well, most of the internet is likely vulnerable. I'm glad it's not an obvious bug in openwrt/android, as that'd also mean tens/hundreds of millions of devices are vulnerable. But it's a good study case - if you own something that has this bug, but there's no longer software updates available, you're short of luck. You may have working software on a perfectly working hardware, but since you (or some third party) can't fix it, it's effectively a paperweight.
But there may be devices which use glibc that I haven't covered. There may be set top boxes, televisions, cable modem / DSL gateways that are affected by this. There's likely a whole bunch of medical kit and control systems out there with this bug. Millions of potential consumer and industrial devices are impacted by this bug and it's likely never going to be patched. And since it's DNS, it's totally unencrypted/unauthorized, so anyone can hijack/spoof DNS to control what's going on.
So this is why I'm a big fan of open source software and being able to reflash your own devices. There's likely millions (or more!) devices this affects that is perfectly fine hardware but will never get software updates. This exposes a lot of people, with no easy fix besides "buy a replacement" and hope that it also isn't impacted. Heck, look at your home, office, workspace, outdoors - look at all those little electronic devices and think that at least some of them run Linux with this vulnerability and will be network connected. Any of them could be vulnerable to this and any of them may be owned by someone now.
This is "Hollywood" level of exploit. This is like, watching an episode of "Person of Interest" and realising all of those drive-by hacks are actually possible. This is like, anyone everywhere can do this - not just governments, but anyone with the minimum technical ability needed to run the exploit. Yes, this includes your internet connected fridge and your Internet-Of-Things lightbulbs.
Oh, and FreeBSD isn't vulnerable. Heh.
Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts
Wednesday, February 17, 2016
Friday, March 6, 2015
cache line aliasing effects, or "why is freebsd slower than linux?"
There was some threads on FreeBSD/DragonflyBSD mailing lists a few years ago (2012?) which talked about some math benchmarks being much slower on FreeBSD/DragonflyBSD versus Linux.
When the same benchmark is run on FreeBSD/DragonflyBSD using the Linux layer (ie, a linux binary compiled for linux, but run on BSD) it gives the same or better behaviour.
Some digging was done, and it turned out it was due to memory allocation patterns and memory layout. The jemalloc library allocates large chunks at page aligned boundaries, whereas the allocator in glibc under Linux does not.
I've put the code online in the hope that others can test and verify this:
https://github.com/erikarn/himenobmtxpa
The branch 'local/freebsd' has my local change to allow the allocator offset to be specified. The offset compounds on each allocation - so with an 'n' byte offset, the first allocation is 0 bytes offset from the page boundary, the next is 'n' bytes offset from the page boundary, the next is '2n' bytes offset, etc.
You can experiment with different values and get completely different behavioural results. It's non-trivial: there's a 100% speedup by using a 127 byte offset for each allocation, versus a 0 byte offset.
I'd like to investigate cache line aliasing effects further. There was work done a few years ago to offset mbuf headers in the FreeBSD kernel so they weren't all page-aligned or 256/512/1024 byte aligned - and apparently this gave a significant performance improvement. But it wasn't folded into FreeBSD. What I'd like to do is come up with some better strategies / profiling guides for identifying when this is actually happening so the underlying objects being accessed can be adjusted.
So - if anyone out there has any tips, hints or suggestions on how to do this, please let me know. I'd like to document and automate this testing.
When the same benchmark is run on FreeBSD/DragonflyBSD using the Linux layer (ie, a linux binary compiled for linux, but run on BSD) it gives the same or better behaviour.
Some digging was done, and it turned out it was due to memory allocation patterns and memory layout. The jemalloc library allocates large chunks at page aligned boundaries, whereas the allocator in glibc under Linux does not.
I've put the code online in the hope that others can test and verify this:
https://github.com/erikarn/himenobmtxpa
The branch 'local/freebsd' has my local change to allow the allocator offset to be specified. The offset compounds on each allocation - so with an 'n' byte offset, the first allocation is 0 bytes offset from the page boundary, the next is 'n' bytes offset from the page boundary, the next is '2n' bytes offset, etc.
You can experiment with different values and get completely different behavioural results. It's non-trivial: there's a 100% speedup by using a 127 byte offset for each allocation, versus a 0 byte offset.
I'd like to investigate cache line aliasing effects further. There was work done a few years ago to offset mbuf headers in the FreeBSD kernel so they weren't all page-aligned or 256/512/1024 byte aligned - and apparently this gave a significant performance improvement. But it wasn't folded into FreeBSD. What I'd like to do is come up with some better strategies / profiling guides for identifying when this is actually happening so the underlying objects being accessed can be adjusted.
So - if anyone out there has any tips, hints or suggestions on how to do this, please let me know. I'd like to document and automate this testing.
Labels:
cache,
dragonflybsd,
freebsd,
intel,
Linux,
performance
Monday, March 31, 2014
Meraki Sparky boards, and constant resetting
There's a Mesh internet project at Sudo Room and they've been doing some great work getting a platform up and running. However, like a lot of volunteer projects, they're working with whatever time and equipment they've been donated.
A few months ago they were donated a few hundred Meraki Sparky boards. They're an Atheros AR2317 SoC based device with an integrated 2GHz 802.11bg radio, 10/100 ethernet and.. well, a hardware watchdog that resets the board after five minutes.
Now, annoyingly, this reset occurs inside of Redboot too - which precludes them from being (fully) flashed before the unit reboots. Once the unit was flashed with OpenWRT, the unit still reboots every five minutes.
So, I started down the path of trying to debug this.
What did I know?
Firstly, the AR2317 watchdog doesn't have a way of resetting things itself - instead, all it can do is post an interrupt. The AR7161 and later SoCs do indeed have a way to do a full hardware reset if the watchdog is tickled.
Secondly, redboot has a few tricksy ways to manipulate the hardware:
A few months ago they were donated a few hundred Meraki Sparky boards. They're an Atheros AR2317 SoC based device with an integrated 2GHz 802.11bg radio, 10/100 ethernet and.. well, a hardware watchdog that resets the board after five minutes.
Now, annoyingly, this reset occurs inside of Redboot too - which precludes them from being (fully) flashed before the unit reboots. Once the unit was flashed with OpenWRT, the unit still reboots every five minutes.
So, I started down the path of trying to debug this.
What did I know?
Firstly, the AR2317 watchdog doesn't have a way of resetting things itself - instead, all it can do is post an interrupt. The AR7161 and later SoCs do indeed have a way to do a full hardware reset if the watchdog is tickled.
Secondly, redboot has a few tricksy ways to manipulate the hardware:
- 'x' can examine registers. Since we need them in KSEG1 (unmapped, uncached) then the reset registers (0x11000xxx becomes 0xb1000xxx.) Since its hardware access, we should do them as DWORDS and not bytes.
- 'mfill' can be used to write to registers.
Thirdly, there's an Atheros specific command - bdshow - which is surprisingly informative:
RedBoot> bdshow
name: Meraki Outdoor 1.0
magic: 35333131
cksum: 2a1b
rev: 10
major: 1
minor: 0
pciid: 0013
wlan0: yes 00:18:0a:50:7b:ae
wlan1: no 00:00:00:00:00:00
enet0: yes 00:18:0a:50:7b:ae
enet1: no 00:00:00:00:00:00
uart0: yes
sysled: no, gpio 0
factory: no, gpio 0
serclk: internal
cpufreq: calculated 184000000 Hz
sysfreq: calculated 92000000 Hz
memcap: disabled
watchdg: disabled (WARNING: for debugging only!)
serialNo: Q2AJYS5XMYZ8
Watchdog Gpio pin: 6
secret number: e2f019a200ee517e30ded15cdbd27b a72f9e30c8
.. hm. Watchdog GPIO pin 6? What's that?
name: Meraki Outdoor 1.0
magic: 35333131
cksum: 2a1b
rev: 10
major: 1
minor: 0
pciid: 0013
wlan0: yes 00:18:0a:50:7b:ae
wlan1: no 00:00:00:00:00:00
enet0: yes 00:18:0a:50:7b:ae
enet1: no 00:00:00:00:00:00
uart0: yes
sysled: no, gpio 0
factory: no, gpio 0
serclk: internal
cpufreq: calculated 184000000 Hz
sysfreq: calculated 92000000 Hz
memcap: disabled
watchdg: disabled (WARNING: for debugging only!)
serialNo: Q2AJYS5XMYZ8
Watchdog Gpio pin: 6
secret number: e2f019a200ee517e30ded15cdbd27b
.. hm. Watchdog GPIO pin 6? What's that?
Next, I tried manually manipulating the watchdog registers but nothing actually happened.
Then I wondered - what about manipulating the GPIO registers? Maybe there's a hardware reset circuit hooked up to GPIO 6 that needs to be toggled to keep the board from resetting.
Board: ap61
RAM: 0x80000000-0x82000000, [0x8003ddd0-0x80fe1000] available
FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
== Executing boot script in 2.000 seconds - enter ^C to abort
^C
RedBoot> # set direction of gpio6 to out
RedBoot> mfill -b 0xb1000098 -l 4 -p 0x00000043
RedBoot> x -b 0xb1000098
B1000098: 00 00 00 43 00 00 00 00 00 00 00 00 00 00 00 03 |...C............|
B10000A8: FF EF F7 B9 7D DF 5F FF 00 00 00 00 00 00 00 00 |....}._.........|
RedBoot> # pat gpio6 - set it high, then low.
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000042
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000002
.. then I manually did this every minute or so.
RedBoot>
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000042
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000002
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000042
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000002
.. so, the solution here seems to be to "set gpio6 to be output", then "pat it every 60 seconds."
RAM: 0x80000000-0x82000000, [0x8003ddd0-0x80fe1000] available
FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
== Executing boot script in 2.000 seconds - enter ^C to abort
^C
RedBoot> # set direction of gpio6 to out
RedBoot> mfill -b 0xb1000098 -l 4 -p 0x00000043
RedBoot> x -b 0xb1000098
B1000098: 00 00 00 43 00 00 00 00 00 00 00 00 00 00 00 03 |...C............|
B10000A8: FF EF F7 B9 7D DF 5F FF 00 00 00 00 00 00 00 00 |....}._.........|
RedBoot> # pat gpio6 - set it high, then low.
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000042
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000002
.. then I manually did this every minute or so.
RedBoot>
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000042
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000002
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000042
RedBoot> mfill -b 0xb1000090 -l 4 -p 0x00000002
.. so, the solution here seems to be to "set gpio6 to be output", then "pat it every 60 seconds."
I hope this helps people bring OpenWRT up on this board finally. There seems to be a few of them out there!
Thursday, April 5, 2012
The initial introduction into "it's the NIC, stupid!"
I've finally hit that dreaded condition which hardware guys hate - where a NIC is behaving badly.
In my case, an IBM/Lenovo Thinkpad T60 has been modified (not by me) to take an Atheros AR9280 NIC. Unfortunately, the NIC was proving to be very unstable when doing 802.11n throughput. The investigations did show I was doing something slightly incorrect with TX descriptors (and I've since fixed that) but the stability issues remained.
The Atheros NICs can expose some host interface error conditions via the AR_INTR_SYNC_CAUSE register. These include PCI(e) transaction timeouts, illegal chip access (eg whilst the MAC is asleep), parity errors, and other rather nice things. FreeBSD's HAL and Linux ath9k does have the register definition for what the bits do - but unfortunately we don't keep statistics.
In my particular case:
In my case, an IBM/Lenovo Thinkpad T60 has been modified (not by me) to take an Atheros AR9280 NIC. Unfortunately, the NIC was proving to be very unstable when doing 802.11n throughput. The investigations did show I was doing something slightly incorrect with TX descriptors (and I've since fixed that) but the stability issues remained.
The Atheros NICs can expose some host interface error conditions via the AR_INTR_SYNC_CAUSE register. These include PCI(e) transaction timeouts, illegal chip access (eg whilst the MAC is asleep), parity errors, and other rather nice things. FreeBSD's HAL and Linux ath9k does have the register definition for what the bits do - but unfortunately we don't keep statistics.
In my particular case:
- I'd see AR_INTR_SYNC_LOCAL_TIMEOUT occur. This is because a PCI(e) transaction didn't complete in time. I can tune these timeouts via a local register but that's not the point - I was seeing these errors when receiving only beacons from the access point. That's a bit silly.
- I'd also see AR_INTR_SYNC_RADM_CPL_DLLP_ABORT, which is an indication that the PCIe layer isn't behaving well.
I swapped it out with another AR9280 based NIC and suddenly all the instabilities have gone away. No TX hangs, no missed TX interrupts. Everything looks great.
So as an open source developer, I want to try and put some tools into the hands of the community to be able to debug what's going on - or, if that's not possible, at least get some indication that things are going wrong. Right now the only thing people see is "I see TX timeouts, it must be the driver/chip fault." There's too much going on to be able to conclude that.
My game plan is this:
- Implement statistics keeping for each of the SYNC interrupts and expose those via a diagnostic interface. Ben Grear has done something similar for Linux ath9k after a private email discussion. He's also seeing MAC sleep accesses, so it's quite likely we'll start finding/squishing these.
- Take the offending laptop/NIC to the office and attach it to a very expensive and fancy looking PCIe analyser. I'm hoping we'll find something really silly occuring - like lots of sleep state transitions, or a high number of parity errors.
- Try documenting this a lot better so users are able to understand what's going on when their NIC is misbehaving.
Monday, February 13, 2012
.. and the price of packaging up software? Billions.
A friend of mine from Perth recently wrote an article outlining the "cost" of Debian Wheezy:
http://blog.james.rcpt.to/2012/02/13/debian-wheezy-us19-billion-your-price-free/
To quote:
"In my analysis the projected cost of producing Debian Wheezy in February 2012 is US$19,070,177,727 (AU$17.7B, EUR€14.4B, GBP£12.11B), making each package’s upstream source code wrth an average of US$1,112,547.56 (AU$837K) to produce. Impressively, this is all free (of cost)."
Now this has apparently caused a bit of a stir among Linux and IT news sites. It's a large number, right? It's all free, right?
However - Debian for the most part is a package repository. Sure, a lot of effort goes into building and maintaining that - and I think _that_ should be assigned a cost - but I think counting all of those package upstreams as part of Debian is hiding the true nature of software development.
According to Ohloh, the cost of producing FreeBSD, at $72,000 a year per programmer, would be $ 243,777,135, _before_ all of the packages in the FreeBSD ports repository. FreeBSD has over 23,000 packages too, just like Debian - if those were also counted, it may start to push that figure far up from millions to billions.
Does it mean Debian Wheezy is equivalent of $20B of effort? Maybe. But then a tiny (comparatively) more effort and you end up with FreeBSD. Or, with different effort - Redhat. Or Gentoo. Or Mandrake. Or NetBSD. Or OpenBSD. Or MacPorts/Fink, which packages this similar software for MacOS X.
What I guess I'm trying to say is this. You get cool stuff from programmers for free. Including that in your project "cost" just seems silly.
http://blog.james.rcpt.to/
To quote:
"In my analysis the projected cost of producing Debian Wheezy in February 2012 is US$19,070,177,727 (AU$17.7B, EUR€14.4B, GBP£12.11B), making each package’s upstream source code wrth an average of US$1,112,547.56 (AU$837K) to produce. Impressively, this is all free (of cost)."
Now this has apparently caused a bit of a stir among Linux and IT news sites. It's a large number, right? It's all free, right?
However - Debian for the most part is a package repository. Sure, a lot of effort goes into building and maintaining that - and I think _that_ should be assigned a cost - but I think counting all of those package upstreams as part of Debian is hiding the true nature of software development.
According to Ohloh, the cost of producing FreeBSD, at $72,000 a year per programmer, would be $ 243,777,135, _before_ all of the packages in the FreeBSD ports repository. FreeBSD has over 23,000 packages too, just like Debian - if those were also counted, it may start to push that figure far up from millions to billions.
Does it mean Debian Wheezy is equivalent of $20B of effort? Maybe. But then a tiny (comparatively) more effort and you end up with FreeBSD. Or, with different effort - Redhat. Or Gentoo. Or Mandrake. Or NetBSD. Or OpenBSD. Or MacPorts/Fink, which packages this similar software for MacOS X.
What I guess I'm trying to say is this. You get cool stuff from programmers for free. Including that in your project "cost" just seems silly.
Subscribe to:
Posts (Atom)