Gentoo Logo
Gentoo Logo Side
Gentoo Spaceship

Contributors:
. Aaron W. Swenson
. Agostino Sarubbo
. Alexey Shvetsov
. Alexis Ballier
. Alexys Jacob
. Alice Ferrazzi
. Alice Ferrazzi
. Andreas K. Hüttel
. Anthony Basile
. Arun Raghavan
. Bernard Cafarelli
. Brian Harring
. Christian Ruppert
. Chí-Thanh Christopher Nguyễn
. Denis Dupeyron
. Detlev Casanova
. Diego E. Pettenò
. Domen Kožar
. Doug Goldstein
. Eray Aslan
. Fabio Erculiani
. Gentoo Haskell Herd
. Gentoo Miniconf 2016
. Gentoo Monthly Newsletter
. Gentoo News
. Gilles Dartiguelongue
. Greg KH
. Göktürk Yüksek
. Hanno Böck
. Hans de Graaff
. Ian Whyman
. Jan Kundrát
. Jason A. Donenfeld
. Jeffrey Gardner
. Joachim Bartosik
. Johannes Huber
. Jonathan Callen
. Jorge Manuel B. S. Vicetto
. Kristian Fiskerstrand
. Lance Albertson
. Liam McLoughlin
. Luca Barbato
. Marek Szuba
. Mart Raudsepp
. Matt Turner
. Matthew Thode
. Michael Palimaka
. Michal Hrusecky
. Michał Górny
. Mike Doty
. Mike Gilbert
. Mike Pagano
. Nathan Zachary
. Pacho Ramos
. Patrick Kursawe
. Patrick Lauer
. Patrick McLean
. Paweł Hajdan, Jr.
. Petteri Räty
. Piotr Jaroszyński
. Rafael G. Martins
. Remi Cardona
. Richard Freeman
. Robin Johnson
. Ryan Hill
. Sean Amoss
. Sebastian Pipping
. Steev Klimaszewski
. Stratos Psomadakis
. Sven Vermeulen
. Sven Wegener
. Tom Wijsman
. Tomáš Chvátal
. Yury German
. Zack Medico

Last updated:
May 29, 2017, 16:05 UTC

Disclaimer:
Views expressed in the content published here do not necessarily represent the views of Gentoo Linux or the Gentoo Foundation.


Bugs? Comments? Suggestions? Contact us!

Powered by:
Planet Venus

Welcome to Gentoo Universe, an aggregation of weblog articles on all topics written by Gentoo developers. For a more refined aggregation of Gentoo-related topics only, you might be interested in Planet Gentoo.

May 29, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
Laptop ban, and threat models (May 29, 2017, 13:03 UTC)

At some point this past month, the USA has been talking about banning laptops in cabin luggage, from flight coming from Europe as well as the Middle East, where such a ban is already in effect. This appears to have been reversed just a week later, so it may not be quite a problem right now.

Many words have been spent already to point out how pointless, unsafe, and ultimately futile this ban is from the stated reasons, and the security risks connected with the Government (capital G because this is mostly an abstract at this point) having access to your laptop without your presence, so I won’t be spending any time for that. I may come back to talking about practical security aspects, including mitigation, later, but for this post, I’m mostly interested in talking about the threat modeling, which should always be at the base of security practice, but often it isn’t.

Let’s handwave the first bullet point, and assume that anyone with the means who want to mess with you, either actively (attacking you) or passively (monitoring you), can take over your laptop against you if they have physical access. Any laptop, and an amount of time that is consistent with the time the laptop is out of your control in a situation such as checking it in a flight. As I said this has been discussed and is being discussed, and it’s not the kind of thing that I’m interested in talking about.

The question I want to ask is: who should be worried about their laptops? Everybody or a limited public? And to answer this question, I will use three straw travellers, and give examples of why all three of these should care about this particular problem, even though it may not appear so at first. These actors are drawn upon the information I have about myself, my sister, and my brother in law, because the three of us have an interesting different set of problems and fit widely different categories.

So there is me, working for a multinational company that, in its entirety, has access to a significant user base and personally-identifiable information (PII) (although I don’t have access to much of that, luckily for me). My sister, who works for a small, local company in Italy, that used to have PII from the local government, but at most nowadays has access to clothing and accessory manufacturers model and price information. And my brother in law, that works in the sales department for a different kind of multinational company, in a specific industrial manufacturing sector, holding a number of patents on their technologies.

Is every government interested in the three of us equally? I think it’s clear it’s not the case. The United States, with their current government being worse than the twenty years of Berlusconi we had in Italy, is moving further and further away from a democracy, and then having the ability to target people based on profiling that can only be done with PII no company in their sane mind would ever surrender them short of a hostile takeover, would probably be interested in me. Either because my laptop could contain, or be used to gather, credentials to access said PII, or because through me they can work their way through to more interesting targets.

Would they care about either my sister or my brother in law? Probably only if they knew the connection and were planning on getting me indirectly, which I would expect they wouldn’t do, as I’m too little a number in the organization for me to be worth that amount of time. Getting me first hand, sure, through third parties? Probably not. It would then be easy to discount the problem: who cares, if you’re a possible target of the US government, use burner laptops, if you’re not, check in your laptop and stop complaining! Except.

Except you can imagine a different government, say one that people have been very sceptical about because they tend to have a heavy hand on both their local and export market, and that has been suggested plays a role in industrial espionage on foreign companies. Such a government may actually be interested in my brother in law’s computer. While he doesn’t work on the technology himself any more, he probably gets to know about launches, new sale and, most importantly, prices they apply to their customers. If the government is out to make money, rather than profile people, he’s a target.

But governments, usually, play by some rules. Well, maybe not the US government this year, but even the TSA would have some regard about which luggage gets inspected, and how the content of said luggage is treated. My checked in luggage got inspected multiple times (because I flew a whole lot too much across the states these past few years), and they never broke or misplaced anything. In one case they actually repacked my bag better than I did myself, and I felt bad to have to empty it out to take my charger out.

What I would be more worried about is the baggage handling on the European airport side. It was in the 90s that Venice Marco Polo had a huge problem with theft from the checked in luggage, but my mother is still afraid of that and upset, because she lost a number of souvenirs from her trip to Madrid (back when such a trip was worth a lot more money, and she would get it as a prize for selling Avon products). But if valuable laptops are in the checked luggage, would you not expect this to happen again? This is something that everybody risks being a target of. But of course it is very obvious and easy to notice and possibly make right.

What if there are criminals among the baggage handlers that are more sophisticated than that, and can actually use techniques similar to the government’s to subvert your laptop? We have seen this happening already with the WannaCry attack just now, this is more than just possible. But of course just a ransomware in this case would be a lot of wasted effort and just as visible as the pure theft.

But what about criminals who may be looking for making much more money from CEO fraud? This kind of fraud is not new, and it’s spread enough, and can make quite a bit of money. In this case, the laptop of someone working in sales for a medium-sized multinational company, or someone working for a small company that contracts out for a much bigger fashion accessory company would be very interesting. Among other things, they are likely to let them in on the conversation happening with customers, and from there to understand their workflow of purchase orders and invoices… and if you just wait enough time between the travel and the scam, it’s going to be very hard to detect.

With these criminals, both my sister and my brother in law are targets, myself a significant amount less, because I work in the engineering department, and thus I have no access whatsoever to purchase orders and similar. Having an invoice arrive from me would raise all the possible red flags and give the criminals away immediately.

Now, there are of course more stereotypes or templates of people, and I’m sure that I can find one where storing a laptop in the checked luggage does not, actually, cause a significant risk. But my first impressions of having thought about this is that we should all be careful, and paranoid, about this particular attack vector, even more so than about end-to-end encrypted messaging, which has instead taken over the conversation for the past year.

May 26, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)

I started writing this while sitting on a very comfortable bed in a fancy hotel in Hong Kong. I spent the weekend in the SAR in the middle of a business trip to Shanghai, thanks to the multi-enty visa I managed to be given this time.

Whith a not quite relaxing trip to Pudong Airport in Shanghai (all my fault!), and the flight being delayed for well over an hour due to traffic control (weather forced a number of other flights late, even though by the time it was our turn, the weather was vastly fine), I got to the airport in a bit of a short temper (even by my own standards). The hotel was supposed to have a mobile wi-fi for me, but as I arrived almost at midnight, and the train requiring me to change stations, and not sure how long it would run, I was ready to spend more money for a Uber. That meant getting an Internet connection before getting to the hotel.

I’m usually okay with using portable hotspots (like the one I’m reverse engineering) but the problem here is that you have to rent one, and that means binging it back before flying out, which is a hassle. Of all the booth around me when I got in the arrivals’ hall, only one advertised SIM cards, so I headed towards that. After a good ten minutes waiting with the clerk explaining a guy how the thing worked, I gave up and proceeded to one of the desks that rented hotspots, but the card payment happens online, and it ended up blocked on Verified by VISA – and while I could have looked up the VBV password on LastPass, it seemed too sketchy. So I headed back to the SIM booth, as they had no customers.

What it turned out to be, is a bit quirky: they sold i-Sim data cards. The quirk is that while you buy a SIM and a 7- or 30-days plan, and you get 200 MB of data. Except, you actually have nearly unlimited data during the period, just as long as you click on some ads in their app.

It sounds like a bit of a scam, doesn’t it? It definitely reminded me of the Pay to surf stuff that was going on back in the ‘90s, and that, I’ll admit, at the time got me too. But it turned out to be working quite fine in Hong Kong, for me. Let me describe the experience.

The feature that made me more interested than wary about this, despite the bell I kept hearing, was that the service is available in Singapore, in addition to Hong Kong, Macau, Taiwan and Korea. This was relevant because after my trip to Shanghai, I headed to Singapore for SREcon Asia & Australia, and I was already planning to get a SIM there too, after all I am an Ingress player.

Since it’s just two days here, and then a few more the week after the next in Singapore, a single 7-days subscription wouldn’t have helped much, so I originally intended to get the 30-days one. The price was reasonable, HK$129 for the 30-days, particularly when you consider that the mobile hotspot rent would be HK$50/day with a minimum of four days. As it happens, the clerk was as tired as me, and by mistake activated a single 7-day pass on the SIM, which was supposed to be HK$59 (down from HK$69 regular price). When he realised the mistake, he offered to make it up for me by giving me the pre-order price (HK$49), and sell me two SIMs, the second one not activated yet, but with an already attached 7-day plan, which turned ended up being quite the deal for me. For those wondering, it’s just a bit less of €12.

For the i-Sim to be enabled, you have to activate it with their app. I checked the app permission both when I installed and when it requested extra, and it seems to be sane. It does ask for phone identity, but works fine without. It asks for camera permissions if you want to scan the barcode rather than typing the long SIM identifier by hand (particularly useful if you don’t know the manufacturer code by heart like the clerk did, except the gray barcode is effectively unreadable by the phone’s camera so I ended up having to type it anyway.

In the app, beside having a way to check how much data you used, there are a number of hexagons for different “areas” of advertisement. F&B (food and beverage) is the one the clerk recommended with the most ads, but I checked the others out and I even found an ads for the Intercontinental Hotel. Each time you select one of the ads with the i-Sim green logo in the bottom corner (not all of them do), a countdown indicator appears on the top-right. Only close the advertisement once it completes, and i-Sim will give you another 10 or 20MB credit (appears to depend on advertiser). It behaves like so many mobile games nowadays, where you can get more in-game currencies if you watch ads to completion.

As far as I can tell, the ads are not specific to the location you run them in, but they appear to be always Hong Kong’s. They also appear to have improved them during my week in China, as they went from being simply static images my first time, to being webviews pointing to the OpenRice or Facebook pages of the place, at least for most restaurants. I think this may be a bit buggy as now the counter appears and completes before the webview even finishes to load in some cases, so I assume they’ll have to find a combined option at some point.

On the technical side, the SIM uses the network of Three HK, which is ironic given my recent spat with Three Ireland, but it also means it appears to cover the tiny country very well. It does have its own APN settings though. The clerk insisted on setting them up himself, similarly to how the one in Shanghai did, although this time I managed to watch him doing so. He also explained to me how to set them again if I need for the new card, although I kept telling him I knew that. In Singapore it uses StarHub, and also seems to have good coverage around the city.

As a reference, the service will activate on a new card only once the card registers on the network. Which means you can’t start “topping up” the data until you actually land where the card will work, which is what I was hoping on doing while in China, heading to Singapore. Despite that the procedure was quite simple: switch the card number from the app, confirm you want to deactivate the old card, then once on the flight switch the SIM cards around, reset the APN to the NTT one, and that’s it. It’ll take a while to register on the network the first time, but for me it registered fine just after immigration clearance and before picking up the luggage.

Both the app, and the card, appear to have worked fine for me. I have used to “top up” over a GB of data, even though I clearly didn’t need that much, and it used less than 50MB itself. Given you can also use it over WiFi, it makes it fairly convenient. The ads I’ve seen are all in Chinese, which means they vastly fly over my head, and I only see the drawings, although there is the occasional image that includes English text to invite you to try some restaurant or other. There appears to have been a promotion with IHG as well, although it got me to an error page when I clicked on it, too bad.

So how does this fare, money for service? I’m happy with it as it is. I’m not sure if the prices of connectivity in Hong Kong or Singapore make this more expensive, but €6 for a week of nearly limitless connectivity is more than reasonable in my experience. The fact that you can actually not bother topping up the 200MB until you actually need to, means the ads are not even in your way.

Do they track you? Maybe, but how I wouldn’t know. Yes I had to sign up for an account, but they don’t appear to ask you for much information. And even if they were to do traffic profiling, they would see very little as obviously all (or nearly all) my connections are encrypted already (Chrome’s Data Saver takes care of the random HTTP link that still go around).

The only thing that makes me sad is that while they say the SIM is reusable, it only is reusable for the 90 days after you activated your last plan. I don’t think I’ll be back to Asia within three months, because among other things I’m mostly booked solid for that time frame, which makes moot this particular point. I got lucky to have gone to HK before Singapore, and I may be able to hand one of the two SIMs to one of my colleagues, if they allow me to hand the SIM to a different account.

I wonder if they are profitable, and if they’ll stay in business or not. For this trip, it looks like it was a good deal for me.

May 24, 2017

Description:
ytnef is Yeraze’s TNEF Stream Reader – for winmail.dat files.

The complete ASan output of the issue:

# ytnefprint $FILE
==22808==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61800000039e at pc 0x7f6b57c2fcb8 bp 0x7ffd8ca179d0 sp 0x7ffd8ca179c8
READ of size 1 at 0x61800000039e thread T0
    #0 0x7f6b57c2fcb7 in DecompressRTF /tmp/ytnef-1.9.2/lib/ytnef.c:1549:31
    #1 0x7f6b57c20195 in MAPIPrint /tmp/ytnef-1.9.2/lib/ytnef.c:1417:39
    #2 0x508f50 in PrintTNEF /tmp/ytnef-1.9.2/ytnefprint/main.c:169:5
    #3 0x50882e in main /tmp/ytnef-1.9.2/ytnefprint/main.c:84:5
    #4 0x7f6b56d3f78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x419c38 in _start (/usr/bin/ytnefprint+0x419c38)

0x61800000039e is located 0 bytes to the right of 798-byte region [0x618000000080,0x61800000039e)
allocated by thread T0 here:
    #0 0x4cf7e0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7f6b57c1a527 in TNEFFillMapi /tmp/ytnef-1.9.2/lib/ytnef.c:513:26
    #2 0x7f6b57c15384 in TNEFMapiProperties /tmp/ytnef-1.9.2/lib/ytnef.c:396:7
    #3 0x7f6b57c2ab47 in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1184:15
    #4 0x7f6b57c299d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10
    #5 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9
    #6 0x7f6b56d3f78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/ytnef-1.9.2/lib/ytnef.c:1549:31 in DecompressRTF
Shadow bytes around the buggy address:
  0x0c307fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff8030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff8040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff8050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff8060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c307fff8070: 00 00 00[06]fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff80b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff80c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==22808==ABORTING

Affected version:
1.9.2

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
N/A

Reproducer:
https://github.com/asarubbo/poc/blob/master/00244-ytnef-heapoverflow-DecompressRTF

Timeline:
2017-03-27: bug discovered and reported to upstream
2017-05-24: blog post about the issue

Note:
This bug was found with American Fuzzy Lop.

Permalink:

ytnef: heap-based buffer overflow in DecompressRTF (ytnef.c)

Description:
ytnef is Yeraze’s TNEF Stream Reader – for winmail.dat files.

The complete ASan output of the issue:

# ytnefprint $FILE
==11998==AddressSanitizer CHECK failed: /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_common.cc:120 "((0 && "unable to mmap")) != (0)" (0x0, 0x0)
    #0 0x4d95cf in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_rtl.cc:69
    #1 0x4f4335 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_termination.cc:79
    #2 0x4e3962 in __sanitizer::ReportMmapFailureAndDie(unsigned long, char const*, char const*, int, bool) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_common.cc:120
    #3 0x4ed265 in __sanitizer::MmapOrDie(unsigned long, char const*, bool) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_posix.cc:132
    #4 0x424c6a in __sanitizer::LargeMmapAllocator::Allocate(__sanitizer::AllocatorStats*, unsigned long, unsigned long) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_allocator_secondary.h:41
    #5 0x424c6a in __sanitizer::CombinedAllocator<__sanitizer::SizeClassAllocator64, __sanitizer::SizeClassAllocatorLocalCache<__sanitizer::SizeClassAllocator64 >, __sanitizer::LargeMmapAllocator >::Allocate(__sanitizer::SizeClassAllocatorLocalCache<__sanitizer::SizeClassAllocator64 >*, unsigned long, unsigned long, bool, bool) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_allocator_combined.h:70
    #6 0x424c6a in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:407
    #7 0x41f1fb in __asan::Allocator::Calloc(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:605
    #8 0x41f1fb in __asan::asan_calloc(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:786
    #9 0x4cf7ba in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:75
    #10 0x7fe45c3e4e53 in TNEFFillMapi /tmp/ytnef-1.9.2/lib/ytnef.c:424:19
    #11 0x7fe45c3e1384 in TNEFMapiProperties /tmp/ytnef-1.9.2/lib/ytnef.c:396:7
    #12 0x7fe45c3f6b47 in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1184:15
    #13 0x7fe45c3f59d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10
    #14 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9
    #15 0x7fe45b50b78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #16 0x419c38 in _start (/usr/bin/ytnefprint+0x419c38)

Affected version:
1.9.2

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
N/A

Reproducer:
https://github.com/asarubbo/poc/blob/master/00246-ytnef-memallocfailures

Timeline:
2017-03-27: bug discovered and reported to upstream
2017-05-24: blog post about the issue

Note:
This bug was found with American Fuzzy Lop.

Permalink:

ytnef: memory allocation failure in TNEFFillMapi (ytnef.c)

Description:
ytnef is Yeraze’s TNEF Stream Reader – for winmail.dat files.

The complete ASan output of the issue:

# ytnefprint $FILE
==12532==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000014 at pc 0x7f8e3c35544e bp 0x7ffeb883d890 sp 0x7ffeb883d888                                                                         
READ of size 1 at 0x602000000014 thread T0                                                                                                                                                                        
    #0 0x7f8e3c35544d in SwapDWord /tmp/ytnef-1.9.2/lib/ytnef.c:180:28                                                                                                                                            
    #1 0x7f8e3c35544d in TNEFFillMapi /tmp/ytnef-1.9.2/lib/ytnef.c:430                                                                                                                                            
    #2 0x7f8e3c360b47 in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1184:15                                                                                                                                           
    #3 0x7f8e3c35f9d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10                                                                                                                                       
    #4 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9                                                                                                                                                   
    #5 0x7f8e3b47578f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                                                                                        
    #6 0x419c38 in _start (/usr/bin/ytnefprint+0x419c38)                                                                                                                                                          
                                                                                                                                                                                                                  
0x602000000014 is located 0 bytes to the right of 4-byte region [0x602000000010,0x602000000014)                                                                                                                   
allocated by thread T0 here:                                                                                                                                                                                      
    #0 0x4cf7e0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74                                                                          
    #1 0x7f8e3c36072a in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1154:12                                                                                                                                           
    #2 0x7f8e3c35f9d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10                                                                                                                                       
    #3 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9                                                                                                                                                   
    #4 0x7f8e3b47578f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                                                                                        
                                                                                                                                                                                                                  
SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/ytnef-1.9.2/lib/ytnef.c:180:28 in SwapDWord                                                                                                                  
Shadow bytes around the buggy address:                                                                                                                                                                            
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
=>0x0c047fff8000: fa fa[04]fa fa fa fa fa fa fa fa fa fa fa fa fa                                                                                                                                                 
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa                                                                                                                                                 
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa                                                                                                                                                 
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa                                                                                                                                                 
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa                                                                                                                                                 
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa                                                                                                                                                 
Shadow byte legend (one shadow byte represents 8 application bytes):                                                                                                                                              
  Addressable:           00                                                                                                                                                                                       
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==12532==ABORTING

Affected version:
1.9.2

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
N/A

Reproducer:
https://github.com/asarubbo/poc/blob/master/00245-ytnef-heapoverflow-SwapDWord

Timeline:
2017-03-27: bug discovered and reported to upstream
2017-05-24: blog post about the issue

Note:
This bug was found with American Fuzzy Lop.

Permalink:

ytnef: heap-based buffer overflow in SwapDWord (ytnef.c)

Description:
ytnef is Yeraze’s TNEF Stream Reader – for winmail.dat files.

The complete ASan output of the issue:

# ytnefprint $FILE
==22220==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000038 at pc 0x7ff75139d8eb bp 0x7ffeed684ad0 sp 0x7ffeed684ac8
READ of size 1 at 0x602000000038 thread T0
    #0 0x7ff75139d8ea in SwapWord /tmp/ytnef-1.9.2/lib/ytnef.c:153:28
    #1 0x7ff75139d8ea in TNEFDateHandler /tmp/ytnef-1.9.2/lib/ytnef.c:682
    #2 0x7ff7513b4b47 in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1184:15
    #3 0x7ff7513b39d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10
    #4 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9
    #5 0x7ff7504c978f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #6 0x419c38 in _start (/usr/bin/ytnefprint+0x419c38)

0x602000000038 is located 0 bytes to the right of 8-byte region [0x602000000030,0x602000000038)
allocated by thread T0 here:
    #0 0x4cf7e0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7ff7513b472a in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1154:12
    #2 0x7ff7513b39d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10
    #3 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9
    #4 0x7ff7504c978f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/ytnef-1.9.2/lib/ytnef.c:153:28 in SwapWord
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa fd fa fa fa 00[fa]fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==22220==ABORTING

Affected version:
1.9.2

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
N/A

Reproducer:
https://github.com/asarubbo/poc/blob/master/00243-ytnef-heapoverflow-SwapWord

Timeline:
2017-03-27: bug discovered and reported to upstream
2017-05-24: blog post about the issue

Note:
This bug was found with American Fuzzy Lop.

Permalink:

ytnef: heap-based-buffer overflow in SwapWord (ytnef.c)

Description:
ytnef is Yeraze’s TNEF Stream Reader – for winmail.dat files.

The complete ASan output of the issue:

# ytnefprint $FILE
==12467==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f59364c62b6 bp 0x7ffe1b8d4af0 sp 0x7ffe1b8d4278 T0)
==12467==The signal is caused by a READ memory access.
==12467==Hint: address points to the zero page.
    #0 0x7f59364c62b5 in strlen /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/string/../sysdeps/x86_64/strlen.S:76
    #1 0x43e99c in __interceptor_strlen.part.31 /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:282
    #2 0x7f593734a162 in MAPIPrint /tmp/ytnef-1.9.2/lib/ytnef.c:1437:15
    #3 0x508f50 in PrintTNEF /tmp/ytnef-1.9.2/ytnefprint/main.c:169:5
    #4 0x50882e in main /tmp/ytnef-1.9.2/ytnefprint/main.c:84:5
    #5 0x7f593646878f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #6 0x419c38 in _start (/usr/bin/ytnefprint+0x419c38)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/string/../sysdeps/x86_64/strlen.S:76 in strlen
==12467==ABORTING

Affected version:
1.9.2

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
N/A

Reproducer:
https://github.com/asarubbo/poc/blob/master/00241-ytnef-nullptr-MAPIPrint

Timeline:
2017-03-27: bug discovered and reported to upstream
2017-05-24: blog post about the issue

Note:
This bug was found with American Fuzzy Lop.

Permalink:

ytnef: NULL pointer dereference in MAPIPrint (ytnef.c)

Description:
ytnef is Yeraze’s TNEF Stream Reader – for winmail.dat files.

The complete ASan output of the issue:

# ytnefprint $FILE
==11928==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000001031 at pc 0x00000049df8d bp 0x7ffd1e1feb20 sp 0x7ffd1e1fe2d0
READ of size 2 at 0x602000001031 thread T0
    #0 0x49df8c in printf_common(void*, char const*, __va_list_tag*) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:544
    #1 0x49ea7a in __interceptor_vprintf /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1388
    #2 0x49eb37 in printf /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1434
    #3 0x509747 in PrintTNEF /tmp/ytnef-1.9.2/ytnefprint/main.c:195:7
    #4 0x50882e in main /tmp/ytnef-1.9.2/ytnefprint/main.c:84:5
    #5 0x7f16830da78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #6 0x419c38 in _start (/usr/bin/ytnefprint+0x419c38)

0x602000001031 is located 0 bytes to the right of 1-byte region [0x602000001030,0x602000001031)
allocated by thread T0 here:
    #0 0x4cf7e0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7f1683faf8bb in TNEFAttachmentFilename /tmp/ytnef-1.9.2/lib/ytnef.c:752:19
    #2 0x7f1683fc5b47 in TNEFParse /tmp/ytnef-1.9.2/lib/ytnef.c:1184:15
    #3 0x7f1683fc49d3 in TNEFParseFile /tmp/ytnef-1.9.2/lib/ytnef.c:1042:10
    #4 0x508814 in main /tmp/ytnef-1.9.2/ytnefprint/main.c:80:9
    #5 0x7f16830da78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:544 in printf_common(void*, char const*, __va_list_tag*)
Shadow bytes around the buggy address:
  0x0c047fff81b0: fa fa 00 00 fa fa 04 fa fa fa 00 00 fa fa 00 fa
  0x0c047fff81c0: fa fa 00 00 fa fa 00 fa fa fa 00 00 fa fa 04 fa
  0x0c047fff81d0: fa fa 00 00 fa fa 00 05 fa fa 00 00 fa fa 00 00
  0x0c047fff81e0: fa fa 05 fa fa fa 00 00 fa fa 00 05 fa fa 00 00
  0x0c047fff81f0: fa fa 00 00 fa fa fd fd fa fa fd fd fa fa fd fd
=>0x0c047fff8200: fa fa fd fa fa fa[01]fa fa fa 00 00 fa fa 04 fa
  0x0c047fff8210: fa fa 00 00 fa fa 04 fa fa fa 00 00 fa fa 04 fa
  0x0c047fff8220: fa fa 00 00 fa fa 04 fa fa fa 00 00 fa fa 00 fa
  0x0c047fff8230: fa fa 00 00 fa fa 00 fa fa fa 00 00 fa fa 04 fa
  0x0c047fff8240: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 01 fa
  0x0c047fff8250: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==11928==ABORTING

Affected version:
1.9.2

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
N/A

Reproducer:
https://github.com/asarubbo/poc/blob/master/00242-ytnef-heapoverflow-PrintTNEF

Timeline:
2017-03-27: bug discovered and reported to upstream
2017-05-24: blog post about the issue

Note:
This bug was found with American Fuzzy Lop.

Permalink:

ytnef: heap-based buffer overflow in PrintTNEF (ytnefprint/main.c)

May 21, 2017
qpdf: three infinite loop in libqpdf (May 21, 2017, 09:25 UTC)

Description:
qpdf QPDF is a command-line program that does structural, content-preserving transformations on PDF files.

I discovered three infinite loop. Upstream didn’t provide a feedback, so they might have the same root cause.

# qpdf $FILE -
==8000==ERROR: AddressSanitizer: stack-overflow on address 0x7fff9cf4efd8 (pc 0x7f925abe7e23 bp 0x7fff9cf4f050 sp 0x7fff9cf4efe0 T0)
    #0 0x7f925abe7e22 in QPDFObjectHandle::assertInitialized() const /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1380
    #1 0x7f925abe38aa in QPDFObjectHandle::isIndirect() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:241:5
    #2 0x7f925abe38aa in QPDFObjectHandle::releaseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:71
    #3 0x7f925ad2ca5d in QPDFObjectHandle::ReleaseResolver::releaseResolved(QPDFObjectHandle&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObjectHandle.hh:554:8
    #4 0x7f925ad2ca5d in QPDF_Array::releaseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Array.cc:19
    #5 0x7f925abe3c24 in QPDFObject::ObjAccessor::releaseResolved(QPDFObject*) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObject.hh:67:6
    #6 0x7f925abe3c24 in QPDFObjectHandle::releaseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:80
    #7 0x7f925ad30a6e in QPDFObjectHandle::ReleaseResolver::releaseResolved(QPDFObjectHandle&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObjectHandle.hh:554:8
    #8 0x7f925ad30a6e in QPDF_Dictionary::releaseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:23
    #9 0x7f925abe3c24 in QPDFObject::ObjAccessor::releaseResolved(QPDFObject*) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObject.hh:67:6
    #10 0x7f925abe3c24 in QPDFObjectHandle::releaseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:80
    #11 0x7f925ad30a6e in QPDFObjectHandle::ReleaseResolver::releaseResolved(QPDFObjectHandle&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDFObjectHandle.hh:554:8
    #12 0x7f925ad30a6e in QPDF_Dictionary::releaseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:23

Reproducer:
https://github.com/asarubbo/poc/blob/master/00176-qpdf-infiniteloop1
CVE:
CVE-2017-9208

############################

# qpdf $FILE -
    #0 0x427108 in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) /tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:323
    #1 0x50ce78 in operator new(unsigned long) /tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_new_delete.cc:78
    #2 0x7fe47c18de58 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator const&) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf3e58)
    #3 0x7fe47c18ec3a in std::string::_Rep::_M_clone(std::allocator const&, unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4c3a)
    #4 0x7fe47c18ece3 in std::string::reserve(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4ce3)
    #5 0x7fe47c656405 in std::string::push_back(char) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:1072:10
    #6 0x7fe47c656405 in std::string::operator+=(char) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:968
    #7 0x7fe47c656405 in QPDFTokenizer::presentCharacter(char) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFTokenizer.cc:189
    #8 0x7fe47c65d19a in QPDFTokenizer::readToken(PointerHolder, std::string const&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFTokenizer.cc:519:6
    #9 0x7fe47c61da83 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:873:23
    #10 0x7fe47c61f018 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:939:15
    #11 0x7fe47c6122d4 in QPDFObjectHandle::parse(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:841:12
    #12 0x7fe47c553ec1 in QPDF::readObject(PointerHolder, std::string const&, int, int, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1017:31
    #13 0x7fe47c542a0b in QPDF::reconstruct_xref(QPDFExc&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:393:7
    #14 0x7fe47c57e826 in QPDF::readObjectAtOffset(bool, long long, std::string const&, int, int, int&, int&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1359:6
    #15 0x7fe47c59e56d in QPDF::resolve(int, int) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1474:7
    #16 0x7fe47c5f4854 in QPDF::Resolver::resolve(QPDF*, int, int) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDF.hh:520:19
    #17 0x7fe47c5f4854 in QPDFObjectHandle::dereference() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1520
    #18 0x7fe47c626227 in QPDFObjectHandle::isName() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:184:5
    #19 0x7fe47c626227 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1074
    #20 0x7fe47c61f018 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:939:15
    #21 0x7fe47c6122d4 in QPDFObjectHandle::parse(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:841:12
    #22 0x7fe47c553ec1 in QPDF::readObject(PointerHolder, std::string const&, int, int, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1017:31
    #23 0x7fe47c542a0b in QPDF::reconstruct_xref(QPDFExc&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:393:7
    #24 0x7fe47c57e826 in QPDF::readObjectAtOffset(bool, long long, std::string const&, int, int, int&, int&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1359:6
    #25 0x7fe47c59e56d in QPDF::resolve(int, int) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF.cc:1474:7
    #26 0x7fe47c5f4854 in QPDF::Resolver::resolve(QPDF*, int, int) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/include/qpdf/QPDF.hh:520:19
    #27 0x7fe47c5f4854 in QPDFObjectHandle::dereference() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1520
    #28 0x7fe47c626227 in QPDFObjectHandle::isName() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:184:5
    #29 0x7fe47c626227 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:1074
    #30 0x7fe47c61f018 in QPDFObjectHandle::parseInternal(PointerHolder, std::string const&, QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*, bool, bool, bool) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:939:15

Reproducer:
https://github.com/asarubbo/poc/blob/master/00177-pdf-infiniteloop2
CVE:
CVE-2017-9209

############################

# qpdf $FILE -
==13070==ERROR: AddressSanitizer: stack-overflow on address 0x7ffd0ba0efb0 (pc 0x00000042711b bp 0x7ffd0ba0f8a0 sp 0x7ffd0ba0efb0 T0)
    #0 0x42711a in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) /tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:325
    #1 0x50ce78 in operator new(unsigned long) /tmp/portage/sys-devel/llvm-3.9.1/work/llvm-3.9.1.src/projects/compiler-rt/lib/asan/asan_new_delete.cc:78
    #2 0x7f949448ae58 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator const&) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf3e58)
    #3 0x7f949448bc3a in std::string::_Rep::_M_clone(std::allocator const&, unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4c3a)
    #4 0x7f949448bce3 in std::string::reserve(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6+0xf4ce3)
    #5 0x7f9494a4451d in std::string::push_back(char) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:1072:10
    #6 0x7f9494a4451d in std::string::operator+=(char) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/include/g++-v4/bits/basic_string.h:968
    #7 0x7f9494a4451d in QPDF_Name::normalizeName(std::string const&) /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Name.cc:24
    #8 0x7f9494a3ddaa in QPDF_Dictionary::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:35:12
    #9 0x7f949490c23f in QPDFObjectHandle::unparseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23
    #10 0x7f9494909e8c in QPDFObjectHandle::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11
    #11 0x7f9494a39cb0 in QPDF_Array::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Array.cc:30:20
    #12 0x7f949490c23f in QPDFObjectHandle::unparseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23
    #13 0x7f9494909e8c in QPDFObjectHandle::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11
    #14 0x7f9494a3de56 in QPDF_Dictionary::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:36:27
    #15 0x7f949490c23f in QPDFObjectHandle::unparseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23
    #16 0x7f9494909e8c in QPDFObjectHandle::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11
    #17 0x7f9494a39cb0 in QPDF_Array::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Array.cc:30:20
    #18 0x7f949490c23f in QPDFObjectHandle::unparseResolved() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:699:23
    #19 0x7f9494909e8c in QPDFObjectHandle::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDFObjectHandle.cc:685:11
    #20 0x7f9494a3de56 in QPDF_Dictionary::unparse() /tmp/portage/app-text/qpdf-6.0.0-r1/work/qpdf-6.0.0/libqpdf/QPDF_Dictionary.cc:36:27

Reproducer:
https://github.com/asarubbo/poc/blob/master/00177-qpdf-infiniteloop3
CVE:
CVE-2017-9210

############################

Affected version:
6.0.0

Fixed version:
N/A

Commit fix:
N/A

Credit:
These bugs were discovered by Agostino Sarubbo of Gentoo.

Timeline:
2017-02-13: bug discovered and reported to upstream
2017-05-21: blog post about the issue
2017-05-23: CVE assigned

Note:
These bugs were found with American Fuzzy Lop.

Permalink:

qpdf: three infinite loop in libqpdf

May 20, 2017
imageworsener: multiple vulnerabilities (May 20, 2017, 15:37 UTC)

Description:
imageworsener is a utility for image scaling and processing.

After have fuzzed the 1.3.0 release and have found something already documented in the previous posts, I re-tested the new release and the fuzzer turned up some issues. I don’t know if those issues were present also in the old releases or the recent commits introduced them.

# imagew $FILE /tmp/out -outfmt bmp
src/imagew-cmd.c:850:46: runtime error: division by zero
src/imagew-cmd.c:850:29: runtime error: value inf is outside the range of representable values of type 'int'

Commit fix:
https://github.com/jsummers/imageworsener/commit/dc49c807926b96e503bd7c0dec35119eecd6c6fe
Reproducer:
https://github.com/asarubbo/poc/blob/master/00278-imageworsener-fpe-outside-int
CVE:
CVE-2017-9201

############################

# imagew $FILE /tmp/out -outfmt bmp
src/imagew-cmd.c:854:45: runtime error: division by zero
src/imagew-cmd.c:854:28: runtime error: value inf is outside the range of representable values of type 'int'

Commit fix:
https://github.com/jsummers/imageworsener/commit/dc49c807926b96e503bd7c0dec35119eecd6c6fe
Reproducer:
https://github.com/asarubbo/poc/blob/master/00279-imageworsener-fpe-outside-int_2
CVE:
CVE-2017-9202

############################

# imagew $FILE /tmp/out -outfmt bmp
src/imagew-main.c:960:12: runtime error: index -1 out of bounds for type 'struct iw_channelinfo_out [4]'

Commit fix:
https://github.com/jsummers/imageworsener/commit/a4f247707f08e322f0b41e82c3e06e224240a654
Reproducer:
https://github.com/asarubbo/poc/blob/master/00280-imageworsener-oob-iw_channelinfo_out
CVE:
CVE-2017-9203

############################

# imagew $FILE /tmp/out -outfmt bmp
==29040==ERROR: AddressSanitizer: SEGV on unknown address 0x60b00a000086 (pc 0x7f693a6b6a30 bp 0x7ffc6ae53710 sp 0x7ffc6ae536f0 T0)                  
==29040==The signal is caused by a READ memory access.                                                                                               
    #0 0x7f693a6b6a2f in iw_get_ui16le /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:405:23              
    #1 0x7f693a6b6a2f in iw_get_ui16_e /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:435                 
    #2 0x7f693a67d008 in iwjpeg_scan_exif_ifd /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:130:14       
    #3 0x7f693a67d008 in iwjpeg_scan_exif /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:182              
    #4 0x7f693a67d008 in iwjpeg_read_saved_markers /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:205     
    #5 0x7f693a67d008 in iw_read_jpeg_file /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:430             
    #6 0x7f693a5ed21d in iw_read_file_by_fmt /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-allfmts.c:43:12      
    #7 0x510184 in iwcmd_run /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:1191:6                         
    #8 0x50c1a6 in iwcmd_main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3018:7                        
    #9 0x50c1a6 in main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3067                                
    #10 0x7f69395f6680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                          
    #11 0x41b048 in _init (/usr/bin/imagew+0x41b048)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:405:23 in iw_get_ui16le
==29040==ABORTING

Commit fix:
https://github.com/jsummers/imageworsener/commit/b45cb1b665a14b0175b9cb1502ef7168e1fe0d5d
Reproducer:
https://github.com/asarubbo/poc/blob/master/00281-imageworsener-invalidread-iw_get_ui16le
CVE:
CVE-2017-9204

############################

# imagew $FILE /tmp/out -outfmt bmp
==9730==ERROR: AddressSanitizer: SEGV on unknown address 0x60b0ff100086 (pc 0x7f4178fefadb bp 0x7fffcee12570 sp 0x7fffcee12550 T0)                   
==9730==The signal is caused by a READ memory access.                                                                                                
    #0 0x7f4178fefada in iw_get_ui16be /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:422:24              
    #1 0x7f4178fefada in iw_get_ui16_e /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:436                 
    #2 0x7f4178fb6008 in iwjpeg_scan_exif_ifd /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:130:14       
    #3 0x7f4178fb6008 in iwjpeg_scan_exif /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:182              
    #4 0x7f4178fb6008 in iwjpeg_read_saved_markers /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:205     
    #5 0x7f4178fb6008 in iw_read_jpeg_file /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:430             
    #6 0x7f4178f2621d in iw_read_file_by_fmt /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-allfmts.c:43:12      
    #7 0x510184 in iwcmd_run /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:1191:6                         
    #8 0x50c1a6 in iwcmd_main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3018:7                        
    #9 0x50c1a6 in main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3067                                
    #10 0x7f4177f2f680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                          
    #11 0x41b048 in _init (/usr/bin/imagew+0x41b048)                                                                                                 
                                                                                                                                                     
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:422:24 in iw_get_ui16be
==9730==ABORTING

Commit fix:
https://github.com/jsummers/imageworsener/commit/b45cb1b665a14b0175b9cb1502ef7168e1fe0d5d
Reproducer:
https://github.com/asarubbo/poc/blob/master/00282-imageworsener-invalidread-iw_get_ui16be
CVE:
CVE-2017-9205

############################

# imagew $FILE /tmp/out -outfmt bmp
==24197==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x608000000a70 at pc 0x7f1c90ffbb6b bp 0x7ffd41b1af40 sp 0x7ffd41b1af38            
READ of size 1 at 0x608000000a70 thread T0                                                                                                           
    #0 0x7f1c90ffbb6a in iw_get_ui16le /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:405:23              
    #1 0x7f1c90ffbb6a in iw_get_ui16_e /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:435                 
    #2 0x7f1c90fc2008 in iwjpeg_scan_exif_ifd /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:130:14       
    #3 0x7f1c90fc2008 in iwjpeg_scan_exif /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:182              
    #4 0x7f1c90fc2008 in iwjpeg_read_saved_markers /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:205     
    #5 0x7f1c90fc2008 in iw_read_jpeg_file /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:430             
    #6 0x7f1c90f3221d in iw_read_file_by_fmt /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-allfmts.c:43:12      
    #7 0x510184 in iwcmd_run /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:1191:6                         
    #8 0x50c1a6 in iwcmd_main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3018:7                        
    #9 0x50c1a6 in main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3067                                
    #10 0x7f1c8ff3b680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                          
    #11 0x41b048 in _init (/usr/bin/imagew+0x41b048)                                                                                                 
                                                                                                                                                     
Address 0x608000000a70 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:405:23 in iw_get_ui16le

Commit fix:
https://github.com/jsummers/imageworsener/commit/b45cb1b665a14b0175b9cb1502ef7168e1fe0d5d
Reproducer:
https://github.com/asarubbo/poc/blob/master/00283-imageworsener-heapoverflow-iw_get_ui16le
CVE:
CVE-2017-9206

############################

# imagew $FILE /tmp/out -outfmt bmp
==9198==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x608000004070 at pc 0x7ffb620f1b97 bp 0x7fff09707940 sp 0x7fff09707938
READ of size 1 at 0x608000004070 thread T0
    #0 0x7ffb620f1b96 in iw_get_ui16be /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:422:24
    #1 0x7ffb620f1b96 in iw_get_ui16_e /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:436
    #2 0x7ffb620b8008 in iwjpeg_scan_exif_ifd /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:130:14
    #3 0x7ffb620b8008 in iwjpeg_scan_exif /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:182
    #4 0x7ffb620b8008 in iwjpeg_read_saved_markers /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:205
    #5 0x7ffb620b8008 in iw_read_jpeg_file /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-jpeg.c:430
    #6 0x7ffb6202821d in iw_read_file_by_fmt /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-allfmts.c:43:12
    #7 0x510184 in iwcmd_run /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:1191:6
    #8 0x50c1a6 in iwcmd_main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3018:7
    #9 0x50c1a6 in main /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-cmd.c:3067
    #10 0x7ffb61031680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #11 0x41b048 in _init (/usr/bin/imagew+0x41b048)

Address 0x608000004070 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /var/tmp/portage/media-gfx/imageworsener-1.3.1/work/imageworsener-1.3.1/src/imagew-util.c:422:24 in iw_get_ui16be

Commit fix:
https://github.com/jsummers/imageworsener/commit/b45cb1b665a14b0175b9cb1502ef7168e1fe0d5d
Reproducer:
https://github.com/asarubbo/poc/blob/master/00284-imageworsener-heapoverflow-iw_get_ui16be
CVE:
CVE-2017-9207

############################

Affected version:
1.3.1

Fixed version:
1.3.2 (not released atm)

Credit:
These bugs were discovered by Agostino Sarubbo of Gentoo.

Timeline:
2017-05-10: bugs discovered and reported to upstream
2017-05-20: blog post about the issue
2017-05-23: CVE assigned

Note:
These bugs were found with American Fuzzy Lop.

Permalink:

imageworsener: multiple vulnerabilities

Description:
autotrace is a program for converting bitmaps to vector graphics.

Time ago I tried to fuzz autotrace, but the first attempt resulted in a crash-by-default so I was unable to complete the task. See CVE-2016-7392 – autotrace: heap-based buffer overflow in pstoedit_suffix_table_init (output-pstoedit.c) for more info about.
Some days ago I noticed that the debian team patched the mentioned issue ( you can blame them for the following you will see 😀 ), so I took the patch and I started the job. I’m sure there are duplicates, or better to say, issues that have the same root cause. But for completeness I’m providing all stacktraces/testcases.
Since we applied several patches, I’m providing the tarball as well, to verify the lines where the faults happen.
There are enough issues to kill the package from each repository since the latest upstream release was about 15 years ago.

Some details to avoid to repeat them multiple times.
– reproducible with: autotrace $FILE
– affected version: 0.31.1
– Fixed version: N/A
– Commit fix: N/A

==27066==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000071 at pc 0x7f42e63f224f bp 0x7ffe8cc02b70 sp 0x7ffe8cc02b68                                                                         
WRITE of size 1 at 0x602000000071 thread T0                                                                                                                                                                       
    #0 0x7f42e63f224e in pnm_load_ascii /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:303:12                                                                                       
    #1 0x7f42e63edfaf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3                                                                                      
    #2 0x7f42e64842e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13                                                                                       
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16                                                                                                            
    #4 0x7f42e54df680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                                                                                        
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)                                                                                                                                                            
                                                                                                                                                                                                                  
0x602000000071 is located 0 bytes to the right of 1-byte region [0x602000000070,0x602000000071)                                                                                                                   
allocated by thread T0 here:                                                                                                                                                                                      
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74                                                                          
    #1 0x7f42e64849e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2                                                                                        
    #2 0x7f42e63eded4 in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:239:12                                                                                     
    #3 0x7f42e64842e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13                                                                                       
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16                                                                                                            
    #5 0x7f42e54df680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:303:12 in pnm_load_ascii

Reproducer:
HEAP-input-pnm.c-303-12.PBM
CVE:
CVE-2017-9151

#########################################

==15561==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000008e at pc 0x7ff8acddc761 bp 0x7ffcd65a9bf0 sp 0x7ffcd65a9be8
READ of size 1 at 0x60300000008e thread T0
    #0 0x7ff8acddc760 in pnm_load_raw /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:346:41
    #1 0x7ff8acdd5faf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #2 0x7ff8ace6c2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7ff8abec7680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x60300000008e is located 0 bytes to the right of 30-byte region [0x603000000070,0x60300000008e)
allocated by thread T0 here:
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7ff8ace6c9e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2
    #2 0x7ff8acdd5ed4 in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:239:12
    #3 0x7ff8ace6c2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7ff8abec7680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:346:41 in pnm_load_raw

Reproducer:
HEAP-input-pnm.c-346-41.PBM
CVE:
CVE-2017-9152

#########################################

==11769==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6160000005ba at pc 0x7f1540eec0d1 bp 0x7ffc27a48c20 sp 0x7ffc27a48c18
WRITE of size 1 at 0x6160000005ba thread T0
    #0 0x7f1540eec0d0 in pnm_load_rawpbm /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:391:13
    #1 0x7f1540ee6faf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #2 0x7f1540f7d2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f153ffd8680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x6160000005ba is located 0 bytes to the right of 570-byte region [0x616000000380,0x6160000005ba)
allocated by thread T0 here:
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7f1540f7d9e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2
    #2 0x7f1540ee6ed4 in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:239:12
    #3 0x7f1540f7d2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f153ffd8680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:391:13 in pnm_load_rawpbm

Reproducer:
HEAP-input-pnm.c-391-13.PBM
CVE:
CVE-2017-9153

#########################################

==15741==ERROR: AddressSanitizer: SEGV on unknown address 0x7fabc702e804 (pc 0x7fabcc84c7bb bp 0x7ffd2d0598d0 sp 0x7ffd2d0598a0 T0)
==15741==The signal is caused by a READ memory access.
    #0 0x7fabcc84c7ba in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11
    #1 0x7fabcc872d6c in is_outline_edge /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:606:8
    #2 0x7fabcc866b7d in next_point /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:875:16
    #3 0x7fabcc85c2ef in find_one_outline /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:232:13
    #4 0x7fabcc85a592 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:136:25
    #5 0x7fabcc8505df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #6 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #7 0x7fabcb8a9680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11 in GET_COLOR

Reproducer:
SEGV-color.c.16-11.PBM
CVE:
CVE-2017-9154

#########################################

==10703==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f9d7f436fad bp 0x7ffff7bfce10 sp 0x7ffff7bfccc0 T0)
==10703==The signal is caused by a READ memory access.
==10703==Hint: address points to the zero page.
    #0 0x7f9d7f436fac in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #1 0x7f9d7f4cd2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #2 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #3 0x7f9d7e528680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #4 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3 in input_pnm_reader

Reproducer:
SEGV-input-pnm.c-243-3.PBM
CVE:
CVE-2017-9155

#########################################

==11174==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f6d831eb74b bp 0x7ffc4e65fcb0 sp 0x7ffc4e65fb80 T0)
==11174==The signal is caused by a WRITE memory access.
==11174==Hint: address points to the zero page.
    #0 0x7f6d831eb74a in pnm_load_ascii /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:303:12
    #1 0x7f6d831e7faf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #2 0x7f6d8327e2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f6d822d9680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:303:12 in pnm_load_ascii

Reproducer:
SEGV-input-pnm.c-303-12.PBM
CVE:
CVE-2017-9156

#########################################

==28602==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f48c4e62a5d bp 0x7ffd95ea1cb0 sp 0x7ffd95ea1b80 T0)
==28602==The signal is caused by a WRITE memory access.
==28602==Hint: address points to the zero page.
    #0 0x7f48c4e62a5c in pnm_load_ascii /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:306:14
    #1 0x7f48c4e5efaf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #2 0x7f48c4ef52e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f48c3f50680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:306:14 in pnm_load_ascii

Reproducer:
SEGV-input-pnm.c-306-14.PBM
CVE:
CVE-2017-9157

#########################################

==28887==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f743bc8b10e bp 0x00000000000f sp 0x7ffeef5b4b98 T0)
==28887==The signal is caused by a WRITE memory access.
==28887==Hint: address points to the zero page.
    #0 0x7f743bc8b10d  /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/string/../sysdeps/x86_64/memcpy.S:71
    #1 0x7f743bc79ebd in __GI__IO_file_xsgetn /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/libio/fileops.c:1392
    #2 0x7f743bc6f20f in fread /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/libio/iofread.c:38
    #3 0x7f743cb3e505 in pnm_load_raw /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:336:11
    #4 0x7f743cb37faf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #5 0x7f743cbce2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #6 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #7 0x7f743bc29680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/string/../sysdeps/x86_64/memcpy.S:71

Reproducer:
SEGV-input-pnm.c-336-11.PBM
CVE:
CVE-2017-9158

#########################################

==12246==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f4ffc714627 bp 0x7ffcb0118cb0 sp 0x7ffcb0118c30 T0)
==12246==The signal is caused by a WRITE memory access.
==12246==Hint: address points to the zero page.
    #0 0x7f4ffc714626 in pnm_load_rawpbm /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:391:15
    #1 0x7f4ffc70ffaf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #2 0x7f4ffc7a62e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f4ffb801680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:391:15 in pnm_load_rawpbm

Reproducer:
SEGV-input-pnm.c-391-15.PBM
CVE:
CVE-2017-9159

#########################################

==23827==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f0793e00620 at pc 0x7f0798f0581a bp 0x7fff2523daf0 sp 0x7fff2523dae8
WRITE of size 1 at 0x7f0793e00620 thread T0
    #0 0x7f0798f05819 in pnmscanner_gettoken /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:458:12
    #1 0x7f0798f0713e in pnm_load_ascii /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:294:5
    #2 0x7f0798f03faf in input_pnm_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:243:3
    #3 0x7f0798f9a2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f0797ff5680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #6 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

Address 0x7f0793e00620 is located in stack of thread T0 at offset 544 in frame
    #0 0x7f0798f05e9f in pnm_load_ascii /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:263

  This frame has 1 object(s):
    [32, 544) 'buf' <== Memory access at offset 544 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-pnm.c:458:12 in pnmscanner_gettoken

Reproducer:
STACK-input-pnm.c-458-12.PBM
CVE:
CVE-2017-9160

#########################################

autotrace.c:188:23: runtime error: signed integer overflow: 46486 * 46485 cannot be represented in type 'int'

Reproducer:
UNDEF-autotrace.c-188-23.PBM
CVE:
CVE-2017-9161

#########################################

autotrace.c:191:2: runtime error: signed integer overflow: 65535 * 65529 cannot be represented in type 'int'

Reproducer:
UNDEF-autotrace.c-191-2.PBM
CVE:
CVE-2017-9162

#########################################

pxl-outline.c:106:54: runtime error: signed integer overflow: 65535 * 53531 cannot be represented in type 'int'

Reproducer:
UNDEF-pxl-outline.c-106-54.PBM
CVE:
CVE-2017-9163

#########################################

==1166==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62d00000880c at pc 0x7f9aa579b946 bp 0x7ffca93d7890 sp 0x7ffca93d7888
READ of size 1 at 0x62d00000880c thread T0
    #0 0x7f9aa579b945 in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11
    #1 0x7f9aa57c1d6c in is_outline_edge /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:606:8
    #2 0x7f9aa57b5b7d in next_point /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:875:16
    #3 0x7f9aa57ab2ef in find_one_outline /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:232:13
    #4 0x7f9aa57a9592 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:136:25
    #5 0x7f9aa579f5df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #6 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #7 0x7f9aa47f8680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x62d00000880c is located 8 bytes to the right of 33796-byte region [0x62d000000400,0x62d000008804)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7f9aa5711116 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:319:7
    #2 0x7f9aa5711116 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7f9aa579d2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f9aa47f8680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11 in GET_COLOR

Reproducer:
HEAP-color.c-16-11.BMP
CVE:
CVE-2017-9164

#########################################

==6460==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000071 at pc 0x7fea3aae195b bp 0x7ffe69932b70 sp 0x7ffe69932b68
READ of size 1 at 0x602000000071 thread T0
    #0 0x7fea3aae195a in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:17:11
    #1 0x7fea3aaef153 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:125:19
    #2 0x7fea3aae55df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #3 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #4 0x7fea39b3e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x602000000071 is located 0 bytes to the right of 1-byte region [0x602000000070,0x602000000071)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7fea3aa57116 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:319:7
    #2 0x7fea3aa57116 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7fea3aae32e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7fea39b3e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:17:11 in GET_COLOR

Reproducer:
HEAP-color.c-17-11.BMP
CVE:
CVE-2017-9165

#########################################

==9854==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61f000000d81 at pc 0x7f66a5a2e971 bp 0x7ffd049fb890 sp 0x7ffd049fb888
READ of size 1 at 0x61f000000d81 thread T0
    #0 0x7f66a5a2e970 in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:18:11
    #1 0x7f66a5a54d6c in is_outline_edge /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:606:8
    #2 0x7f66a5a48fd2 in next_point /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:836:16
    #3 0x7f66a5a3e2ef in find_one_outline /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:232:13
    #4 0x7f66a5a3c592 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:136:25
    #5 0x7f66a5a325df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #6 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #7 0x7f66a4a8b680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x61f000000d81 is located 0 bytes to the right of 3329-byte region [0x61f000000080,0x61f000000d81)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7f66a59a4116 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:319:7
    #2 0x7f66a59a4116 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7f66a5a302e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f66a4a8b680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:18:11 in GET_COLOR

Reproducer:
HEAP-color.c-18-11.BMP
CVE:
CVE-2017-9166

#########################################

==6435==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000006d at pc 0x7ff19cd36604 bp 0x7fff53b20c50 sp 0x7fff53b20c48
WRITE of size 1 at 0x60200000006d thread T0
    #0 0x7ff19cd36603 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:337:25
    #1 0x7ff19cd36603 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7ff19cdbd2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7ff19be18680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x60200000006d is located 3 bytes to the left of 3-byte region [0x602000000070,0x602000000073)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7ff19cd30fc1 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:309:7
    #2 0x7ff19cd30fc1 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7ff19cdbd2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7ff19be18680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:337:25 in ReadImage

Reproducer:
HEAP-input-bmp.c-337-25.BMP
CVE:
CVE-2017-9167

#########################################

==1216==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000006d at pc 0x7fbacd3ae631 bp 0x7ffdb62cfc50 sp 0x7ffdb62cfc48
WRITE of size 1 at 0x60200000006d thread T0
    #0 0x7fbacd3ae630 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:353:25
    #1 0x7fbacd3ae630 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fbacd4352e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fbacc490680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x60200000006d is located 3 bytes to the left of 3-byte region [0x602000000070,0x602000000073)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7fbacd3a8fc1 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:309:7
    #2 0x7fbacd3a8fc1 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7fbacd4352e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7fbacc490680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:353:25 in ReadImage

Reproducer:
HEAP-input-bmp.c-353-25.BMP
CVE:
CVE-2017-9168

#########################################

==6260==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000068 at pc 0x7f9f33109651 bp 0x7fff2313dc50 sp 0x7fff2313dc48
WRITE of size 1 at 0x607000000068 thread T0
    #0 0x7f9f33109650 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:355:25
    #1 0x7f9f33109650 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7f9f331902e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f9f321eb680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x607000000068 is located 0 bytes to the right of 72-byte region [0x607000000020,0x607000000068)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7f9f3318eb13 in at_fitting_opts_new /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:51:3
    #2 0x509455 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:82:24
    #3 0x7f9f321eb680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:355:25 in ReadImage

Reproducer:
HEAP-input-bmp.c-355-25.BMP
CVE:
CVE-2017-9169

#########################################

==6415==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000006d at pc 0x7f53cbb18669 bp 0x7ffd2e82ac50 sp 0x7ffd2e82ac48
WRITE of size 1 at 0x60200000006d thread T0
    #0 0x7f53cbb18668 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:370:25
    #1 0x7f53cbb18668 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7f53cbb9f2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f53cabfa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x60200000006d is located 3 bytes to the left of 3-byte region [0x602000000070,0x602000000073)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7f53cbb12fc1 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:309:7
    #2 0x7f53cbb12fc1 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7f53cbb9f2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f53cabfa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:370:25 in ReadImage

Reproducer:
HEAP-input-bmp.c-370-25.BMP
CVE:
CVE-2017-9170

#########################################

==6455==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fb7800fe801 at pc 0x7fb7848c85c7 bp 0x7ffc39b0ec50 sp 0x7ffc39b0ec48
READ of size 1 at 0x7fb7800fe801 thread T0
    #0 0x7fb7848c85c6 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:492:24
    #1 0x7fb7848c85c6 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fb78494f2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fb7839aa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x7fb7800fe801 is located 0 bytes to the right of 655361-byte region [0x7fb78005e800,0x7fb7800fe801)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7fb7848c3116 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:319:7
    #2 0x7fb7848c3116 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7fb78494f2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7fb7839aa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:492:24 in ReadImage

Reproducer:
HEAP-input-bmp.c-492-24.BMP
CVE:
CVE-2017-9171

#########################################

==6652==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000b1 at pc 0x7f80c1d6e5e7 bp 0x7ffd0fd20c50 sp 0x7ffd0fd20c48
WRITE of size 1 at 0x6020000000b1 thread T0
    #0 0x7f80c1d6e5e6 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:496:29
    #1 0x7f80c1d6e5e6 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7f80c1df52e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f80c0e50680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x6020000000b1 is located 0 bytes to the right of 1-byte region [0x6020000000b0,0x6020000000b1)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7f80c1d6da41 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:486:7
    #2 0x7f80c1d6da41 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7f80c1df52e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f80c0e50680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:496:29 in ReadImage

Reproducer:
HEAP-input-bmp.c-496-29.BMP
CVE:
CVE-2017-9172

#########################################

==6562==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fe5db1fc800 at pc 0x7fe637b9d5f7 bp 0x7ffcd7777c50 sp 0x7ffcd7777c48
WRITE of size 1 at 0x7fe5db1fc800 thread T0
    #0 0x7fe637b9d5f6 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:497:29
    #1 0x7fe637b9d5f6 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fe637c242e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fe636c7f680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x7fe5db1fc800 is located 0 bytes to the right of 83898368-byte region [0x7fe5d61f9800,0x7fe5db1fc800)
allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7fe637b9ca41 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:486:7
    #2 0x7fe637b9ca41 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7fe637c242e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7fe636c7f680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:497:29 in ReadImage

Reproducer:
HEAP-input-bmp.c-497-29.BMP
CVE:
CVE-2017-9173

#########################################

==3794==ERROR: AddressSanitizer: SEGV on unknown address 0x7fb79d28c2c9 (pc 0x7fb819bbb8af bp 0x7ffcb8a228d0 sp 0x7ffcb8a228a0 T0)
==3794==The signal is caused by a READ memory access.
    #0 0x7fb819bbb8ae in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:21:23
    #1 0x7fb819be1d6c in is_outline_edge /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:606:8
    #2 0x7fb819bd5b7d in next_point /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:875:16
    #3 0x7fb819bcb2ef in find_one_outline /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:232:13
    #4 0x7fb819bc9592 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:136:25
    #5 0x7fb819bbf5df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #6 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #7 0x7fb818c18680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:21:23 in GET_COLOR

Reproducer:
SEGV-color.c-21-23.BMP
CVE:
CVE-2017-9174

#########################################

==6582==ERROR: AddressSanitizer: SEGV on unknown address 0x7fc6edefe800 (pc 0x7fc7f37e70a0 bp 0x7ffcdd383e10 sp 0x7ffcdd383c60 T0)
==6582==The signal is caused by a WRITE memory access.
    #0 0x7fc7f37e709f in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:353:25
    #1 0x7fc7f37e709f in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fc7f386f2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fc7f28ca680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:353:25 in ReadImage

Reproducer:
SEGV-input-bmp.c-353-25.BMP
CVE:
CVE-2017-9175

#########################################

==29001==ERROR: AddressSanitizer: SEGV on unknown address 0x602600000064 (pc 0x7f4698d176b5 bp 0x7fff96527e10 sp 0x7fff96527c60 T0)
==29001==The signal is caused by a WRITE memory access.
    #0 0x7f4698d176b4 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:370:25
    #1 0x7f4698d176b4 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7f4698d9f2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f4697dfa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:370:25 in ReadImage

Reproducer:
SEGV-input-bmp.c-370-25.BMP
CVE:
CVE-2017-9176

#########################################

==6445==ERROR: AddressSanitizer: SEGV on unknown address 0x170344731d00 (pc 0x7f562a18a7ce bp 0x7ffe24662e10 sp 0x7ffe24662c60 T0)
==6445==The signal is caused by a READ memory access.
    #0 0x7f562a18a7cd in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:390:12
    #1 0x7f562a18a7cd in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7f562a2142e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f562926f680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:390:12 in ReadImage

Reproducer:
SEGV-input-bmp.c-390-12.BMP
CVE:
CVE-2017-9177

#########################################

==6450==ERROR: AddressSanitizer: SEGV on unknown address 0x7fbf9c7ae200 (pc 0x7fbda21ddde7 bp 0x7fffce040e10 sp 0x7fffce040c60 T0)
==6450==The signal is caused by a WRITE memory access.
    #0 0x7fbda21ddde6 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:421:11
    #1 0x7fbda21ddde6 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fbda22692e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fbda12c4680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:421:11 in ReadImage

Reproducer:
SEGV-input-bmp.c-421-11.BMP
CVE:
CVE-2017-9178

#########################################

==6420==ERROR: AddressSanitizer: SEGV on unknown address 0x114a61dc3b1f (pc 0x7fb614a28dc8 bp 0x7ffc640a6e10 sp 0x7ffc640a6c60 T0)
==6420==The signal is caused by a READ memory access.
    #0 0x7fb614a28dc7 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:425:14
    #1 0x7fb614a28dc7 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fb614ab42e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fb613b0f680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:425:14 in ReadImage

Reproducer:
SEGV-input-bmp.c-425-14.BMP
CVE:
CVE-2017-9179

#########################################

==6430==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fb696759bc7 bp 0x7fffc7440e10 sp 0x7fffc7440c60 T0)
==6430==The signal is caused by a READ memory access.
==6430==Hint: address points to the zero page.
    #0 0x7fb696759bc6 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:440:14
    #1 0x7fb696759bc6 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fb6967e42e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fb69583f680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:440:14 in ReadImage

Reproducer:
SEGV-input-bmp.c-440-14.BMP
CVE:
CVE-2017-9180

#########################################

==6799==ERROR: AddressSanitizer: SEGV on unknown address 0x7fe7fa7fe800 (pc 0x7fe90010491c bp 0x7ffef16afe10 sp 0x7ffef16afc60 T0)
==6799==The signal is caused by a WRITE memory access.
    #0 0x7fe90010491b in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c
    #1 0x7fe90010491b in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #2 0x7fe90018d2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7fe8ff1e8680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c in ReadImage

Reproducer:
SEGV-input-bmp.c.BMP
CVE:
CVE-2017-9181

#########################################

==12448==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f428790192a at pc 0x7f428f289946 bp 0x7fffa4721890 sp 0x7fffa4721888
READ of size 1 at 0x7f428790192a thread T0
    #0 0x7f428f289945 in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11
    #1 0x7f428f2afd6c in is_outline_edge /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:606:8
    #2 0x7f428f2a3b7d in next_point /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:875:16
    #3 0x7f428f2992ef in find_one_outline /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:232:13
    #4 0x7f428f297592 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:136:25
    #5 0x7f428f28d5df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #6 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #7 0x7f428e2e6680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x7f428790192a is located 298 bytes inside of 33545727-byte region [0x7f4287901800,0x7f42898ff5ff)
freed by thread T0 here:
    #0 0x4cff00 in __interceptor_cfree /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:55
    #1 0x7f428f2041f6 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:501:7
    #2 0x7f428f2041f6 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7f428f28b2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f428e2e6680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

previously allocated by thread T0 here:
    #0 0x4d00b8 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x7f428f1ff116 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:319:7
    #2 0x7f428f1ff116 in input_bmp_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-bmp.c:241
    #3 0x7f428f28b2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7f428e2e6680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-use-after-free /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11 in GET_COLOR

Reproducer:
UAF-color.c-16-11.BMP
CVE:
CVE-2017-9182

#########################################

input-bmp.c:309:7: runtime error: signed integer overflow: 1676736000 * 3 cannot be represented in type 'int'

Reproducer:
UNDEF-autotrace.c-309-7.BMP
CVE:
CVE-2017-9183

#########################################

input-bmp.c:314:7: runtime error: signed integer overflow: 32776 * 4194305 cannot be represented in type 'int'

Reproducer:
UNDEF-autotrace.c-314-7.BMP
CVE:
CVE-2017-9184

#########################################

input-bmp.c:319:7: runtime error: signed integer overflow: 1379841 * 8445184 cannot be represented in type 'int'

Reproducer:
UNDEF-autotrace.c-319-7.BMP
CVE:
CVE-2017-9185

#########################################

input-bmp.c:326:17: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'

Reproducer:
UNDEF-autotrace.c-326-17.BMP
CVE:
CVE-2017-9186

#########################################

input-bmp.c:486:7: runtime error: signed integer overflow: 1073741827 * 3 cannot be represented in type 'int'

Reproducer:
UNDEF-input-bmp.c-486-7.BMP
CVE:
CVE-2017-9187

#########################################

input-bmp.c:516:63: runtime error: left shift of 128 by 24 places cannot be represented in type 'int'

Reproducer:
UNDEF-input-bmp.c-516-63.BMP
CVE:
CVE-2017-9188

#########################################

==12009==ERROR: AddressSanitizer: unknown-crash on address 0x7fbb91586d21 at pc 0x7fbb91230946 bp 0x7ffe088d8890 sp 0x7ffe088d8888
READ of size 1 at 0x7fbb91586d21 thread T0
    #0 0x7fbb91230945 in GET_COLOR /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11
    #1 0x7fbb91256d6c in is_outline_edge /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:606:8
    #2 0x7fbb9124ab7d in next_point /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:875:16
    #3 0x7fbb912402ef in find_one_outline /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:232:13
    #4 0x7fbb9123e592 in find_outline_pixels /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/pxl-outline.c:136:25
    #5 0x7fbb912345df in at_splines_new_full /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:314:14
    #6 0x50dad0 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:147:13
    #7 0x7fbb9028d680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

Address 0x7fbb91586d21 is a wild pointer.
SUMMARY: AddressSanitizer: unknown-crash /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/color.c:16:11 in GET_COLOR

Reproducer:
UNKNOWN-color.c-16-11.BMP
CVE:
CVE-2017-9189

#########################################

==4658==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x613000000200 in thread T0                                   
    #0 0x4cff00 in __interceptor_cfree /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:55
    #1 0x7fd75068d29e in free_bitmap /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/bitmap.c:24:5                                  
    #2 0x7fd7506a077d in at_bitmap_free /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:203:3                           
    #3 0x50dd23 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:173:3                                                
    #4 0x7fd74f6fa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                           
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)                                                                                               
                                                                                                                                                     
0x613000000200 is located 48 bytes inside of 538976288-byte region [0x6130000001d0,0x6130202021f0)                                                   
==4658==AddressSanitizer CHECK failed: /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_descriptions.cc:178 "((res.trace)) != (0)" (0x0, 0x0)                                                                                                                  
    #0 0x4da09f in AsanCheckFailed /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_rtl.cc:69             
    #1 0x4f4e05 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_termination.cc:79                                                         
    #2 0x42875c in GetStackTraceFromId /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_descriptions.cc:178
    #3 0x42875c in __asan::HeapAddressDescription::Print() const /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_descriptions.cc:395
    #4 0x42a19b in __asan::AddressDescription::Print(char const*) const /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_descriptions.h:225
    #5 0x42a19b in __asan::ErrorFreeNotMalloced::Print() /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_errors.cc:148
    #6 0x4d712b in __asan::ErrorDescription::Print() /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_errors.h:374
    #7 0x4d712b in __asan::ScopedInErrorReport::~ScopedInErrorReport() /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_report.cc:169
    #8 0x4d712b in __asan::ReportFreeNotMalloced(unsigned long, __sanitizer::BufferedStackTrace*) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_report.cc:275
    #9 0x41f46d in __asan::Allocator::ReportInvalidFree(void*, unsigned char, __sanitizer::BufferedStackTrace*) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:617
    #10 0x41f46d in __asan::Allocator::AtomicallySetQuarantineFlagIfAllocated(__asan::AsanChunk*, void*, __sanitizer::BufferedStackTrace*) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:507
    #11 0x41f46d in __asan::Allocator::Deallocate(void*, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:560
    #12 0x41f46d in __asan::asan_free(void*, __sanitizer::BufferedStackTrace*, __asan::AllocType) /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_allocator.cc:773
    #13 0x4cfedc in __interceptor_cfree /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:58
    #14 0x7fd75068d29e in free_bitmap /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/bitmap.c:24:5
    #15 0x7fd7506a077d in at_bitmap_free /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:203:3
    #16 0x50dd23 in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:173:3
    #17 0x7fd74f6fa680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #18 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

Reproducer:
BADFREE-bitmap.c-24-5.TGA
CVE:
CVE-2017-9190

#########################################

==4247==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001f0 at pc 0x0000004b97d8 bp 0x7ffc8908ac20 sp 0x7ffc8908a3d0
WRITE of size 4 at 0x6140000001f0 thread T0
    #0 0x4b97d7 in __asan_memcpy /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_interceptors.cc:453
    #1 0x7f76fde92d68 in rle_fread /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:252:15
    #2 0x7f76fde8f322 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:514:12
    #3 0x7f76fde8f322 in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #4 0x7f76fdf132e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #5 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #6 0x7f76fcf6e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #7 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x6140000001f0 is located 0 bytes to the right of 432-byte region [0x614000000040,0x6140000001f0)
allocated by thread T0 here:
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7f76fdf139e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2
    #2 0x7f76fde8f081 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:490:11
    #3 0x7f76fde8f081 in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #4 0x7f76fdf132e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #5 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #6 0x7f76fcf6e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_interceptors.cc:453 in __asan_memcpy

Reproducer:
HEAP-input-tga.c-252-15.TGA
CVE:
CVE-2017-9191

#########################################

==3665==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fd1da8f5803 at pc 0x0000004b9b35 bp 0x7ffcc2ab6cb0 sp 0x7ffcc2ab6460
WRITE of size 2147385265 at 0x7fd1da8f5803 thread T0
    #0 0x4b9b34 in __asan_memset /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_interceptors.cc:457
    #1 0x7fd1dfe2052e in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:528:7
    #2 0x7fd1dfe2052e in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #3 0x7fd1dfea42e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7fd1deeff680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #6 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x7fd1da8f5803 is located 0 bytes to the right of 2147188739-byte region [0x7fd15a93d800,0x7fd1da8f5803)
allocated by thread T0 here:
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7fd1dfea49e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2
    #2 0x7fd1dfe20081 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:490:11
    #3 0x7fd1dfe20081 in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #4 0x7fd1dfea42e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #5 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #6 0x7fd1deeff680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_intercept

Reproducer:
HEAP-input-tga.c-528-7.TGA
CVE:
CVE-2017-9192

#########################################

==4277==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000ce at pc 0x7f0fd82f5740 bp 0x7fffa1c10cb0 sp 0x7fffa1c10ca8             
READ of size 1 at 0x6020000000ce thread T0                                                                                                           
    #0 0x7f0fd82f573f in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:538:33                               
    #1 0x7f0fd82f573f in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157                           
    #2 0x7f0fd83762e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13                          
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16                                               
    #4 0x7f0fd73d1680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                           
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)                                                                                               
                                                                                                                                                     
Address 0x6020000000ce is a wild pointer.                                                                                                            
SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:538:33 in ReadImage

Reproducer:
HEAP-input-tga.c-538-33.TGA
CVE:
CVE-2017-9193

#########################################

==4417==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f6e03dfea81 at pc 0x7f6e09772720 bp 0x7ffc16306cb0 sp 0x7ffc16306ca8
READ of size 1 at 0x7f6e03dfea81 thread T0
    #0 0x7f6e0977271f in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:559:29
    #1 0x7f6e0977271f in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #2 0x7f6e097f32e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f6e0884e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x7f6e03dfea81 is located 1 bytes to the right of 122167936-byte region [0x7f6dfc97c800,0x7f6e03dfea80)
allocated by thread T0 here:
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7f6e097f39e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2
    #2 0x7f6e0976f081 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:490:11
    #3 0x7f6e0976f081 in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #4 0x7f6e097f32e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #5 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #6 0x7f6e0884e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:559:29 in ReadImage

Reproducer:
HEAP-input-tga.c-559-29.TGA
CVE:
CVE-2017-9194

#########################################

==4272==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000322 at pc 0x7f119fdf26b8 bp 0x7ffc12807cb0 sp 0x7ffc12807ca8
READ of size 1 at 0x602000000322 thread T0
    #0 0x7f119fdf26b7 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:620:27
    #1 0x7f119fdf26b7 in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #2 0x7f119fe732e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #3 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #4 0x7f119eece680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #5 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

Address 0x602000000322 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:620:27 in ReadImage

Reproducer:
HEAP-input-tga.c-620-27.TGA
CVE:
CVE-2017-9195

#########################################

==4317==ERROR: AddressSanitizer: negative-size-param: (size=-393212)
    #0 0x4b9c19 in __asan_memset /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_interceptors.cc:457
    #1 0x7fb89cb5952e in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:528:7
    #2 0x7fb89cb5952e in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #3 0x7fb89cbdd2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #4 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #5 0x7fb89bc38680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #6 0x41a708 in _init (/usr/bin/autotrace+0x41a708)

0x7fb81763d800 is located 0 bytes inside of 2147188739-byte region [0x7fb81763d800,0x7fb8975f5803)
allocated by thread T0 here:
    #0 0x4d02b0 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7fb89cbdd9e1 in at_bitmap_init /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:191:2
    #2 0x7fb89cb59081 in ReadImage /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:490:11
    #3 0x7fb89cb59081 in input_tga_reader /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/input-tga.c:157
    #4 0x7fb89cbdd2e9 in at_bitmap_read /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/autotrace.c:142:13
    #5 0x50da1e in main /tmp/portage/media-gfx/autotrace-0.31.1-r8/work/autotrace-0.31.1/main.c:133:16
    #6 0x7fb89bc38680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: negative-size-param /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_interceptors.cc:457 in __asan_memset

Reproducer:
NEGATIVESIZE-input-tga.c-528-7.TGA
CVE:
CVE-2017-9196

#########################################

input-tga.c:498:55: runtime error: signed integer overflow: 1491099865 * 3 cannot be represented in type 'int'                                       
SUMMARY: AddressSanitizer: undefined-behavior input-tga.c:498:55 in                                                                                  
input-tga.c:508:18: runtime error: signed integer overflow: 77871 * 57445 cannot be represented in type 'int'                                        
SUMMARY: AddressSanitizer: undefined-behavior input-tga.c:508:18 in                                                                                  
input-tga.c:192:19: runtime error: signed integer overflow: 1491099865 * 4 cannot be represented in type 'int'                                       
SUMMARY: AddressSanitizer: undefined-behavior input-tga.c:192:19 in                                                                                  
input-tga.c:528:63: runtime error: signed integer overflow: 1491099865 * 4 cannot be represented in type 'int' 

Reproducer:
UNDEF-input-tga.c.TGA
CVE:
CVE-2017-9197
CVE-2017-9198
CVE-2017-9199
CVE-2017-9200

#########################################

Credit:
These bugs were discovered by Agostino Sarubbo of Gentoo.

Reproducer:
https://github.com/asarubbo/poc/blob/master/00285-autotrace-multiple-vulnerabilities.tar

Sources:
https://github.com/asarubbo/poc/blob/master/00286-autotrace-sources.tar.xz

Timeline:
2017-04-10: bugs discovered
2017-05-20: blog post about the issues
2017-05-23: CVE assigned

Note:
These bugs were found with American Fuzzy Lop.

Permalink:

autotrace: multiple vulnerabilities (The autotrace nightmare)

May 19, 2017
Hanno Böck a.k.a. hanno (homepage, bugs)

Today the OCSP servers from Let’s Encrypt were offline for a while. This has caused far more trouble than it should have, because in theory we have all the technologies available to handle such an incident. However due to failures in how they are implemented they don’t really work.

We have to understand some background. Encrypted connections using the TLS protocol like HTTPS use certificates. These are essentially cryptographic public keys together with a signed statement from a certificate authority that they belong to a certain host name.

CRL and OCSP – two technologies that don’t work

Certificates can be revoked. That means that for some reason the certificate should no longer be used. A typical scenario is when a certificate owner learns that his servers have been hacked and his private keys stolen. In this case it’s good to avoid that the stolen keys and their corresponding certificates can still be used. Therefore a TLS client like a browser should check that a certificate provided by a server is not revoked.

That’s the theory at least. However the history of certificate revocation is a history of two technologies that don’t really work.

One method are certificate revocation lists (CRLs). It’s quite simple: A certificate authority provides a list of certificates that are revoked. This has an obvious limitation: These lists can grow. Given that a revocation check needs to happen during a connection it’s obvious that this is non-workable in any realistic scenario.

The second method is called OCSP (Online Certificate Status Protocol). Here a client can query a server about the status of a single certificate and will get a signed answer. This avoids the size problem of CRLs, but it still has a number of problems. Given that connections should be fast it’s quite a high cost for a client to make a connection to an OCSP server during each handshake. It’s also concerning for privacy, as it gives the operator of an OCSP server a lot of information.

However there’s a more severe problem: What happens if an OCSP server is not available? From a security point of view one could say that a certificate that can’t be OCSP-checked should be considered invalid. However OCSP servers are far too unreliable. So practically all clients implement OCSP in soft fail mode (or not at all). Soft fail means that if the OCSP server is not available the certificate is considered valid.

That makes the whole OCSP concept pointless: If an attacker tries to abuse a stolen, revoked certificate he can just block the connection to the OCSP server – and thus a client can’t learn that it’s revoked. Due to this inherent security failure Chrome decided to disable OCSP checking altogether. As a workaround they have something called CRLsets and Mozilla has something similar called OneCRL, which is essentially a big revocation list for important revocations managed by the browser vendor. However this is a weak workaround that doesn’t cover most certificates.

OCSP Stapling and Must Staple to the rescue?

There are two technologies that could fix this: OCSP Stapling and Must-Staple.

OCSP Stapling moves the querying of the OCSP server from the client to the server. The server gets OCSP replies and then sends them within the TLS handshake. This has several advantages: It avoids the latency and privacy implications of OCSP. It also allows surviving short downtimes of OCSP servers, because a TLS server can cache OCSP replies (they’re usually valid for several days).

However it still does not solve the security issue: If an attacker has a stolen, revoked certificate it can be used without Stapling. The browser won’t know about it and will query the OCSP server, this request can again be blocked by the attacker and the browser will accept the certificate.

Therefore an extension for certificates has been introduced that allows us to require Stapling. It’s usually called OCSP Must-Staple and is defined in https://tools.ietf.org/html/rfc7633 RFC 7633 (although the RFC doesn’t mention the name Must-Staple, which can cause some confusion). If a browser sees a certificate with this extension that is used without OCSP Stapling it shouldn’t accept it.

So we should be fine. With OCSP Stapling we can avoid the latency and privacy issues of OCSP and we can avoid failing when OCSP servers have short downtimes. With OCSP Must-Staple we fix the security problems. No more soft fail. All good, right?

The OCSP Stapling implementations of Apache and Nginx are broken

Well, here come the implementations. While a lot of protocols use TLS, the most common use case is the web and HTTPS. According to Netcraft statistics by far the biggest share of active sites on the Internet run on Apache (about 46%), followed by Nginx (about 20 %). It’s reasonable to say that if these technologies should provide a solution for revocation they should be usable with the major products in that area. On the server side this is only OCSP Stapling, as OCSP Must Staple only needs to be checked by the client.

What would you expect from a working OCSP Stapling implementation? It should try to avoid a situation where it’s unable to send out a valid OCSP response. Thus roughly what it should do is to fetch a valid OCSP response as soon as possible and cache it until it gets a new one or it expires. It should furthermore try to fetch a new OCSP response long before the old one expires (ideally several days). And it should never throw away a valid response unless it has a newer one. Google developer Ryan Sleevi wrote a detailed description of what a proper OCSP Stapling implementation could look like.

Apache does none of this.

If Apache tries to renew the OCSP response and gets an error from the OCSP server – e. g. because it’s currently malfunctioning – it will throw away the existing, still valid OCSP response and replace it with the error. It will then send out stapled OCSP errors. Which makes zero sense. Firefox will show an error if it sees this. This has been reported in 2014 and is still unfixed.

Now there’s an option in Apache to avoid this behavior: SSLStaplingReturnResponderErrors. It’s defaulting to on. If you switch it off you won’t get sane behavior (that is – use the still valid, cached response), instead Apache will disable Stapling for the time it gets errors from the OCSP server. That’s better than sending out errors, but it obviously makes using Must Staple a no go.

It gets even crazier. I have set this option, but this morning I still got complaints that Firefox users were seeing errors. That’s because in this case the OCSP server wasn’t sending out errors, it was completely unavailable. For that situation Apache has a feature that will fake a tryLater error to send out to the client. If you’re wondering how that makes any sense: It doesn’t. The “tryLater” error of OCSP isn’t useful at all in TLS, because you can’t try later during a handshake which only lasts seconds.

This is controlled by another option: SSLStaplingFakeTryLater. However if we read the documentation it says “Only effective if SSLStaplingReturnResponderErrors is also enabled.” So if we disabled SSLStapingReturnResponderErrors this shouldn’t matter, right? Well: The documentation is wrong.

There are more problems: Apache doesn’t get the OCSP responses on startup, it only fetches them during the handshake. This causes extra latency on the first connection and increases the risk of hitting a situation where you don’t have a valid OCSP response. Also cached OCSP responses don’t survive server restarts, they’re kept in an in-memory cache.

There’s currently no way to configure Apache to handle OCSP stapling in a reasonable way. Here’s the configuration I use, which will at least make sure that it won’t send out errors and cache the responses a bit longer than it does by default:

SSLStaplingCache shmcb:/var/tmp/ocsp-stapling-cache/cache(128000000)
SSLUseStapling on
SSLStaplingResponderTimeout 2
SSLStaplingReturnResponderErrors off
SSLStaplingFakeTryLater off
SSLStaplingStandardCacheTimeout 86400


I’m less familiar with Nginx, but from what I hear it isn’t much better either. According to https://blog.crashed.org/nginx-stapling-busted/ this blogpost it doesn’t fetch OCSP responses on startup and will send out the first TLS connections without stapling even if it’s enabled. Here’s a blog post that recommends to work around this by connecting to all configured hosts after the server has started.

To summarize: This is all a big mess. Both Apache and Nginx have OCSP Stapling implementations that are essentially broken. As long as you’re using either of those then enabling Must-Staple is a reliable way to shoot yourself in the foot and get into trouble. Don’t enable it if you plan to use Apache or Nginx.

Certificate revocation is broken. It has been broken since the invention of SSL and it’s still broken. OCSP Stapling and OCSP Must-Staple could fix it in theory. But that would require working and stable implementations in the most widely used server products.

May 18, 2017
Sven Vermeulen a.k.a. swift (homepage, bugs)
Matching MD5 SSH fingerprint (May 18, 2017, 16:20 UTC)

Today I was attempting to update a local repository, when SSH complained about a changed fingerprint, something like the following:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:p4ZGs+YjsBAw26tn2a+HPkga1dPWWAWX+NEm4Cv4I9s.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/user/.ssh/known_hosts:9
ECDSA host key for 192.168.56.101 has changed and you have requested strict checking.
Host key verification failed.

I checked if the host was changed recently, or the alias through which I connected switched host, or the SSH key changed. But that wasn't the case. Or at least, it wasn't the case recently, and I distinctly remember connecting to the same host two weeks ago.

Now, what happened I don't know yet, but I do know I didn't want to connect until I reviewed the received SSH key fingerprint. I obtained the fingerprint from the administration (who graceously documented it on the wiki)...

... only to realize that the documented fingerprint are MD5 hashes (and in hexadecimal result) whereas the key shown by the SSH command shows it in base64 SHA256 by default.

Luckily, a quick search revealed this superuser post which told me to connect to the host using the FingerprintHash md5 option:

~$ ssh -o FingerprintHash=md5 192.168.56.11

The result is SSH displaying the MD5 hashed fingerprint which I can now validate against the documented one. Once I validated that the key is the correct one, I accepted the change and continued with my endeavour.

I later discovered (or, more precisely, have strong assumptions) that I had an old elliptic curve key registered in my known_hosts file, which was not used for the communication for quite some time. I recently re-enabled elliptic curve support in OpenSSH (with Gentoo's USE="-bindist") which triggered the validation of the old key.

May 16, 2017
Alexys Jacob a.k.a. ultrabug (homepage, bugs)

In my previous blog post, I demonstrated how to use the PIV feature of a Yubikey to add a 2nd factor authentication to SSH.

Careful readers such as Grzegorz Kulewski pointed out that using the GPG capability of the Yubikey was also a great, more versatile and more secure option on the table (I love those community insights):

  • GPG keys and subkeys are indeed more flexible and can be used for case-specific operations (signing, encryption, authentication)
  • GPG is more widely used and one could use their Yubikey smartcard for SSH, VPN, HTTP auth and code signing
  • The Yubikey 4 GPG feature supports 4096 bit keys (limited to 2048 for PIV)

While I initially looked at the GPG feature, its apparent complexity got me to discard it for my direct use case (SSH). But I couldn’t resist the good points of Grzegorz and here I got back into testing it. Thank you again Grzegorz for the excuse you provided 😉

So let’s get through with the GPG feature of the Yubikey to authenticate our SSH connections. Just like the PIV method, this one has the  advantage to allow a 2nd factor authentication while using the public key authentication mechanism of OpenSSH and thus does not need any kind of setup on the servers.

Method 3 – SSH using Yubikey and GPG

Acknowledgement

The first choice you have to make is to decide whether you allow your master key to be stored on the Yubikey or not. This choice will be guided by how you plan to use and industrialize your usage of the GPG based SSH authentication.

Consider this to choose whether to store the master key on the Yubikey or not:

  • (con) it will not allow the usage of the same GPG key on multiple Yubikeys
  • (con) if you loose your Yubikey, you will have to revoke your entire GPG key and start from scratch (since the secret key is stored on the Yubikey)
  • (pro) by storing everything on the Yubikey, you won’t necessary have to have an offline copy of your master key (and all the process that comes with it)
  • (pro) it is easier to generate and store everything on the key and is then a good starting point for new comers or rare GPG users

Because I want to demonstrate and enforce the most straightforward way of using it, I will base this article on generating and storing everything on a Yubikey 4. You can find useful links at the end of the article pointing to reference on how to do it differently.

Tools installation

For this to work, we will need some tools on our local machine to setup our Yubikey correctly.

Gentoo users should install those packages:

emerge -av dev-libs/opensc sys-auth/ykpers app-crypt/ccid sys-apps/pcsc-tools app-crypt/gnupg

Gentoo users should also allow the pcscd service to be hotplugged (started automatically upon key insertion) by modifying their /etc/rc.conf and having:

rc_hotplug="pcscd"

Yubikey setup

The idea behind the Yubikey setup is to generate and store the GPG keys directly on our Yubikey and to secure them via a PIN code (and an admin PIN code).

  • default PIN code: 123456
  • default admin PIN code: 12345678

First, insert your Yubikey and let’s change its USB operating mode to OTP+U2F+CCID with MODE_FLAG_EJECT flag.

ykpersonalize -m86
Firmware version 4.3.4 Touch level 783 Program sequence 3

The USB mode will be set to: 0x86

Commit? (y/n) [n]: y

NOTE: if you have an older version of Yubikey (before Sept. 2014), use -m82 instead.

Then, we can generate a new GPG key on the Yubikey. Let’s open the smartcard for edition.

gpg --card-edit --expert

Reader ...........: Yubico Yubikey 4 OTP U2F CCID (0005435106) 00 00
Application ID ...: A7560001240102010006054351060000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 75435106
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

Then switch to admin mode.

gpg/card> admin
Admin commands are allowed

We can start generating the Signature, Encryption and Authentication keys on the Yubikey. During the process, you will be prompted alternatively for the admin PIN and PIN.

gpg/card> generate 
Make off-card backup of encryption key? (Y/n) 

Please note that the factory settings of the PINs are
   PIN = '123456'     Admin PIN = '12345678'
You should change them using the command --change-pin

I advise you say Yes to the off-card backup of the encryption key.

Yubikey 4 users can choose a 4096 bits key, let’s go for it for every key type.

What keysize do you want for the Signature key? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits
Note: There is no guarantee that the card supports the requested size.
      If the key generation does not succeed, please check the
      documentation of your card to see what sizes are allowed.
What keysize do you want for the Encryption key? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits
What keysize do you want for the Authentication key? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits

Then you’re asked for the expiration of your key. I choose 1 year but it’s up to you (leave 0 for no expiration).

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at mer. 15 mai 2018 21:42:42 CEST
Is this correct? (y/N) y

Finally you give GnuPG details about your user ID and you will be prompted for a passphrase (make it strong).

GnuPG needs to construct a user ID to identify your key.

Real name: Ultrabug
Email address: ultrabug@nospam.com
Comment: 
You selected this USER-ID:
    "Ultrabug <ultrabug@nospam.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

If you chose to make an off-card backup of your key, you will also get notified of its location as well the revocation certificate.

gpg: Note: backup of card key saved to '/home/ultrabug/.gnupg/sk_8E407636C9C32C38.gpg'
gpg: key 22A73AED8E766F01 marked as ultimately trusted
gpg: revocation certificate stored as '/home/ultrabug/.gnupg/openpgp-revocs.d/A1580FD98C0486D94C1BE63B22A73AED8E766F01.rev'
public and secret key created and signed.

Make sure to store that backup in a secure and offline location.

You can verify that everything went good and take this chance to note the public key ID.

gpg/card> verify

Reader ...........: Yubico Yubikey 4 OTP U2F CCID (0001435106) 00 00
Application ID ...: A7560001240102010006054351060000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 75435106
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: A158 0FD9 8C04 86D9 4C1B E63B 22A7 3AED 8E76 6F01
 created ....: 2017-05-16 20:43:17
Encryption key....: E1B6 7009 907D 1D94 B200 37D7 8E40 7636 C9C3 2C38
 created ....: 2017-05-16 20:43:17
Authentication key: AAED AB8E E055 41B2 EFFF 62A4 164F 873A 75D2 AD6B
 created ....: 2017-05-16 20:43:17
General key info..: pub rsa4096/22A73AED8E766F01 2017-05-16 Ultrabug <ultrabug@nospam.com>
sec> rsa4096/22A73AED8E766F01 created: 2017-05-16 expires: 2018-05-16
 card-no: 0001 05435106
ssb> rsa4096/164F873A75D2AD6B created: 2017-05-16 expires: 2018-05-16
 card-no: 0001 05435106
ssb> rsa4096/8E407636C9C32C38 created: 2017-05-16 expires: 2018-05-16
 card-no: 0001 05435106

You’ll find the public key ID on the “General key info” line (22A73AED8E766F01):

General key info..: pub rsa4096/22A73AED8E766F01 2017-05-16 Ultrabug <ultrabug@nospam.com>

Quit the card edition.

gpg/card> quit

It is then convenient to upload your public key to a key server, whether public or on your own web server (you can also keep it to be used and imported directly from an USB stick).

Export the public key:

gpg --armor --export 22A73AED8E766F01 > 22A73AED8E766F01.asc

Then upload it to your http server or a public server (needed if you want to be able to easily use the key on multiple machines):

# Upload it to your http server
scp 22A73AED8E766F01.asc user@server:public_html/static/22A73AED8E766F01.asc

# OR upload it to a public keyserver
gpg --keyserver hkps://hkps.pool.sks-keyservers.net --send-key 22A73AED8E766F01

Now we can finish up the Yubikey setup. Let’s edit the card again:

gpg --card-edit --expert

Reader ...........: Yubico Yubikey 4 OTP U2F CCID (0001435106) 00 00
Application ID ...: A7560001240102010006054351060000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 75435106
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: A158 0FD9 8C04 86D9 4C1B E63B 22A7 3AED 8E76 6F01
 created ....: 2017-05-16 20:43:17
Encryption key....: E1B6 7009 907D 1D94 B200 37D7 8E40 7636 C9C3 2C38
 created ....: 2017-05-16 20:43:17
Authentication key: AAED AB8E E055 41B2 EFFF 62A4 164F 873A 75D2 AD6B
 created ....: 2017-05-16 20:43:17
General key info..: pub rsa4096/22A73AED8E766F01 2017-05-16 Ultrabug <ultrabug@nospam.com>
sec> rsa4096/22A73AED8E766F01 created: 2017-05-16 expires: 2018-05-16
 card-no: 0001 05435106
ssb> rsa4096/164F873A75D2AD6B created: 2017-05-16 expires: 2018-05-16
 card-no: 0001 05435106
ssb> rsa4096/8E407636C9C32C38 created: 2017-05-16 expires: 2018-05-16
 card-no: 0001 05435106
gpg/card> admin

Make sure that the Signature PIN is forced to request that your PIN is entered when your key is used. If it is listed as “not forced”, you can enforce it by entering the following command:

gpg/card> forcesig

It is also good practice to set a few more settings on your key.

gpg/card> login
Login data (account name): ultrabug

gpg/card> lang
Language preferences: en

gpg/card> name 
Cardholder's surname: Bug
Cardholder's given name: Ultra

Now we need to setup the PIN and admin PIN on the card.

gpg/card> passwd 
gpg: OpenPGP card no. A7560001240102010006054351060000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? Q

If you uploaded your public key on your web server or a public server, configure it on the key:

gpg/card> url
URL to retrieve public key: http://ultrabug.fr/keyserver/22A73AED8E766F01.asc

gpg/card> quit

Now we can quit the gpg card edition, we’re done on the Yubikey side!

gpg/card> quit

SSH client setup

This is the setup on the machine(s) where you will be using the GPG key. The idea is to import your key from the card to your local keyring so you can use it on gpg-agent (and its ssh support).

You can skip the fetch/import part below if you generated the key on the same machine than you are using it. You should see it listed when executing gpg -k.

Plug-in your Yubikey and load the smartcard.

gpg --card-edit --expert

Then fetch the key from the URL to import it to your local keyring.

gpg/card> fetch

Then you’re done on this part, exit gpg and update/display& your card status.

gpg/card> quit

gpg --card-status

You can verify the presence of the key in your keyring:

gpg -K
sec>  rsa4096 2017-05-16 [SC] [expires: 2018-05-16]
      A1580FD98C0486D94C1BE63B22A73AED8E766F01
      Card serial no. = 0001 05435106
uid           [ultimate] Ultrabug <ultrabug@nospam.com>
ssb>  rsa4096 2017-05-16 [A] [expires: 2018-05-16]
ssb>  rsa4096 2017-05-16 [E] [expires: 2018-05-16]

Note the “Card serial no.” showing that the key is actually stored on a smartcard.

Now we need to configure gpg-agent to enable ssh support, edit your ~/.gnupg/gpg-agent.conf configuration file and make sure that the enable-ssh-support is present:

default-cache-ttl 7200
max-cache-ttl 86400
enable-ssh-support

Then you will need to update your ~/.bashrc file to automatically start gpg-agent and override ssh-agent’s environment variables. Add this at the end of your ~/.bashrc file (or equivalent).

# start gpg-agent if it's not running
# then override SSH authentication socket to use gpg-agent
pgrep -l gpg-agent &>/dev/null
if [[ "$?" != "0" ]]; then
 gpg-agent --daemon &>/dev/null
fi
SSH_AUTH_SOCK=/run/user/$(id -u)/gnupg/S.gpg-agent.ssh
export SSH_AUTH_SOCK

To simulate a clean slate, unplug your card then kill any running gpg-agent:

killall gpg-agent

Then plug back your card and source your ~/.bashrc file:

source ~/.bashrc

Your GPG key is now listed in you ssh identities!

ssh-add -l
4096 SHA256:a4vsJM6Sw1Rt8orvPnI8nvNUwHbRQ67ylnoTxruozK9 cardno:000105435106 (RSA)

You will now be able to get the SSH public key hash to copy to your remote servers using:

ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCVDq24Ld/bOzc3yNnY6fF7FNfZnb6wRVdN2xMo1YiA5pz20y+2P1ynq0rb6l/wsSip0Owq4G6fzaJtT1pBUAkEJbuMvZBrbYokb2mZ78iFZyzAkCT+C9YQtvPClFxSnqSL38jBpunZuuiFfejM842dWdMNK3BTcjeTQdTbmY+VsVOw7ppepRh7BWslb52cVpg+bHhB/4H0BUUd/KHZ5sor0z6e1OkqIV8UTiLY2laCCL8iWepZcE6n7MH9KItqzX2I9HVIuLCzhIib35IRp6d3Whhw3hXlit4/irqkIw0g7s9jC8OwybEqXiaeQbmosLromY3X6H8++uLnk7eg9RtCwcWfDq0Qg2uNTEarVGgQ1HXFr8WsjWBIneC8iG09idnwZNbfV3ocY5+l1REZZDobo2BbhSZiS7hKRxzoSiwRvlWh9GuIv8RNCDss9yNFxNUiEIi7lyskSgQl3J8znDXHfNiOAA2X5kVH0s6AQx4hQP9Dl1X2Em4zOz+yJEPFnAvE+XvBys1yuUPq1c3WKMWzongZi8JNu51Yfj7Trm74hoFRn+CREUNpELD9JignxlvkoKAJpWVLdEu1bxJ7jh7kcMQfVEflLbfkEPLV4nZS4sC1FJR88DZwQvOudyS69wLrF3azC1Gc/fTgBiXVVQwuAXE7vozZk+K4hdrGq4u7Gw== cardno:000105435106

This is what ends up in ~/.ssh/authorized_keys on your servers.

When connecting to your remote server, you will be prompted for the PIN!

Conclusion

Using the GPG feature of your Yubikey is very convenient and versatile. Even if it is not that hard after all, it is interesting and fair to note that the PIV method is indeed more simple to implement.

When you need to maintain a large number of security keys in an organization and that their usage is limited to SSH, you will be inclined to stick with PIV if 2048 bits keys are acceptable for you.

However, for power users and developers, usage of GPG is definitely something you need to consider for its versatility and enhanced security.

Useful links

You may find those articles useful to setup your GPG key differently and avoid having the secret key tied to your Yubikey.

Sebastian Pipping a.k.a. sping (homepage, bugs)

Hi!

When I started fetchcommandwrapper about 6 years ago it was a proof of concept: It plugged into portage replacing wget for downloads, facilitating ${GENTOO_MIRRORS} and aria2 to both download faster and distribute loads across mirrors. A hack for sure, but with some potential.

Back then public interest was non-existent, fetchcommandwrapper had some issues — e.g. metadata.xsd downloads failed and some sites rejected downloading before it made aria2 dress like wget — and I stopped using it myself, eventually.

With the latest bug reports, bugfixes and release of version 0.8 in Gentoo, fetchcommandwrapper is ready for general use now. To give it a shot, you emerge app-portage/fetchcommandwrapper and append source /usr/share/fetchcommandwrapper/make.conf to /etc/portage/make.conf. Done.

If you have extra options that you would like to pass to aria2c, put them in ${FETCHCOMMANDWRAPPER_EXTRA}, or ${FETCHCOMMANDWRAPPER_OPTIONS} for fetchcommendwrapper itself; for example

FETCHCOMMANDWRAPPER_OPTIONS="--link-speed=600000"

tells fetchcommandwrapper that my download link has 600KB/s only and makes aria2 in turn drop connections to mirrors that cannot keep up with at least a third of that, so that faster mirrors get a chance to take their place.

For non-ebuild bugs, feel free to use https://github.com/gentoo/fetchcommandwrapper/issues to report.

Best, Sebastian

May 12, 2017
Alexys Jacob a.k.a. ultrabug (homepage, bugs)

In my previous blog post, I demonstrated how to use a Yubikey to add a 2nd factor (2FA) authentication to SSH using pam_ssh and pam_yubico.

In this article, I will go further and demonstrate another method using Yubikey’s Personal Identity Verification (PIV) capability.

This one has the huge advantage to allow a 2nd factor authentication while using the public key authentication mechanism of OpenSSH and thus does not need any kind of setup on the servers.

Method 2 – SSH using Yubikey and PIV

Yubikey 4 and NEO also act as smartcards supporting the PIV standard which allows you to store a private key on your security key through PKCS#11. This is an amazing feature which is also very good for our use case.

Tools installation

For this to work, we will need some tools on our local machines to setup our Yubikey correctly.

Gentoo users should install those packages:

emerge dev-libs/opensc sys-auth/ykpers sys-auth/yubico-piv-tool sys-apps/pcsc-lite app-crypt/ccid sys-apps/pcsc-tools sys-auth/yubikey-personalization-gui

Gentoo users should also allow the pcscd service to be hotplugged (started automatically upon key insertion) by modifying their /etc/rc.conf and having:

rc_hotplug="pcscd"

Yubikey setup

The idea behind the Yubikey setup is to generate and store a private key in our Yubikey and to secure it via a PIN code.

First, insert your Yubikey and let’s change its USB operating mode to OTP+CCID.

ykpersonalize -m2
Firmware version 4.3.4 Touch level 783 Program sequence 3

The USB mode will be set to: 0x2

Commit? (y/n) [n]: y

Then, we will create a new management key:

key=`dd if=/dev/random bs=1 count=24 2>/dev/null | hexdump -v -e '/1 "%02X"'`
echo $key
D59E46FE263DDC052A409C68EB71941D8DD0C5915B7C143A

Replace the default management key (if prompted, copy/paste the key printed above):

yubico-piv-tool -a set-mgm-key -n $key --key 010203040506070801020304050607080102030405060708

Then change the default PIN code and PUK code of your Yubikey

yubico-piv-tool -a change-pin -P 123456 -N <NEW PIN>

yubico-piv-tool -a change-puk -P 12345678 -N <NEW PUK>

Now that your Yubikey is secure, let’s proceed with the PCKS#11 certificate generation. You will be prompted for your management key that you generated before.

yubico-piv-tool -s 9a -a generate -o public.pem -k

Then create a self-signed certificate (only used for libpcks11) and import it in the Yubikey:

yubico-piv-tool -a verify-pin -a selfsign-certificate -s 9a -S "/CN=SSH key/" -i public.pem -o cert.pem
yubico-piv-tool -a import-certificate -s 9a -i cert.pem

Here you are! You can now export your public key to use with OpenSSH:

ssh-keygen -D opensc-pkcs11.so -e
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWtqI37jwxYMJ9XLq9VwHgJlhZViPVAGIUfMm8SAlfs6cka4Cj570lkoGK04r8JAVJFy/iKfhGpL9N9XuartfIoq6Cg/6Qvg3REupuqs51V2cBaC/gnWIQ7qZqlzBulvcOvzNfHFD/lX42J58+E8tWnYg6GzIsImFZQVpmI6SxNfSmVQIqxIufInrbQaI+pKXntdTQC9wyNK5FAA8TXAdff5ZDnmetsOTVble9Ia5m6gqM7MnxNZ56uDpn+6lCxRZSW+Ln2PDE7sivVcST4qpfwY4P4Lrb3vrjCGODFg4xmGNKXsLi2+uZbs5rW7bg4HFO50kKDucPV1M+rBWA9999

Copy to your servers your SSH public key to your usual ~/.ssh/authorized_keys file in your $HOME.

Testing PIV secured SSH

Plug-in your Yubikey, and then SSH to your remote server using the opensc-pkcs11 library. You will be prompted for your PIN and then successfully logged in 🙂

ssh -I opensc-pkcs11.so cheetah
Enter PIN for 'PIV_II (PIV Card Holder pin)':

You can then configure SSH to use it by default for all your hosts in your ~/.ssh/config

Host=*
PKCS11Provider /usr/lib/opensc-pkcs11.so

Using PIV with ssh-agent

You can also use ssh-agent to avoid typing your PIN every time.

When asked for the passphrase, enter your PIN:

ssh-add -s /usr/lib/opensc-pkcs11.so
Enter passphrase for PKCS#11: 
Card added: /usr/lib/opensc-pkcs11.so

You can verify that it worked by listing the available keys in your ssh agent:

ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWtqI37jwxYMJ9XLq9VwHgJlhZViPVAGIUfMm8SAlfs6cka4Cj570lkoGK04r8JAVJFy/iKfhGpL9N9XuartfIoq6Cg/6Qvg3REupuqs51V2cBaC/gnWIQ7qZqlzBulvcOvzNfHFD/lX42J58+E8tWnYg6GzIsImFZQVpmI6SxNfSmVQIqxIufInrbQaI+pKXntdTQC9wyNK5FAA8TXAdff5ZDnmetsOTVble9Ia5m6gqM7MnxNZ56uDpn+6lCxRZSW+Ln2PDE7sivVcST4qpfwY4P4Lrb3vrjCGODFg4xmGNKXsLi2+uZbs5rW7bg4HFO50kKDucPV1M+rBWA9999 /usr/lib64/opensc-pkcs11.so

Enjoy!

Now you have a flexible yet robust way to authenticate your users which you can also extend by adding another type of authentication on your servers using PAM.

binutils: multiple crashes (May 12, 2017, 12:58 UTC)

Description:
binutils are a collection of binary tools necessary to build programs.

After the post on oss-security from Thuan Pham I was interested too into the fuzz of binutils to see what will happen…Here are the partial results (I didn’t run the fuzzers against all command-line tools):

# readelf -a $FILE
==12002==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000039 at pc 0x0000005a4f79 bp 0x7ffea5d104d0 sp 0x7ffea5d104c8
READ of size 1 at 0x602000000039 thread T0
    #0 0x5a4f78 in byte_get_little_endian /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/elfcomm.c:210:22
    #1 0x565bc4 in process_mips_specific /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:15190:8
    #2 0x52483a in process_arch_specific /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16565:14
    #3 0x52483a in process_object /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16770
    #4 0x50b57c in process_file /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17138:13
    #5 0x50b57c in main /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17209
    #6 0x7f2e28f6e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #7 0x419f68 in dl_iterate_phdr (/usr/x86_64-pc-linux-gnu/binutils-bin/2.28/readelf+0x419f68)

0x602000000039 is located 0 bytes to the right of 9-byte region [0x602000000030,0x602000000039)
allocated by thread T0 here:
    #0 0x4cf918 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x50be47 in get_data /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:392:9
    #2 0x565a00 in process_mips_specific /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:15169:32
    #3 0x52483a in process_arch_specific /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16565:14
    #4 0x52483a in process_object /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16770
    #5 0x50b57c in process_file /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17138:13
    #6 0x50b57c in main /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17209
    #7 0x7f2e28f6e680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /var/tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/elfcomm.c:210:22 in byte_get_little_endian

Affected version:
2.28
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00258-binutils-readelf-heapoverflow2-byte_get_little_endian
Commit fix:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f32ba72991d2406b21ab17edc234a2f3fa7fb23d
CVE:
CVE-2017-9038

###########################################

# readelf -a $FILE
==20389==ERROR: AddressSanitizer failed to allocate 0x18da5b8000 (106742644736) bytes of LargeMmapAllocator (error code: 12)
[...]
==20389==AddressSanitizer CHECK failed: /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_common.cc:120 "((0 && "unable to mmap")) != (0)" (0x0, 0x0)
[...]
    #8 0x66216d in xmalloc /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/libiberty/xmalloc.c:148:12
    #9 0x5e32c0 in cmalloc /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/dwarf.c:7450:10
    #10 0x582819 in get_program_headers /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:4761:33
    #11 0x55ab15 in process_program_headers /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:4814:9
    #12 0x52ea4f in process_object /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16751:7
    #13 0x51780f in process_file /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17138:13
    #14 0x51780f in main /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17209
    #15 0x7f252d57178f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #16 0x41a158 in getenv (/usr/x86_64-pc-linux-gnu/binutils-bin/2.28/readelf+0x41a158)

Affected version:
2.28
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00259-binutils-readelf-memallocfailure
Commit fix:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=82156ab704b08b124d319c0decdbd48b3ca2dac5
CVE:
CVE-2017-9039

###########################################

# readelf -a $FILE
==25206==WARNING: AddressSanitizer failed to allocate 0x40000000000070 bytes
==25206==AddressSanitizer's allocator is terminating the process instead of returning 0
==25206==If you don't like this behavior set allocator_may_return_null=1
==25206==AddressSanitizer CHECK failed: /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/sanitizer_common/sanitizer_allocator.cc:221 "((0)) != (0)" (0x0, 0x0)
[...]
    #6 0x66dcfd in xmalloc /tmp/portage/sys-devel/binutils-9999/work/binutils/libiberty/xmalloc.c:147:12
    #7 0x5e5a20 in cmalloc /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/dwarf.c:8259:10
    #8 0x5d2865 in process_mips_specific /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:15373:34
    #9 0x54ac16 in process_arch_specific /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:17449:14
    #10 0x54ac16 in process_object /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:17672
    #11 0x5167f8 in process_file /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:18055:13
    #12 0x5167f8 in main /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:18127
    #13 0x7fca769b578f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #14 0x41a088 in getenv (/usr/x86_64-pc-linux-gnu/binutils-bin/git/readelf+0x41a088)

Affected version:
master after commit 82156ab704b08b124d319c0decdbd48b3ca2dac5 which fixed the bug above
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00272-binutils-memallocfailure
Commit fix:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7296a62a2a237f6b1ad8db8c38b090e9f592c8cf
CVE:
CVE-2017-9040
###########################################

# readelf -a $FILE
==20287==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000039 at pc 0x00000064c061 bp 0x7ffcc34b2580 sp 0x7ffcc34b2578
READ of size 1 at 0x602000000039 thread T0
    #0 0x64c060 in byte_get_little_endian /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/elfcomm.c:210:22
    #1 0x5d31c5 in process_mips_specific /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:15190:8
    #2 0x549e1d in process_arch_specific /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16565:14
    #3 0x549e1d in process_object /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16770
    #4 0x51780f in process_file /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17138:13
    #5 0x51780f in main /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17209
    #6 0x7fa5fc60b78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #7 0x41a158 in getenv (/usr/x86_64-pc-linux-gnu/binutils-bin/2.28/readelf+0x41a158)

0x602000000039 is located 0 bytes to the right of 9-byte region [0x602000000030,0x602000000039)
allocated by thread T0 here:
    #0 0x4d9828 in malloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:66
    #1 0x518af2 in get_data /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:392:9
    #2 0x5d2ee2 in process_mips_specific /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:15169:32
    #3 0x549e1d in process_arch_specific /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16565:14
    #4 0x549e1d in process_object /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:16770
    #5 0x51780f in process_file /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17138:13
    #6 0x51780f in main /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/readelf.c:17209
    #7 0x7fa5fc60b78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/sys-devel/binutils-2.28/work/binutils-2.28/binutils/elfcomm.c:210:22 in byte_get_little_endian

Affected version:
2.28
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00258-binutils-readelf-heapoverflow2-byte_get_little_endian
Commit fix:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=75ec1fdbb797a389e4fe4aaf2e15358a070dcc19
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c4ab9505b53cdc899506ed421fddb7e1f8faf7a3
CVE:
CVE-2017-9041

###########################################

# readelf -a $FILE
/tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:9447:39: runtime error: signed integer overflow: 7443 - -9223372036854775080 cannot be represented in type 'long'

Affected version:
master at 2017-04-12 (dunno about other versions)
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00275-binutils-signintoverflow
Commit fix:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7296a62a2a237f6b1ad8db8c38b090e9f592c8cf
CVE:
CVE-2017-9042

###########################################

# readelf -a $FILE
/tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:16941:18: runtime error: shift exponent 64 is too large for 64-bit type 'unsigned long'

Affected version:
master at 2017-04-12 (dunno about other versions)
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00274-binutils-shifttoolarge
Commit fix:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ddef72cdc10d82ba011a7ff81cafbbd3466acf54
CVE:
CVE-2017-9043
###########################################

# readelf -a $FILE
==7569==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000004 (pc 0x0000005ca9f5 bp 0x7ffcef629b70 sp 0x7ffcef629b20 T0)
==7569==The signal is caused by a READ memory access.
==7569==Hint: address points to the zero page.
    #0 0x5ca9f4 in print_symbol_for_build_attribute /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:16671:16
    #1 0x5c2d08 in process_note /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c
    #2 0x5bc388 in process_notes_at /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:17232:13
    #3 0x5bbc82 in process_corefile_note_segments /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:17262:8
    #4 0x548d86 in process_object /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c
    #5 0x5167f8 in process_file /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:18055:13
    #6 0x5167f8 in main /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:18127
    #7 0x7f8ede38078f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #8 0x41a088 in getenv (/usr/x86_64-pc-linux-gnu/binutils-bin/git/readelf+0x41a088)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/portage/sys-devel/binutils-9999/work/binutils/binutils/readelf.c:16671:16 in print_symbol_for_build_attribute
==7569==ABORTING

Affected version:
master at 2017-04-12 (dunno about other versions)
Fixed version:
N/A
Reproducer:
https://github.com/asarubbo/poc/blob/master/00273-binutils-NULLptr-print_symbol_for_build_attribute
Commit fix:
N/A, seems to be fixed by one of the previous commits.
CVE:
CVE-2017-9044

###########################################

Credit:
These bugs were discovered by Agostino Sarubbo of Gentoo.

Timeline:
2017-04-01: first bug discovered and reported to upstream
2017-05-12: blog post about the issue
2017-05-18: CVE assigned

Note:
These bugs were found with American Fuzzy Lop.

Permalink:

binutils: multiple crashes

Alexys Jacob a.k.a. ultrabug (homepage, bugs)

I recently worked a bit at how we could secure better our SSH connections to our servers at work.

So far we are using the OpenSSH public key only mechanism which means that there is no password set on the servers for our users. While this was satisfactory for a time we think that this still suffers some disadvantages such as:

  • we cannot enforce SSH private keys to have a passphrase on the user side
  • the security level of the whole system is based on the protection of the private key which means that it’s directly tied to the security level of the desktop of the users

This lead us to think about adding a 2nd factor authentication to SSH and about the usage of security keys.

Meet the Yubikey

Yubikeys are security keys made by Yubico. They can support multiple modes and work with the U2F open authentication standard which is why they got my attention.

I decided to try the Yubikey 4 because it can act as a smartcard while offering these interesting features:

  • Challenge-Response
  • OTP
  • GPG
  • PIV

Method 1 – SSH using pam_ssh + pam_yubico

The first method I found satisfactory was to combine pam_ssh authentication module along with pam_yubico as a 2nd factor. This allows server side passphrase enforcement on SSH and the usage of the security key to login.

TL;DR: two gotchas before we begin

ADVISE: keep a root SSH session to your servers while deploying/testing this so you can revert any change you make and avoid to lock yourself out of your servers.

Setup pam_ssh

Use pam_ssh on the servers to force usage of a passphrase on a private key. The idea behind pam_ssh is that the passphrase of your SSH key serves as your SSH password.

Generate your SSH key pair with a passphrase on your local machine.

ssh-keygen -f identity
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in identity.
Your public key has been saved in identity.pub.
The key fingerprint is:
SHA256:a2/HNCe28+bpMZ2dIf9bodnBwnmD7stO5sdBOV6teP8 alexys@yazd
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                o|
|            . ++o|
|        S    BoOo|
|         .  B %+O|
|        o  + %+*=|
|       . .. @ .*+|
|         ....%B.E|
+----[SHA256]-----+

You then must copy your private key (named identity with no extension) to your servers under  the ~/.ssh/login-keys.d/ folder.

In your $HOME on the servers, you will get something like this:

.ssh/
├── known_hosts
└── login-keys.d
    └── identity

Then you can enable the pam_ssh authentication. Gentoo users should enable the pam_ssh USE flag for sys-auth/pambase and re-install.

Add this at the beginning of the file /etc/pam.d/ssh

auth    required    pam_ssh.so debug

The debug flag can be removed after you tested it correctly.

Disable public key authentication

Because it takes precedence over the PAM authentication mechanism, you have to disable OpenSSH PubkeyAuthentication authentication on /etc/ssh/sshd_config:

PubkeyAuthentication no

Enable PAM authentication on /etc/ssh/sshd_config

ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM yes

Test pam_ssh

Now you should be prompted for your SSH passphrase to login through SSH.

➜  ~ ssh cheetah
SSH passphrase:

Setup 2nd factor using pam_yubico

Now we will make use of our Yubikey security key to add a 2nd factor authentication to login through SSH on our servers.

Because the Yubikey is not physically plugged on the server, we cannot use an offline Challenge-Response mechanism, so we will have to use a third party to validate the challenge. Yubico gracefully provide an API for this and the pam_yubico module is meant to use it easily.

Preparing your account using your Yubikey (on your machine)

First of all, you need to get your Yubico API key ID from the following URL:

You will get a Client ID (this you will use) and Secret Key (this you will keep safe).

Then you will need to create an authorization mapping file which basically link your account to a Yubikey fingerprint (modhex). This is equivalent to saying “this Yubikey belongs to this user and can authenticate him”.

First, get your modhex:

Using this modhex, create your mapping file named authorized_yubikeys which will be copied to ~/.yubico/authorized_yubikeys on the servers (replace LOGIN_USERNAME with your actual account login name).

LOGIN_USERNAME:xxccccxxuuxx

NOTE: this mapping file can be a centralized one (in /etc for example) to handle all the users from a server. See the the authfile option on the doc.

Setting up OpenSSH (on your servers)

You must install pam_yubico on the servers. For Gentoo, it’s as simple as:

emerge sys-auth/pam_yubico

Copy your authentication mapping file to your home under the .yubico folder on all servers. You should get this:

.yubico/
└── authorized_yubikey

Configure pam to use pam_yubico. Add this after the pam_ssh on the file /etc/pam.d/ssh which should look like this now:

auth    required    pam_ssh.so
auth    required    pam_yubico.so id=YOUR_API_ID debug debug_file=/var/log/auth.log

The debug and debug_file flags can be removed after you tested it correctly.

Testing pam_yubico

Now you should be prompted for your SSH passphrase and then for your Yubikey OTP to login through SSH.

➜  ~ ssh cheetah
SSH passphrase: 
YubiKey for `ultrabug':

About the Yubico API dependency

Careful readers will notice that using pam_yubico introduces a strong dependency on the Yubico API availability. If the API becomes unreachable or your internet connection goes down then your servers would be unable to authenticate you!

The solution I found to this problem is to instruct pam to ignore the Yubikey authentication when pam_yubico is unable to contact the API.

In this case, the module will return a AUTHINFO_UNAVAIL code to PAM which we can act upon using the following syntax. The /etc/pam.d/ssh first lines should be changed to this:

auth    required    pam_ssh.so
auth    [success=done authinfo_unavail=ignore new_authtok_reqd=done default=die]    pam_yubico.so id=YOUR_API_ID debug debug_file=/var/log/auth.log

Now you can be sure to be able to use your Yubikey even if the API is down or unreachable 😉

May 08, 2017
Sebastian Pipping a.k.a. sping (homepage, bugs)

What’s Wrong with Disqus? / Replacing Disqus with Github Comments (donw.io)

Andreas K. Hüttel a.k.a. dilfridge (homepage, bugs)

If you're in Regensburg, please come to the physics colloquium next week (15.5., 16:00st, lecture hall H34)! See the linked PDF for the full talk announcement.

"Millikelvin transport experiments on carbon nanotubes - nanoelectromechanics, spectroscopy, and more"

May 05, 2017
Luca Barbato a.k.a. lu_zero (homepage, bugs)
Contributing to x264 (May 05, 2017, 18:50 UTC)

Another project I contribute to is x264. As per the previous post on the topic I’ll try to summarize how things work.

Overview

Coding style

x264 has a coding style and on review you will get asked to follow it, sadly the sources do not contain a document about it, you have to look around the code and match what is there.

Testing

x264 has an amazing test harness that doubles as benchmark harness to add support for additional architecture-specific optimizations. checkasm is really good in helping you write new code for this kind of purpose and make sure it is really faster.

It is automatic to use if you are adding a function already implemented in other architectures, if you want to extend the coverage for something new it is moderately difficult, mainly because you have to read the code since no documentation is available otherwise.

Submitting patches

Submitting code to x264 requires you to sign a cla, the process is sort of manual and involves exchanging emails with the person in charge to provide and collect the cla pdf once you signed it.

Once you are done on that you should rebase your changes over the sandbox branch, that’s somehow similar to the next branch on other projects and send them to the developer mailing list using git send-email.

Interaction

The review process will happen in the mailing list and you are supposed to be subscribed to it and interact with the reviewers there.

TL;DR

  • Mimic the coding style used in the project and hope you get it right
  • Peruse checkasm to make sure what you are doing works as intended and it is fast
  • Subscribe to the developer mailing list and learn how to use git send-email.
  • Be patient and wait for review comments in the mail box.

May 04, 2017
Luca Barbato a.k.a. lu_zero (homepage, bugs)
Contributing to libvpx (May 04, 2017, 15:45 UTC)

Recently I started to write the PowerPC/VSX support for libvpx, Alexandra will help as well.

Every open source project has its own rules, I found the choices taken in Libvpx interesting enough to write them down (and possibly help newcomers with some shortcuts).

Overview

Coding style

The coding style is strongly enforced, the CI system will bounce your code if it doesn’t adhere to the style.

This constraint is enforced through a clang-format ruleset.

If you are using vim, this makes your life easier, otherwise the git integration comes handy.

Otherwise:

# clang-format -i what/I/m/working/on.c

Works no matter what.

Testing

New code should have its testcase, if it isn’t already covered.

Libvpx uses gtest and it has a quite decent test coverage. A full run of the tests can take a large chunk of time, if you are working on specific code (e.g. dsp functions), is easy to run only the tests you care about like this:

# ./test_libvpx --gtest_filter="*pattern*with*globs"

The current system does not double as benchmarking tool, so you are quite on your own if you are trying to speed up some parts.

Adding brand new tests more annoying than it should since gtest is quite bloated, updating a test to cover a variant is quite painless though.

Submitting patches

Libvpx uses gerrit and jenkins in a setup that makes them almost painless and has a detailed guide on how to register and fill in some forms to make the Google lawyers happy.

Gerrit and Jenkins defaults are quite clunky, so they Libvpx maintainer definitely invested some time to get them in a better shape.

Once you registered and set the hook to tag your commits sending a set boils down to:

# git push https://chromium-review.googlesource.com/webm/libvpx HEAD:refs/for/master

Interaction

Comments and reports end up in your mailbox, spamming it a lot (expect about 5-6 emails per commit). You have to use the web interface to have decent interaction and luckily PolyGerrit isn’t terrible at all (just make sure your replies gets sent since it has the tendency of keeping them in draft mode).

TL;DR

  • read this
  • install clang-format, including the git integration
  • be ready to make changes in test/*.cc and cope with gtest verboseness.
  • be ready to receive tons of email and use your web browser

May 03, 2017
Nathan Zachary a.k.a. nathanzachary (homepage, bugs)
Aftermath album by Fever Fever (May 03, 2017, 01:13 UTC)

It’s been quite some time since I’ve reviewed an album here on the Z-Issue. That’s not because I haven’t discovered some excellent music out there. On the contrary, I’ve found a plethora of wonderful musicians, albums, and individual tracks. However, it’s more a matter of time (or lack thereof). I feel, though, that I have to review the album Aftermath by Fever Fever because I greatly appreciate those artists who really are at the top of their genre. I generally don’t care all that much for the pop side of rock, but this album is so captivating that I think it will appeal to just about any musical taste.

Fever Fever - Aftermath - album cover
click to enlarge

The title track Aftermath sets the stage for the indie-style rock infused with catchy hooks, melodies, vocals, and lyrics that’s to come. From there on, you’ll be wowed by the perky, unforgettable melody (in the vein of Pompeii by Bastille) of Hypnotized, the beautiful piano-backed track accented by wonderful pizzicato that is Hope is a Child’s Toy (which asserts the amazingly positive worldview of “If hope is a child’s toy, then I don’t ever want to grow old”), and the droning, drum-tap on the steering wheel rhythm of Madness.

So, if you’re looking for some fantastic music with uplifting and life-affirming lyrics, check out this record. If you like the first few tracks (or the ones that I referenced above), you won’t be disappointed by any of the other songs. Give it a listen, and buy a copy on Amazon Music or iTunes. You’ll not only have another great, repeat-worthy album in your collection, but you’ll help the artist keep on doing what they’re doing. 🙂

Cheers,
Zach

P.S. A big thank you to Wes for helping me get lossless copies of the tracks and appeasing this obnoxious audiophile. 🙂

April 30, 2017
Sebastian Pipping a.k.a. sping (homepage, bugs)

Hey there!

If you are not subscribed to the new Gentoo packages feed, let me quickly introduce you to SafeEyes that I started using on a daily basis. It has found it’s way into Gentoo as x11-misc/safeeyes now. This article does a good job:

SafeEyes Protects You From Eye Strain When Working On The Computer (webupd8.org)

Best, Sebastian

April 28, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
Project Memory (April 28, 2017, 14:03 UTC)

For a series of events that I’m not entirely sure the start of, I started fixing some links on my old blog posts, fixing some links that got broken, most of which I ended up having to find on the Wayback Archive. While looking at that, I ended up finding some content for my very old blog. A one that was hosted on Blogspot, written in Italian only, and seriously written by an annoying brat that needed to learn something about life. Which I did, of course. The story of that blog is for a different time and post, for now I’ll actually focus on a different topic.

When I started looking at this, I ended up going through a lot of my blogposts and updated a number of broken links, either by linking to the Wayback machine or by removing the link. I focused on those links that can easily be grepped for, which turns out to be a very good side effect of having migrated to Hugo.

This meant, among other things, removing references to identi.ca (which came to my mind because of all the hype I hear about Mastodon nowadays), removing links to my old “Hire me!” page, and so on. And that’s where things started showing a pattern.

I ended up updating or removing links to Berlios, Rubyforge, Gitorious, Google Code, Gemcutter, and so on.

For many of these, turned out I don’t even have a local copy (at hand at least) of some of my smaller projects (mostly the early Ruby stuff I’ve done). But I almost certainly have some of that data in my backups, some of which I actually have in Dublin and want to start digging into at some point soon. Again, this is a story for a different time.

The importance to the links to those project management websites is that for many projects, those pages were all that you had about them. And for some of those, all the important information was captured by those services.

Back when I started contributing to free software projects, SourceForge was the badge of honor of being an actual project: it would give you space to host a website, as well as the ability to have source code repositories and websites. And this was the era before Git, before Mercurial, and the other DVCS, which means either you had SourceForge, or you likely had no source control at all. But SourceForge admins also reviewed (or at least alleged to) every project that was created, and so creating a project on the platform was not straightforward, you would do that only if you really had the time to invest on the project.

A few projects were big enough to have their own servers, and a few projects were hosted in some other “random” project management sites, that for a while appeared to sprout out because the Forge software used by SourceForge was (for a while at least) released as free software itself. Some of those websites were specific in nature, others more general. Over time, BerliOS appeared to become the anti-SourceForge, with a streamlined application process, and most importantly, with Subversion years before SF would gain support for it.

Things got a bit more interesting later, when things like Bazaar, Mercurial, GIT and so on started appearing on the horizon, because at that point having proper source control could be achieved without needing special servers (without publishing it at least, although there were ways around that. Which at the same time made some project management website redundant, and others more appealable.

But, let’s take a look at the list of project management websites I have used and are now completely or partly gone, with or without history:

  • The aforementioned BerliOS, which has been teetering back and forth a couple of times. I had a couple of projects over there, which I ended up importing to GitHub, and I also forked unpaper. The service and the hosting were taken down in 2014, but (all?) the projects hosted on the platform were mirrored on SourceForge. As far as I can tell they were mirrored read-only, so for instance I can’t de-duplicate the unieject projects since I originally wrote it on SourceForge and then migrated to BerliOS.

  • The Danish SunSITE, which hosted a number of open-source projects for reasons that I’m not entirely clear on. NoX-Wizard, an open-source Ultima OnLine server emulator was hosted there, for reasons that are even murkier to me. The site got renamed to dotsrc.org, but they dropped all the hosting services in 2009. I can’t seem to find an archive of their data; Nox-Wizard was migrated during my time to SourceForge, so that’s okay by me.

  • RubyForge used that same Forge app as SourceForge, and was focused on Ruby module development. It was abruptly terminated in 2014, and as it turns out I made the mistake here of not importing my few modules explicitly. I should have them in my backups if I start looking for them, I just haven’t done so yet.

  • Gitorious set itself up as being an open, free software software to compete with GitHub. Unfortunately it clearly was not profitable enough and it got acquired, twice. The second time by competing service GitLab, that had no interest in running the software. A brittle mirror of the project repositories only (no user pages) is still online, thanks to Archive Team. I originally used Gitorious for my repositories rather than GitHub, but I came around to it and moved everything over before they shut the service down, well almost everything, as it turns out some of the LScube repos were not saved, because they were only mirrors… except that the domain for that project expired so we lost access to the main website and GIT repository, too.

  • Google Code was Google’s project hosting service, that started by offering Subversion repositories, downloads, issue trackers and so on. Very few of the projects I tracked used Google Code to begin with, and it was finally turned down in 2015, by making all projects read-only except for setting up a redirection to a new homepage. The biggest project I followed from Google Code was libarchive and they migrated it fully to GitHub, including migrating the issues.

  • Gemcutter used to be a repository for Ruby gems packages. I actually forgot why it was started, but it was for a while the alternative repository where a lot of cool kids stored their libraries. Gemcutter got merged back into rubygems.org and the old links now appear to redirect to the right pages. Yay!

With such a list of project hosting websites going the way of the dodo, an obvious conclusion to take is that hosting things on your own servers is the way to go. I would still argue otherwise. Despite the amount of hosting websites going away, it feels to me like the vast majority of the information we lost over the past 13 years is for blogs and personal websites badly used for documentation. With the exception of RubyForge, all the above examples were properly archived one way or the other, so at least the majority of the historical memory is not gone at all.

Not using project hosting websites is obviously an option. Unfortunately it comes with the usual problems and with even higher risks of losing data. Even GitLab’s snafu had higher chances to be fixed than whatever your one-person-project has when the owner gets tired, runs out of money, graduate from university, or even dies.

So what can we do to make things more resilient to disappearing? Let me suggest a few points of actions, which I think are relevant and possible right now to make things better for everybody.

First of all, let’s all make sure that the Internet Archive by donating. I set up a €5/month donation which gets matched by my employer. The Archive not only provides the Wayback Machine, which is how I can still fetch some of the content both from my past blogs and from blogs of people who deleted or moved them, or even passed on. Internet is our history, we can’t let it disappear without effort.

Then for what concerns the projects themselves, it may be a bit less clear cut. The first thing I’ll be much more wary about in the future is relying on the support sites when writing comments or commit messages. Issue trackers get lost, or renumbered, and so the references to those may be broken too easily. Be verbose in your commit messages, and if needed provide a quoted issue, instead of just “Fix issue #1123”.

Even mailing lists are not safe. While Gmane is currently supposedly still online, most of the gmane links from my own blog are broken, and I need to find replacements for them.

This brings me to the following problem: documentation. Wikis made documenting things significantly cheaper as you don’t need o learn lots neither in form of syntax nor in form of process. Unfortunately, backing up wikis is not easy because a database is involved, and it’s very hard, when taking over a project whose maintainers are unresponsive, to find a good way to import the wiki. GitHub makes thing easier thanks to their GitHub pages, and it’s at least a starting point. Unfortunately it makes the process a little more messy than the wiki, but we can survive that, I’m sure.

Myself, I decided to use a hybrid approach. Given that some of my projects such as unieject managed to migrate from SourceForge to BerliOS, to Gitorious, to GitHub, I have now set up a number of redirects on my website, so that their official websites will read https://www.flameeyes.eu/p/glucometerutils and it’ll redirect to wherever I’m hosting them at the time.

April 24, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
ELECOM DEFT and the broken descriptor (April 24, 2017, 10:03 UTC)

Update (2017-05-26): Jiri merged the patch, which may land in 4.12 or 4.13.

In my previous post reviewing the ELECOM DEFT I noted that I had to do some work to get the three function buttons on the mouse to work on Linux correctly. Let me try to dig a bit into this one so it can be useful to others in the future.

The simptoms: the three top buttons (Fn1, Fn2, Fn3) of the device are unresponsive on Linux, they do not show up on xev and evtest.

My first guess was that they were using the same technique they do for gaming mice, by configuring on the device itself what codes to send when the buttons are pressed. That looked likely because the receiver is appearing as a big composite device. But that was not the case. After installing the Windows driver and app on my “sacrificial laptop”, and using USBlyzer to figure out what was going on, I couldn’t see the app doing anything to the device. Which meant they instead remapped the behaviour of the buttons on the software side.

This left open only the option that the receiver needs a “quirk driver” to do something. Actually, since I have looked into HID (the protocol used for USB mice and keyboards, among others), I already knew the problem was the HID Report Descriptor is reporting something broken and the Linux kernel is ignoring it. I’m not sure if Windows is just ignoring the descriptor, or if there is a custom driver to implement the quirk there. I did not look too much into this.

But what is this descriptor? If you have not looked into HID before, you have to understand that the HID protocol in USB only specifies very little information by itself, and is mainly a common format for both sending “reports” and to describe said reports. The HID Report Descriptor is effectively bytecode representing the schema that those reports should follow. As it happens, sometimes it’s not the case at all, and the descriptor itself can even be completely broken and unparsable. But that is not the case here.

The descriptor is fetched by the operating system when you connect the device, and is then used to parse the reports coming as interrupt transfer. The first byte of each transfer refers to the report used, and that is looked up in the descriptor to understand it. In most mice, your reports will all look vastly the same: state of the buttons, relative X and Y displacement, wheel (one or two dimensional) displacement. But, since the presence of one or more wheels is not a given, and the amount of buttons to expect can be significantly high, even without going to the ludicrous extent of the OpenOffice mouse, the report descriptor will tell you the size of each field in the structure.

So, looking at USBlyzer, I could tell that the report number 1 was clearly the one that gives the mouse data, and even without knowing much about HID and having not seen the report descriptor, I can tell what’s going on:

button1: 01 01 00 00 00 00 00 00
button2: 01 02 00 00 00 00 00 00
button3: 01 04 00 00 00 00 00 00
fn1:     01 20 00 00 00 00 00 00
fn2:     01 40 00 00 00 00 00 00
fn3:     01 80 00 00 00 00 00 00

So quite obviously, the second byte is a bitmask of which button is being pressed. Note that this is the first of two reports you receive every time you click on the button (and everything is zero because on a trackball you can click the buttons without even touching the ball, and so there is no movement indication in the report).

But, when I looked at the Analysis tab, I found out that USBlyzer is going to parse the reports based on the descriptor as well, showing the button number from the bitmask, the X and Y displacement and so on. For the bitmasks of the three buttons at the top of the device, no button is listed in the analysis. Bingo, we have a problem.

The quest items. Thinking of it like a quest in a JRPG, I now needed two items to complete the quest: a way to figure out what the report descriptor of the device is and what it means. Let’s start from the first item.

There are a number of ways that you find documented for dumping a USB HID report descriptor on Linux. Most of them rely on you unbinding the device from the usbhid driver and then fetching it by sending the right HID commands. usbhid-dump does that and it does well, but I’m going to ignore that. Instead I’m going to read the report descriptor as is presented by sysfs. This may not be the one reported by the hardware, but rather the one that the quirk may have already “fixed” somehow.

So how can you tell where to find the report descriptor? If you look when you plug in a device:

% dmesg | tail -n 3
[13358.058915] elecom 0003:056E:00FF.000C: Fixing up Elecom DEFT Fn buttons
[13358.059721] input: ELECOM ELECOM TrackBall Mouse as /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2.1/3-2.1:1.0/0003:056E:00FF.000C/input/input45
[13358.111673] elecom 0003:056E:00FF.000C: input,hiddev0,hidraw1: USB HID v1.11 Mouse [ELECOM ELECOM TrackBall Mouse] on usb-0000:00:14.0-2.1/input0
% cp /sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2.1/3-2.1:1.0/0003:056E:00FF.000C/report_descriptor my_report_descriptor.bin

You can tell from this dmesg that I’m cheating, and I’m looking at it after the device has been fixed already. Otherwise it would probably be saying hid-generic rather than elecom.

I have made a copy of the original report descriptor of course, so I can look at it even now, but the binary file is not going to be very useful by itself. But, from the same author as the tool listed above, hidrd makes it significantly easier to understand what’s going on. The full spec output includes a number of report pages that are vendor specific, and may be interesting to either fuzz or figure out if they are used for reporting things such as low battery. But let’s ignore that for the immediate and let’s look at the “Desktop, Mouse” page:

Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Mouse),                      ; Mouse (02h, application collection)
Collection (Application),
    Usage (Pointer),                ; Pointer (01h, physical collection)
    Collection (Physical),
        Report ID (1),
        Report Count (5),
        Report Size (1),
        Usage Page (Button),        ; Button (09h)
        Usage Minimum (01h),
        Usage Maximum (05h),
        Logical Minimum (0),
        Logical Maximum (1),
        Input (Variable),
        Report Count (1),
        Report Size (3),
        Input (Constant),
        Report Size (16),
        Report Count (2),
        Usage Page (Desktop),       ; Generic desktop controls (01h)
        Usage (X),                  ; X (30h, dynamic value)
        Usage (Y),                  ; Y (31h, dynamic value)
        Logical Minimum (-32768),
        Logical Maximum (32767),
        Input (Variable, Relative),
    End Collection,
    Collection (Physical),
        Report Count (1),
        Report Size (8),
        Usage Page (Desktop),       ; Generic desktop controls (01h)
        Usage (Wheel),              ; Wheel (38h, dynamic value)
        Logical Minimum (-127),
        Logical Maximum (127),
        Input (Variable, Relative),
    End Collection,
    Collection (Physical),
        Report Count (1),
        Report Size (8),
        Usage Page (Consumer),      ; Consumer (0Ch)
        Usage (AC Pan),             ; AC pan (0238h, linear control)
        Logical Minimum (-127),
        Logical Maximum (127),
        Input (Variable, Relative),
    End Collection,
End Collection,

This is effectively a description of the structure in the reported I showed earlier, starting from the buttons and X/Y displacement, followed by the wheel and the “AC pan” (which I assume is the left/right wheel). All the sizes are given in bits, and the way the language works is a bit strange. The part that interests us is at the start of the first block. Refer to this tutorial for the nitty gritty details, but I’ll try to give a human-readable example.

Report ID is the constant we already know about, and the first byte of the message. Following that we can see it declaring five (Count = 5) bits (Size = 1) used for Buttons between 1 and 5. Ignore the local maximum/minimum in this case, as they are of course either on or off. The Input (Variable) instruction is effectively saying “These are the useful parts”. Following that it declares one (Count = 1) 3-bit (Size = 3) constant value. Since it’s constant, the HID driver will just ignore it. Unfortunately those three bits are actually the three bits needed for the top buttons.

The obvious answer is to change the descriptor so that it describe eight one-bit entries for eight buttons, and no constant bits (if you forget to remove the constant bits, the whole message gets misparsed and moving the mouse is taken as clicks, ask me how I know!). How do you do that? Well, you need a quirk driver in the Linux kernel to intercept the device, and rewrite the descriptor on the fly. This is not hard, and I know of plenty of other drivers doing so. As it happens Linux already has a hid-elecom driver, which was fixing a Bluetooth mouse that also had a wrong descriptor; I extended that to fix the descriptor. But how do you fix a descriptor exactly?

Some of the drivers check for the size of the descriptor, and for some anchor values (usually the ones they are going to change), others replace the descriptor entirely. I prefer the former, as they make it clear that they are trying to just fix something rather than discard whatever the manufacturer is doing. Particularly because in this case the fix is quite trivial, just three bytes need to be changed: change the Count and Maximum for the Buttons input to 8, and make the Count of the constant import zero. hidrd has a mode where it outputs the whole descriptor as a valid C array that you can just embed in the kernel source, with comments what each byte combination does. I used that during testing, before changing my code to do the patching instead. The actual diff, in code format, is:

@@ -4,15 +4,15 @@
 0x09, 0x01,         /*      Usage (Pointer),                */
 0xA1, 0x00,         /*      Collection (Physical),          */
 0x85, 0x01,         /*          Report ID (1),              */
-0x95, 0x05,         /*          Report Count (5),           */
+0x95, 0x08,         /*          Report Count (8),           */
 0x75, 0x01,         /*          Report Size (1),            */
 0x05, 0x09,         /*          Usage Page (Button),        */
 0x19, 0x01,         /*          Usage Minimum (01h),        */
-0x29, 0x05,         /*          Usage Maximum (05h),        */
+0x29, 0x08,         /*          Usage Maximum (08h),        */
 0x15, 0x00,         /*          Logical Minimum (0),        */
 0x25, 0x01,         /*          Logical Maximum (1),        */
 0x81, 0x02,         /*          Input (Variable),           */
-0x95, 0x01,         /*          Report Count (1),           */
+0x95, 0x00,         /*          Report Count (0),           */
 0x75, 0x03,         /*          Report Size (3),            */
 0x81, 0x01,         /*          Input (Constant),           */
 0x75, 0x10,         /*          Report Size (16),           */

And that’s enough to make all the buttons work just fine. Yay! So I sent the first patch to the linux-input mailing list… and then I had a doubt “Am I the first ever Linux user of this device?” As it happens, I’m not, and after sending the patch I searched and found that there was already a patch by Yuxuan Shui sent last year that does effectively the same thing, except with a new module altogether (rather than extending the one already there) and by removing the Constant input declaration altogether, which requires a memmove() of the rest of the input. It also contains the USB ID for the wired version of the DEFT, adding the same fix.

So I went and sent another (or three) revision of the patch, including the other ID. Of course I would argue that mine is cleaner by reusing the other module, but in general I’ll leave it to the maintainers to decide which one to use. One thing that I can say at least for mine is that I tried to make it very explicit what’s going on, in particular by adding as a comment the side-by-side diff of the Collection stanza that I change in the driver. Because I always find it bothersome when I have to look into one of those HID drivers and they seem to just come up with magical constants to save the day. Sigh!

April 21, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
Hardware Review: ELECOM DEFT Trackball (April 21, 2017, 17:04 UTC)

I know that by this point it feels like I’m collecting half-done reverse engineering projects, but sometimes you need some time off from one project to figure out how another is going to behave, so I have temporarily shelved my Accu-Chek Mobile and instead took a day to look at a different problem altogether.

I like trackballs, and with exception of gaming purposes, I consider them superior to mice: no cables that get tangled, no hands to move around the desk, much less space needed to keep clear, and so on. On laptops I prefer TrackPoint™ Style Pointers, which are rare to find, but on desktop I am a happy user of trackballs. Unfortunately my happiness has been having trouble as of late, because finding good trackballs is getting harder. My favourite device would still be Logitech’s Cordless Optical Trackman, but it was discontinued years ago, and it’s effectively impossible to find to buy. Amazon has second-hand listings for hundreds of dollars! I’m still kicking myself in the face for having dropped mine on the floor (literally) while I packed to move to Dublin, completely destroying it.

The new Logitech offerings appear to be all in the realm of thumb-operated “portable” trackballs, such as the M570, which I have and don’t particularly like. An alternative manufacturer that is easy to find both online and in store is Kensington, and I do indeed own an Orbit with the scroll ring, but it’s in my opinion too avant-garde and inconvenient. So I have been mostly unhappy.

But last year a colleague, also a trackball user, suggested me to look into the ELECOM DEFT Trackball (also available wired).

ELECOM, for those who may not be familiar with it, is a Japanese hardware company, that would sell everything from input devices to ultra flat network cables. If you have not been to Japan, it may be interesting to know that there is effectively a parallel world of hardware devices that you would not find in Europe or the USA, which makes a visit to Yodobashi Camera a must-see for every self-respecting geek.

I got the DEFT last year, and loved it. I’ve been using it at work all the time, because that’s where I mostly use a non-gaming input device anyway, but recently I started working from home a bit more often (it’s a long story) and got myself a proper setup for it, with a monitor, keyboard and, for a while, the M570 I noted above. I decided then to get myself two more of the DEFT, one to use with my work from home setup, and the other to use with my personal laptop while I work on reverse engineering.

Note here: I made a huge mistake. In both cases I ordered them from eBay directly from Japan, so I had to deal with the boring customs and VAT modules on my end. Which is not terrible, since the An Post depot is about ten minutes away from my apartment and my office, but it’s still less nice than just receiving the package directly. The second order, I ended up receiving two “Certified Frustration Free” packages, so I checked and indeed these devices are available on Amazon Japan. As I found out a few weeks ago for a completely different product, there is a feature called AmazonGlobal, which is not available for all products but would have been for these. With AmazonGlobal, the customs and VAT charges are taken care by Amazon, so there is no need for me to go out of my way and pay cash to An Post. And as it happens, if you don’t want to sign up for an account with Amazon Japan (which somehow is not federated to the others), you can just look for the same product on the USA version of Amazon, and AmazonGlobal applies just the same.

The trackball has a forefinger-operated ball (although ELECOM also makes a thumb-operated trackball), the usual left/middle/right buttons, a scroll wheel that “tilts” (badly) horizontally, and three function buttons at the top of the mouse (which I’ll go back to later). It also has two switches, one on the side, that has a red or blue area showing depending on how you pull it, and one on the bottom that is marked with the power symbol, H and L. Unfortunately, the manual leaflet that comes with the device is all in Japanese, which meant I had to get the help of Google Translate with my phone’s camera.

The switch on the side selects the DPI of the ball tracking (750 for blue, 1500 for red), while the one at the bottom appear to be a “power-assist” for the ball — it warns that the H version will use more battery.

As I said before, the trackball has three function buttons (marked Fn1, Fn2, Fn3) on the top. These are, for what I could tell, configurable through the Windows and Mac application, and they were indeed not seen by Linux at all, neither through xev nor through evtest. So I set myself up to reverse whichever protocol they used to configure this — I expected something similar to the Anker/Holtek gaming mouse I’m also working on, where the software programs the special event ID in the device directly.

The software can be downloaded on ELECOM’s website, although the whole page is in Japanese. On the other hand, the software itself is (badly) translated to English, so fewer yaks to shave there. Unfortunately when I tried using the app with the USB sniffer open… I could find nothing whatsoever. Turns out the app is actually handling all of that in software, rather than programming the hardware. So why did it not work on Linux? Well, I think that may be the topic for another post, since it turned out to require a kernel patch (which I sent, but can’t currently quite find it in the archives. I think that writing a blog post about it is going to be fairly useful, given that I had to assemble documentation that I found on at least a half dozen different sites.

Other things that may be relevant to know about the ELECOM is that somehow the 2.4GHz connection is sometimes a bit unstable. At the office, I cannot connect the receiver on the USB behind the monitor, because otherwise it skips beats. At home instead I have to put it there, because if I try to connect it directly to the Anker USB-C adapter I use with my Chromebook, the same problem happens. Ironically, the Microsoft receiver has the opposite problem: if I connect it behind the monitor at home, the keyboard sometimes get stuck repeating the same key over and over again. But again, that’s a topic for another time.

April 19, 2017
Hanno Böck a.k.a. hanno (homepage, bugs)

Nextcloud logoA while ago I wanted to report a bug in one of Nextcloud's apps. They use the Github issue tracker, after creating a new issue I was welcomed with a long list of things they wanted to know about my installation. I filled the info to the best of my knowledge, until I was asked for this:

The content of config/config.php:

Which made me stop and wonder: The config file probably contains sensitive information like passwords. I quickly checked, and yes it does. It depends on the configuration of your Nextcloud installation, but in many cases the configuration contains variables for the database password (dbpassword), the smtp mail server password (mail_smtppassword) or both. Combined with other information from the config file (e. g. it also contains the smtp hostname) this could be very valuable information for an attacker.

A few lines later the bug reporting template has a warning (“Without the database password, passwordsalt and secret”), though this is incomplete, as it doesn't mention the smtp password. It also provides an alternative way of getting the content of the config file via the command line.

However... you know, this is the Internet. People don't read the fineprint. If you ask them to paste the content of their config file they might just do it.

User's passwords publicly accessible

The issues on github are all public and the URLs are of a very simple form and numbered (e. g. https://github.com/nextcloud/calendar/issues/[number]), so downloading all issues from a project is trivial. Thus with a quick check I could confirm that some users indeed posted real looking passwords to the bug tracker.

Nextcoud is a fork of Owncloud, so I checked that as well. The bug reporting template contained exactly the same words, probably Nextcloud just copied it over when they forked. So I reported the issue to both Owncloud and Nextcloud via their HackerOne bug bounty programs. That was in January.

I proposed that both projects should go through their past bug reports and remove everything that looks like a password or another sensitive value. I also said that I think asking for the content of the configuration file is inherently dangerous and should be avoided. To allow users to share configuration options in a safe way I proposed to offer an option similar to the command line tool (which may not be available or usable for all users) in the web interface.

The reaction wasn't overwhelming. Apart from confirming that both projects acknowledged the problem nothing happened for quite a while. During FOSDEM I reached out to members of both projects and discussed the issue in person. Shortly after that I announced that I intended to disclose this issue three months after the initial report.

Disclosure deadline was nearing with passwords still public

The deadline was nearing and I didn't receive any report on any actions being taken by Owncloud or Nextcloud. I sent out this tweet which received quite some attention (and I'm sorry that some people got worried about a vulnerability in Owncloud/Nextcloud itself, I got a couple of questions):

will soon disclose a security issue in @ownCloud & @Nextclouders that will harm several users, both projects failed to act properly.

In all fairness to NextCloud, they had actually started scrubbing data from the existing bug reports, they just hadn't informed me. After the tweet Nextcloud gave me an update and Owncloud asked for a one week extension of the disclosure deadline which I agreed to.

The outcome by now isn't ideal. Both projects have scrubbed all obvious passwords from existing bug reports, although I still find values where it's not entirely clear whether they are replacement values or just very bad passwords (e. g. things like “123456”, but you might argue that people using such passwords have other problems).

Nextcloud has changed the wording of the bug reporting template. The new template still asks for the config file, but it mentions the safer command line option first and has the warning closer to the mentioning of the config. This is still far from ideal and I wouldn't be surprised if people continue pasting their passwords. However Nextcloud developers have indicated in the HackerOne discussion that they might pick up my idea of offering a GUI version to export a scrubbed config file. Owncloud has changed nothing yet.

If you have reported bugs to Owncloud or Nextcloud in the past and are unsure whether you may have pasted your password it's probably best to change it. Even if it's been removed now it may still be available within search engine caches or it might have already been recorded by an attacker.

April 15, 2017
Gentoo Haskell Herd a.k.a. haskell (homepage, bugs)
GHC as a cross-compiler update (April 15, 2017, 11:05 UTC)

TL;DR:

Gentoo’s dev-lang/ghc-8.2.1_rc1 supports both cross-building and cross-compiling modes! It’s useful for cross-compiling haskell software and initial porting of GHC itself on a new gentoo target.

Building a GHC crossompiler on Gentoo

Getting ${CTARGET}-ghc (crosscompiler) on Gentoo:

# # convenience variables:
CTARGET=powerpc64-unknown-linux-gnu
#
# # Installing a target toolchain: gcc, glibc, binutils
crossdev ${CTARGET}
# # Installing ghc dependencies:
emerge-${CTARGET} -1 libffi ncurses gmp
#
# # adding 'ghc' symlink to cross-overlay:
ln -s path/to/haskell/overlay/dev-lang/ghc part/to/cross/overlay/cross-${CTARGET}/ghc
#
# # Building ghc crosscompiler:
emerge -1 cross-${CTARGET}/ghc
#
powerpc64-unknown-linux-gnu-ghc --info | grep Target
# ,("Target platform","powerpc64-unknown-linux")

Cross-building GHC on Gentoo

Cross-building ghc on ${CTARGET}:

# # convenience variables:
CTARGET=powerpc64-unknown-linux-gnu
#
# # Installing a target toolchain: gcc, glibc, binutils
crossdev ${CTARGET}
# # Installing ghc dependencies:
emerge-${CTARGET} -1 libffi ncurses gmp
#
# # Cross-building ghc crosscompiler:
emerge-${CTARGET} --buildpkg -1 dev-lang/ghc
#
# # Now built packages can be used on a target to install
# # built ghc as: emerge --usepkg -1 dev-lang/ghc

Building a GHC crossompiler (generic)

That’s how you get a powerpc64 crosscompiler in a fresh git checkout:

$ ./configure --target=powerpc64-unknown-linux-gnu
$ cat mk/build.mk
HADDOCK_DOCS=NO
BUILD_SPHINX_HTML=NO
BUILD_SPHINX_PDF=NO
# to speed things up
BUILD_PROF_LIBS=NO
$ make -j$(nproc)
$ inplace/bin/ghc-stage1 --info | grep Target
,("Target platform","powerpc64-unknown-linux")

Simple!

Below are details that have only historical (or backporting) value.

How did we get there?

Cross-compiling support in GHC is not a new thing. GHC wiki has a detailed section on how to build a crosscompiler. That works quite good. You can even target ghc at m68k: porting example.

What did not work so well is the attempt to install the result! In some places GHC build system tried to run ghc-pkg built for ${CBUILD}, in some places for ${CHOST}.

I never really tried to install a crosscompiler before. I think mostly because I was usually happy to make cross-compiler build at all: making GHC build for a rare target usually required a patch or two.

But one day I’ve decided to give full install a run. Original motivation was a bit unusual: I wanted to free space on my hard drive.

The build tree for GHC usually takes about 6-8GB. I had about 15 GHC source trees lying around. All in all it took about 10% of all space on my hard drive. Fixing make install would allow me to install only final result and get rid of all intermediate files.

I’ve decided to test make install code on Gentoo‘s dev-lang/ghc package as a proper package.

As a result a bunch of minor cleanups happened:

What works?

It allowed me to test various targets. Namely:

Target Bits Endianness Codegen
cross-aarch64-unknown-linux-gnu/ghc 64 LE LLVM
cross-alpha-unknown-linux-gnu/ghc 64 LE UNREG
cross-armv7a-unknown-linux-gnueabi/ghc 32 LE LLVM
cross-hppa-unknown-linux-gnu/ghc 32 BE UNREG
cross-m68k-unknown-linux-gnu/ghc 32 BE UNREG
cross-mips64-unknown-linux-gnu/ghc 32/64 BE UNREG
cross-powerpc64-unknown-linux-gnu/ghc 64 BE NCG
cross-powerpc64le-unknown-linux-gnu/ghc 64 LE NCG
cross-s390x-unknown-linux-gnu/ghc 64 BE UNREG
cross-sparc-unknown-linux-gnu/ghc 32 BE UNREG
cross-sparc64-unknown-linux-gnu/ghc 64 BE UNREG

I am running all of this on x86_64 (64-bit LE platform)

Quite a list! With help of qemu we can even test whether cross-compiler produces something that works:

$ cat hi.hs 
main = print "hello!"
$ powerpc64le-unknown-linux-gnu-ghc hi.hs -o hi.ppc64le
[1 of 1] Compiling Main             ( hi.hs, hi.o )
Linking hi.ppc64le ...
$ file hi.ppc64le 
hi.ppc64le: ELF 64-bit LSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), dynamically linked, interpreter /lib64/ld64.so.2, for GNU/Linux 3.2.0, not stripped
$ qemu-ppc64le -L /usr/powerpc64le-unknown-linux-gnu/ ./hi.ppc64le 
"hello!"

Many qemu targets are slightly buggy and usually are very easy to fix!

A few recent examples:

  • epoll syscall is not wired properly on qemu-alpha: patch
  • CPU initialization code on qemu-s390x
  • thread creation fails on qemu-sparc32plus due to simple mmap() emulation bug
  • tcg on qemu-sparc64 crashes at runtime in static_code_gen_buffer()

Tweaking qemu is fun 🙂


April 10, 2017
Alexys Jacob a.k.a. ultrabug (homepage, bugs)
py3status v3.5 (April 10, 2017, 10:19 UTC)

Howdy folks,

I’m obviously slacking a bit on my blog and I’m ashamed to say that it’s not the only place where I do. py3status is another of them and it wouldn’t be the project it is today without @tobes.

In fact, this new 3.5 release has witnessed his takeover on the top contributions on the project, so I want to extend a warm thank you and lots of congratulations on this my friend 🙂

Also, an amazing new contributor from the USA has come around in the nickname of @lasers. He has been doing a tremendous job on module normalization, code review and feedbacks. His high energy is amazing and more than welcome.

This release is mainly his, so thank you @lasers !

What’s new ?

Well the changelog has never been so large that I even don’t know where to start. I guess the most noticeable change is the gorgeous and brand new documentation of py3status on readthedocs !

Apart from the enhanced guides and sections, what’s amazing behind this new documentation is the level of automation efforts that @lasers and @tobes put into it. They even generate modules’ screenshots programmatically ! I would never have thought of it possible 😀

The other main efforts on this release is about modules normalization where @lasers put so much energy in taking advantage of the formatter features and bringing all the modules to a new level of standardization. This long work brought to light some lack of features or bugs which got corrected along the way.

Last but not least, the way py3status notifies you when modules fail to load/execute got changed. Now modules which fail to load or execute will not pop up a notification (i3 nagbar or dbus) but display directly in the bar where they belong. Users can left click to show the error and right click to discard them from their bar !

New modules

Once again, new and recurring contributors helped the project get better and offer a cool set of modules, thank you contributors !

  • air_quality module, to display the air quality of your place, by @beetleman and @lasers
  • getjson module to display fields from a json url, by @vicyap
  • keyboard_locks module to display keyboard locks states, by @lasers
  • systemd module to check the status of a systemd unit, by @adrianlzt
  • tor_rate module to display the incoming and outgoing data rates of a Tor daemon instance, by @fmorgner
  • xscreensaver module, by @lasers and @neutronst4r

Special mention to @maximbaz for his continuous efforts and help. And also a special community mention to @valdur55 for his responsiveness and help for other users on IRC !

What’s next ?

The 3.6 version will focus on the following ideas, some sane and some crazy 🙂

  • we will continue to work on the ability to add/remove/move modules in the bar at runtime
  • i3blocks and i3pystatus support, to embed their configurations and modules inside py3status
  • formatter optimizations
  • finish modules normalization
  • write more documentation and clean up the old ones

Stay tuned

April 09, 2017
Sven Vermeulen a.k.a. swift (homepage, bugs)
Switched to Lineage OS (April 09, 2017, 14:40 UTC)

I have been a long time user of Cyanogenmod, which discontinued its services end of 2016. Due to lack of (continuous) time, I was not able to switch over toward a different ROM. Also, I wasn't sure if LineageOS would remain the best choice for me or not. I wanted to review other ROMs for my Samsung Galaxy SIII (the i9300 model) phone.

Today, I made my choice and installed LineageOS.

April 07, 2017
Hanno Böck a.k.a. hanno (homepage, bugs)

I want to tell a little story here. I am usually relatively savvy in IT security issues. Yet I was made aware of a quite severe mistake today that caused a security issue in my web page. I want to learn from mistakes, but maybe also others can learn something as well.

I have a private web page. Its primary purpose is to provide a list of links to articles I wrote elsewhere. It's probably not a high value target, but well, being an IT security person I wanted to get security right.

Of course the page uses TLS-encryption via HTTPS. It also uses HTTP Strict Transport Security (HSTS), TLS 1.2 with an AEAD and forward secrecy, has a CAA record and even HPKP (although I tend to tell people that they shouldn't use HPKP, because it's too easy to get wrong). Obviously it has an A+ rating on SSL Labs.

Surely I thought about Cross Site Scripting (XSS). While an XSS on the page wouldn't be very interesting - it doesn't have any kind of login or backend and doesn't use cookies - and also quite unlikely – no user supplied input – I've done everything to prevent XSS. I set a strict Content Security Policy header and other security headers. I have an A-rating on securityheaders.io (no A+, because after several HPKP missteps I decided to use a short timeout).

I also thought about SQL injection. While an SQL injection would be quite unlikely – you remember, no user supplied input – I'm using prepared statements, so SQL injections should be practically impossible.

All in all I felt that I have a pretty secure web page. So what could possibly go wrong?

Well, this morning someone send me this screenshot:
PDO stack trace

And before you ask: Yes, this was the real database password. (I changed it now.)

So what happened? The mysql server was down for a moment. It had crashed for reasons unrelated to this web page. I had already taken care of that and hadn't noted the password leak. The crashed mysql server subsequently let to an error message by PDO (PDO stands for PHP Database Object and is the modern way of doing database operations in PHP).

The PDO error message contains a stack trace of the function call including function parameters. And this led to the password leak: The password is passed to the PDO constructor as a parameter.

There are a few things to note here. First of all for this to happen the PHP option display_errors needs to be enabled. It is recommended to disable this option in production systems, however it is enabled by default. (Interesting enough the PHP documentation about display_errors doesn't even tell you what the default is.)

display_errors wasn't enabled by accident. It was actually disabled in the past. I made a conscious decision to enable it. Back when we had display_errors disabled on the server I once tested a new PHP version where our custom config wasn't enabled yet. I noticed several bugs in PHP pages. So my rationale was that disabling display_errors hides bugs, thus I'd better enable it. In hindsight it was a bad idea. But well... hindsight is 20/20.

The second thing to note is that this only happens because PDO throws an exception that is unhandled. To be fair, the PDO documentation mentions this risk. Other kinds of PHP bugs don't show stack traces. If I had used mysqli – the second supported API to access MySQL databases in PHP – the error message would've looked like this:

PHP Warning: mysqli::__construct(): (HY000/1045): Access denied for user 'test'@'localhost' (using password: YES) in /home/[...]/mysqli.php on line 3

While this still leaks the username, it's much less dangerous. This is a subtlety that is far from obvious. PHP functions have different modes of error reporting. Object oriented functions – like PDO – throw exceptions. Unhandled exceptions will lead to stack traces. Other functions will just report error messages without stack traces.

If you wonder about the impact: It's probably minor. People could've seen the password, but I haven't noticed any changes in the database. I obviously changed it immediately after being notified. I'm pretty certain that there is no way that a database compromise could be used to execute code within the web page code. It's far too simple for that.

Of course there are a number of ways this could've been prevented, and I've implemented several of them. I'm now properly handling exceptions from PDO. I also set a general exception handler that will inform me (and not the web page visitor) if any other unhandled exceptions occur. And finally I've changed the server's default to display_errors being disabled.

While I don't want to shift too much blame here, I think PHP is making this far too easy to happen. There exists a bug report about the leaking of passwords in stack traces from 2014, but nothing happened. I think there are a variety of unfortunate decisions made by PHP. If display_errors is dangerous and discouraged for production systems then it shouldn't be enabled by default.

PHP could avoid sending stack traces by default and make this a separate option from display_errors. It could also introduce a way to make exceptions fatal for functions so that calling those functions is prevented outside of a try/catch block that handles them. (However that obviously would introduce compatibility problems with existing applications, as Craig Young pointed out to me.)

So finally maybe a couple of takeaways:

  • display_errors is far more dangerous than I was aware of.
  • Unhandled exceptions introduce unexpected risks that I wasn't aware of.
  • In the past I was recommending that people should use PDO with prepared statements if they use MySQL with PHP. I wonder if I should reconsider that, given the circumstances mysqli seems safer (it also supports prepared statements).
  • I'm not sure if there's a general takeaway, but at least for me it was quite surprising that I could have such a severe security failure in a project and code base where I thought I had everything covered.

March 30, 2017
Bernard Cafarelli a.k.a. voyageur (homepage, bugs)

After a short detour on how Skydive can help debugging Service Function Chaining, in this post I will give details on the new RPM files now available in RDO to install networking-sfc. We will go through a complete TripleO demo deployment, and configure the different nodes to enable networking-sfc components.
Note that most steps will be quite generic, so can be used to install networking-sfc on other OpenStack setups!

Running tripleo-quickstart

To quickly get a TripleO setup up and running, I used tripleo-quickstart with most default options. So prepare a big enough machine (I used a 32GB one), that you can SSH in as root with password, get this helpful script and run it on master “release”:
$ ./quickstart.sh --install-deps
$ ./quickstart.sh -R master -t all ${VIRTHOST}

After some coffee cups, you should get an undercloud node, an overcloud with one compute node and one controller node, all running inside your test system.

Accessing the nodes

A quick tip here: if you want to have an easy access to all nodes and web interfaces, I recommend sshuttle, the “poor man’s VPN”. Once installed (it is available in Fedora and Gentoo at least), run this command (as root):
# sshuttle -e "ssh -F /home/YOUR_USER/.quickstart/ssh.config.ansible" -r undercloud -v 10.0.0.0/24 192.168.24.0/24

And now, you can directly access both undercloud IP addresses (192.168.x.x) and overcloud ones (10.x)! For example, you can take a look at the tripleo-ui web interface, which should be at http://192.168.24.1:3000/ (username:admin, password: find with “sudo hiera admin_password” on the undercloud)

As for SSH access, tripleo-quickstart created a configuration file to simplify the commands, so you can use these:
# undercloud login (where we can run CLI commands)
$ ssh -F ~/.quickstart/ssh.config.ansible undercloud
# overcloud compute node
$ ssh -F ~/.quickstart/ssh.config.ansible overcloud-novacompute-0
# overcloud controller node
$ ssh -F ~/.quickstart/ssh.config.ansible overcloud-controller-0

The undercloud has some interesting scripts and credential files (stackrc for the undercloud itself, overcloudrc for… the overcloud indeed). But let’s go back to SFC before.

Enable networking-sfc

First, install the networking-sfc RPM package on each node (we will run CLI and demo scripts from the undercloud, so do it on all three nodes):
# yum install -y python-networking-sfc

That was easy, right? OK, you still have to do the configuration steps manually (for now).

On the controller node(s), modify the neutron-server configuration file /etc/neutron/neutron.ini:

# Look for service_plugins line, add the SFC ones at the end
# The service plugins Neutron will use (list value)
service_plugins=router,qos,trunk,networking_sfc.services.flowclassifier.plugin.FlowClassifierPlugin,networking_sfc.services.sfc.plugin.SfcPlugin
[...]
# At the end, set the backends to use (in this case, the default OVS one)
[sfc]
drivers = ovs

[flowclassifier]
drivers = ovs

The controller is now configured. Now, create the SFC tables in the neutron database, and restart the neutron-server service:
$ sudo neutron-db-manage --subproject networking-sfc upgrade head
$ sudo systemctl restart neutron-server

Now for the compute node(s)! We will enable the SFC extension in the Open vSwitch agent, note that its configuration file can be different depending on your setup (you can confirm yours checking the output of “ps aux|grep agent”). In this demo, edit /etc/neutron/plugins/ml2/openvswitch_agent.ini

# This time, look for the extensions line, add sfc to it
# Extensions list to use (list value)
extensions =qos,sfc

And restart the agent:
$ sudo systemctl restart neutron-openvswitch-agent

Demo time

Congratulations, you successfully deployed a complete OpenStack setup and enabled SFC on it! To confirm it, connect to the undercloud and run some networking-sfc commands against the overcloud, they should run without errors:
$ source overcloudrc
(OVERCLOUD) $ neutron port-pair-list # Or "port-pair-create --help"

I updated my demo script for this tripleo-quickstart setup: in addition to the SFC-specific parts, it will also create basic networks, images, … and floating IP addresses for the demo VMs (we can not connect directly to the private addresses as we are not on the same node this time). Now, still on the undercloud, download an run the script:
$ git clone https://github.com/voyageur/openstack-scripts.git
$ ./openstack-scripts/simple_sfc_vms.sh

If all went well, you can read back a previous post to see how to test this setup, or go on your own and experiemnt.

As a short example to end this post, this will confirm that an HTTP request from the source VM does indeed visit a few systems on the way:
$ source overcloudrc
# Get the private IP for the destination VM
(OVERCLOUD) $ openstack server show -f value -c addresses dest_vm
private=172.24.4.9, 192.168.24.104
# Get the floating IP for the source VM
(OVERCLOUD) $ openstack server show -f value -c addresses source_vm
private=172.24.4.19, 192.168.24.107
(OVERCLOUD) $ ssh cirros@192.168.24.107

$ traceroute -n 172.24.4.9
traceroute to 172.24.4.9 (172.24.4.9), 30 hops max, 46 byte packets
1 172.24.4.13 23.700 ms 0.476 ms 0.320 ms
2 172.24.4.15 4.239 ms 0.467 ms 0.374 ms
3 172.24.4.9 0.941 ms 0.599 ms 0.429 ms

Yes, these networking-sfc RPM packages do seem to work 🙂

March 29, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
GnuCash: Stock and Currencies (March 29, 2017, 00:03 UTC)

This is probably a post that can be categorized as a first-world problem, but it’s something that I found difficult to figure out by myself, and I thought it may be interesting to other free software users who happen to work for a company that provides stock grants as a form of compensation. As it happens, I’m one of them.

Many years ago I set up my accounting through GnuCash, because I needed something to keep track of the expenses of my company, back when I had one. Being stubborn and pedantic, now four years after closing said company, I still keep running it and I have a nearly complete accounting of my expenses, for sure from 2009 (time from which I started recording all movements on the credit cards) and some before — I actually manually imported all operations on my bank account from its opening in 2005!

One thing that was not very clear to me how to handle, as setting up proper accounts to track the compensation in form of stock. The as usual unnamed company I work for provides me with a part of compensation in form of stock grants, as long as I work for them. The tax implications of these grants are a bit complicated, but boil down to needing to know the “fair market value” (FMV) of the stock at vesting, and the exchange rate for that month on the Irish Revenue website, since the stock is valued in dollars, but my taxes are in Euro (and do note that it does not matter when you transfer that money, as far as I can tell, which is both a blessing and a curse of course).

For this description to work, your GnuCash file needs to be set to Use Trading Accounts, as that makes it much nicer to have multiple currencies and securities in the same transaction. You also need to create a new security (symbol), a new income account and a new stock account. For the first you select Tools → Security Editor → Add, the two others can be created by right clicking on the Income and Stock accounts respectively, and choosing New Account…:

Creating a new Security for Free Software Foundation, with symbol GNU and type BAZAAR.

Creating a new Stock Grants income with USD as currency.

Creating a new FSF stock account with GNU as the security.

Once you open the newly-created stock account, it will show you a number of column as usual for GnuCash, but in particular it’ll have the stock-specific Price, Buy, and Sell column, which are used for trading. What was definitely not originally clear to me before was that the price is always expressed in the default currency of the GnuCash file, which as far as I know is not editable.

You can of course manually calculate the value at time of vesting by using the FMV and the exchange rate, but it becomes quite more complicated in my opinion. So instead, whenever one of my grants vests, I’m now going to the income account to record it. This account is denominated in dollars, which match the symbol’s currency, and we’ll use it to add new stock to the stock (or asset) account.

Say for example as of today I received a grant of two stock units at FMV of $1337 (note I expanded the splits of the line, that is on purpose because it makes it easier to edit):

Adding an Income entry of $1337*2 in the Stock Grants account.

You then add a second split that points to the stock account created previously and insert the number of stock units (2) in that Charge. Again this only works correctly if you’re using trading accounts! Once you do that, the Transfer Funds dialog will pop up and it will have already the right “Exchange Rate” (which is actually the FMV at vesting time).

Transfer Funds dialog for an income of 2 FSF stock units.

Up to now this is all good, now you have some stock, and the Buy field is actually showing the right price in dollars, but the account’s value is not going to be aggregated correctly in the Accounts page. This is because up until now we have made no effort of dealing with the exchange rate between USD and EUR.

The easiest way to fix this is going to Tools → Price Editor, select the symbol and add a new price (I use Net Asset Value for type), and in the price divide the value in dollar for the right exchange rate.

Price Editor dialog setting the price of GNU to 1337/1.0555 EUR

Et voilà! Now you should have most of the data you need not only to keep an eye on the stock grants, but also to do tax reporting as you have recorded the FMV already converted to Euro, which is what you need there. Unfortunately, as far as I can tell, there is no easy way to export the prices in a nice table that you can just use for reporting. And I’m horrible with Scheme so I have not considered writing my own reporting module yet.

There is also another caveat: I have tried to track the grants already in two different ways in the past, and they did not work out very well. I’m seriously considering making a copy of my GnuCash file, delete the accounts altogether and recreate them following this simplified procedure. But that will probably be a bridge for another time.

March 27, 2017
Sven Vermeulen a.k.a. swift (homepage, bugs)
cvechecker 3.8 released (March 27, 2017, 17:00 UTC)

A new release is now available for the cvechecker application. This is a stupid yet important bugfix release: the 3.7 release saw all newly released CVEs as being already known, so it did not take them up to the database. As a result, systems would never check for the new CVEs.

March 25, 2017
Andreas K. Hüttel a.k.a. dilfridge (homepage, bugs)

We want to stabilize Perl 5.24 on Gentoo pretty soon (meaning in a few weeks), and do actually not expect any big surprises there. If you are running a stable installation, are willing to do some testing, and are familiar with our Gentoo bugzilla and with filing bug reports, then you might just be the right volunteer to give it a try in advance!

Here's what to do:

Step 1: Update app-admin/perl-cleaner to current ~arch.
I'm deliberately not supplying any version number here, since I might do another release, but you should at least have perl-cleaner-2.25.

Step 2: Make sure your system is uptodate (emerge -uDNav world) and do a depclean step (emerge --depclean --ask).

Step 3: Download the current stabilization list from bug 604602 and place it into your /etc/portage/package.keywords or /etc/portage/package.accept_keywords.

Step 4: Update your world (emerge -uDNav world), which triggers the perl update and the module rebuild.

Step 5: Run "perl-cleaner --all"  (you might also want to try "perl-cleaner --all --delete-leftovers").

... and make sure you file bugs for any problems you encounter, during the update and afterwards! Feedback is also appreciated if all goes fine; then you best leave a comment here on the blog post.

March 21, 2017
Jason A. Donenfeld a.k.a. zx2c4 (homepage, bugs)
WireGuard in Google Summer of Code (March 21, 2017, 18:52 UTC)

WireGuard is participating in Google Summer of Code 2017. If you're a student who would like to be funded this summer for writing interesting kernel code, studying cryptography, building networks, or working on a wide variety of interesting problems, then this might be appealing. The program opened to students on March 20th. If you're applying for WireGuard, choose "Linux Foundation" and state in your proposal that you'd like to work on WireGuard with "Jason Donenfeld" as your mentor.

March 17, 2017
Michał Górny a.k.a. mgorny (homepage, bugs)

You should know already that you are not supposed to rely on Portage internals in ebuilds — all variables, functions and helpers that are not defined by the PMS. You probably know that you are not supposed to touch various configuration files, vdb and other Portage files as well. What most people don’t seem to understand, you are not supposed to make any assumptions about the ebuild repository either. In this post, I will expand on this and try to explain why.

What PMS specifies, what you can rely on

I think the first confusing point is that PMS actually defines the repository format pretty thoroughly. However, it does not specify that you can rely on that format being visible from within ebuild environment. It just defines a few interfaces that you can reliably use, some of them in fact quite consistent with the repository layout.

You should really look as the PMS-defined repository format as an input specification. This is the format that the developers are supposed to use when writing ebuilds, and that all basic tools are supposed to support. However, it does not prevent the package managers from defining and using other package formats, as long as they provide the environment compliant with the PMS.

In fact, this is how binary packages are implemented in Gentoo. The PMS does not define any specific format for them. It only defines a few basic rules and facilities, and both Portage and Paludis implement their own binary package formats. The package managers expose APIs required by the PMS, and can use them to run the necessary pkg_* phases.

However, the problem is not limited to two currently used binary package formats. This is a generic goal of being able to define any new package format in the future, and make it work out of the box with existing ebuilds. Imagine just a few possibilities: more compact repository formats (i.e. not requiring hundreds of unpacked files), fetching only needed ebuild files…

Sadly, none of this can even start being implemented if developers continuosly insist to rely on specific repository layout.

The *DIR variables

Let’s get into the details and iterate over the few relevant variables here.

First of all, FILESDIR. This is the directory where ebuild support files are provided throughout src_* phases. However, there is no guarantee that this will be exactly the directory you created in the ebuild repository. The package manager just needs to provide the files in some directory, and this directory may not actually exist before the first src_* phase. This implies that the support files may not even exist at all when installing from a binary package, and may be created (copied, unpacked) later when doing a source build.

The next variable listed by the PMS is DISTDIR. While this variable is somewhat similar to the previous one, some developers are actually eager to make the opposite assumption. Once again, the package manager may provide the path to any directory that contains the downloaded files. This may be a ‘shadow’ directory containing only files for this package, or it can be any system downloads directory containing lots of other files. Once again, you can’t assume that DISTDIR will exist before src_*, and that it will exist at all (and contain necessary files) when the build is performed using a binary package.

The two remaining variables I would like to discuss are PORTDIR and ECLASSDIR. Those two are a cause of real mayhem: they are completely unsuited for a multi-repository layout modern package managers use and they enforce a particular source repository layout (they are not available outside src_* phases). They pretty much block any effort on improvement, and sadly their removal is continuously blocked by a few short-sighted developers. Nevertheless, work on removing them is in progress.

Environment saving

While we’re discussing those matters, a short note on environment saving is worth being written. By environment saving we usually mean the magic that causes the variables set in one phase function to be carried to a phase function following it, possibly over a disjoint sequence of actions (i.e. install followed by uninstall).

A common misunderstanding is to assume the Portage model of environment saving — i.e. basically dumping a whole ebuild environment including functions into a file. However, this is not sanctioned by the PMS. The rules require the package manager to save only variables, and only those that are not defined in global scope. If phase functions define functions, there is no guarantee that those functions will be preserved or restored. If phases redefine global variables, there is no guarantee that the redefinition will be preserved.

In fact, the specific wording used in the PMS allows a completely different implementation to be used. The package manager may just snapshot defined functions after processing the global scope, or even not snapshot them at all and instead re-read the ebuild (and re-inherit eclasses) every time the execution continues. In this case, any functions defined during phase function are lost.

Is there a future in this?

I hope this clears up all the misunderstandings on how to write ebuilds so that they will work reliably, both for source and binary builds. If those rules are followed, our users can finally start expecting some fun features to come. However, before that happens we need to fix the few existing violations — and for that to happen, we need a few developers to stop thinking only of their own convenience.

Marek Szuba a.k.a. marecki (homepage, bugs)
Gentoo Linux in a Docker container (March 17, 2017, 14:31 UTC)

I have been using Docker for ebuild development for quite a while and absolutely love it, mostly because how easy it is to manipulate filesystem state with it. Work on several separate ebuilds in parallel? Just spin up several containers. Clean up once I’m done? Happens automatically when I close the container. Come back to something later? One docker commit invocation and I’m done. I could of course do something similar with virtual machines (and indeed I have to for cross-platform work) – but for native amd64 is is extremely convenient.

There is, however, one catch. By default processes running in a Docker container are fairly restricted privilege-wise and the Gentoo sandbox uses ptrace(). Result? By default, certain ebuilds (sys-libs/glibc and dev-libs/gobject-introspection , to name just two) will fail to emerge. One can of course set FEATURES=”-sandbox -usersandbox” for such ebuilds but it is an absolute no-no for both new ebuilds and any stabilisation work.

In the past working around this issue required messing with Docker security policies, which at least I found rather awkward. Fortunately since version 1.13.0 there has been a considerably easier way – simply pass

--cap-add=SYS_PTRACE

to docker-run. Done! Sandbox can now use ptrace() to its heart’s content.

Big Fat Warning: The reason why by default Docker restricts CAP_SYS_PTRACE is that a malicious program can use ptrace() to break out of the container it runs in. Do not grant this capability to containers unless you know what you are doing. Seriously.

Unfortunately the above is not the end of the story because at least as of version 1.13.0, Docker does not allow to enhance the capabilities of a docker-build job. Why is this a problem? For my own work I use a custom image which extends somewhat the official gentoo/stage3-amd64-hardened . One of the things my Dockerfile does is rsync the Portage tree and update @world so that my image contains a fully up-to-date stage3 even when the official base image does not. You can guess what happens when Docker tries to emerge an ebuild requiring the sandbox to use ptrace()… and remember, one of the packages containing such ebuilds is sys-libs/glibc . To my current knowledge the only way around this is to spin up a ptrace-enabled container using the latest good intermediate image left behind by docker-build and execute the remaining build steps manually. Not fun… Hope they will fix this some day.

 

Possibly the simplest way of changing the passhprase protecting a SSH key imported into gpg-agent is to use the Assuan passwd command:

echo passwd foo | gpg-connect-agent

where foo is the keygrip of your SSH key, which one can obtain from the file $GNUPGHOME/sshcontrol [1]. So far so good – but how does one know which of the keys listed in that file is the right one, especially if your sshcontrol list is fairly long? Here are the options I am aware of at this point:

Use the key comment. If you remember the contents of the comment field of the SSH key in question you can simply grep for it in all the files stored in $GNUPGHOME/private-keys-v1.d/ . Take the name of the file that matches, strip .key from the end and you’re set! Note that these are binary files so make sure your grep variant does not skip over them.

Use the MD5 fingerprint and the key comment. If for some reason you would rather not do the above you can take advantage of the fact that for SSH keys imported into gpg-agent the normal way, each keygrip line in sshcontrol is preceded by comment lines containing, among other things, the MD5 fingerprint of the imported key. Just tell ssh-add to print MD5 fingerprints for keys known to the agent instead of the default SHA256 ones:

ssh-add -E md5 -l

locate the fingerprint corresponding to the relevant key comment, then find the corresponding keygrip in sshcontrol .

Use the MD5 fingerprint and the public key. A slightly more complex variant of the above can be used if your SSH key pair in question has no comment but you still have the public key lying around. Start by running

ssh-add -L

and note the number of the line in which the public key in question shows up. The output of ssh-add -L and ssh-add -l is in the same order so you should have no trouble locating the corresponding MD5 fingerprint.

Bottom line: use meaningful comments for your SSH keys. It can really simplify key management in the long run.

[1] https://lists.gnupg.org/pipermail/gnupg-users/2007-July/031482.html

March 15, 2017
Hanno Böck a.k.a. hanno (homepage, bugs)
Zero Days and Cargo Cult Science (March 15, 2017, 12:25 UTC)

I've complained in the past about the lack of rigorous science in large parts of IT security. However there's no lack of reports and publications that claim to provide data about this space.

Recently RAND Corporation, a US-based think tank, published a report about zero day vulnerabilities. Many people praised it, an article on Motherboard quotes people saying that we finally have “cold hard data” and quoting people from the zero day business who came to the conclusion that this report clearly confirms what they already believed.

I read the report. I wasn't very impressed. The data is so weak that I think the conclusions are almost entirely meaningless.

The story that is spun around this report needs some context: There's a market for secret security vulnerabilities, often called zero days or 0days. These are vulnerabilities in IT products that some actors (government entities, criminals or just hackers who privately collect them) don't share with the vendor of that product or the public, so the vendor doesn't know about them and can't provide a fix.

One potential problem of this are bug collisions. Actor A may find or buy a security bug and choose to not disclose it and use it for its own purposes. If actor B finds the same bug then he might use it to attack actor A or attack someone else. If A had disclosed that bug to the vendor of the software it could've been fixed and B couldn't have used it, at least not against people who regularly update their software. Depending on who A and B are (more or less democratic nation states, nation states in conflict with each other or simply criminals) one can argue how problematic that is.

One question that arises here is how common that is. If you found a bug – how likely is it that someone else will find the same bug? The argument goes that if this rate is low then stockpiling vulnerabilities is less problematic. This is how the RAND report is framed. It tries to answer that question and comes to the conclusion that bug collisions are relatively rare. Thus many people now use it to justify that zero day stockpiling isn't so bad.

The data is hardly trustworthy

The basis of the whole report is an analysis of 207 bugs by an entity that shared this data with the authors of the report. It is incredibly vague about that source. They name their source with the hypothetical name BUSBY.

We can learn that it's a company in the zero day business and indirectly we can learn how many people work there on exploit development. Furthermore we learn: “Some BUSBY researchers have worked for nation-states (so
their skill level and methodology rival that of nation-state teams), and many of BUSBY’s products are used by nation-states.” That's about it. To summarize: We don't know where the data came from.

The authors of the study believe that this is a representative data set. But it is not really explained why they believe so. There are numerous problems with this data:

  • We don't know in which way this data has been filtered. The report states that 20-30 bugs “were removed due to operational sensitivity”. How was that done? Based on what criteria? They won't tell you. Were the 207 bugs plus the 20-30 bugs all the bugs the company had found or was this already pre-filtered? They won't tell you.
  • It is plausible to assume that a certain company focuses on specific bugs, has certain skills, tools or methods that all can affect the selection of bugs and create biases.
  • Oh by the way, did you expect to see the data? Like a table of all the bugs analyzed with the at least the little pieces of information BUSBY was willing to share? Because you were promised to see cold hard data? Of course not. That would mean others could reanalyze the data, and that would be unfortunate. The only thing you get are charts and tables summarizing the data.
  • We don't know the conditions under which this data was shared. Did BUSBY have any influence on the report? Were they allowed to read it and comment on it before publication? Did they have veto rights to the publication? The report doesn't tell us.

Naturally BUSBY has an interest in a certain outcome and interpretation of that data. This creates a huge conflict of interest. It is entirely possible that they only chose to share that data because they expected a certain outcome. And obviously the reverse is also true: Other companies may have decided not to share such data to avoid a certain outcome. It creates an ideal setup for publication bias, where only the data supporting a certain outcome is shared.

It is inexcusable that the problem of conflict of interest isn't even mentioned or discussed anywhere in the whole report.

A main outcome is based on a very dubious assumption

The report emphasizes two main findings. One is that the lifetime of a vulnerability is roughly seven years. With the caveat that the data is likely biased, this claim can be derived from the data available. It can reasonably be claimed that this lifetime estimate is true for the 207 analyzed bugs.

The second claim is about the bug collision rate and is much more problematic:
“For a given stockpile of zero-day vulnerabilities, after a year, approximately 5.7 percent have been discovered by an outside entity.”

Now think about this for a moment. It is absolutely impossible to know that based on the data available. This would only be possible if they had access to all the zero days discovered by all actors in that space in a certain time frame. It might be possible to extrapolate this if you'd know how many bugs there are in total on the market - but you don't.

So how does this report solve this? Well, let it speak for itself:

Ideally, we would want similar data on Red (i.e., adversaries of Blue, or other private-use groups), to examine the overlap between Blue and Red, but we could not obtain that data. Instead, we focus on the overlap between Blue and the public (i.e., the teal section in the figures above) to infer what might be a baseline for what Red has. We do this based on the assumption that what happens in the public groups is somewhat similar to what happens in other groups. We acknowledge that this is a weak assumption, given that the composition, focus, motivation, and sophistication of the public and private groups can be fairly different, but these are the only data available at this time. (page 12)

Okay, weak assumption may be the understatement of the year. Let's summarize this: They acknowledge that they can't answer the question they want to answer. So they just answer an entirely different question (bug collision rate between the 207 bugs they have data about and what is known in public) and then claim that's about the same. To their credit they recognize that this is a weak assumption, but you have to read the report to learn that. Neither the summary nor the press release nor any of the favorable blog posts and media reports mention that.

If you wonder what the Red and Blue here means, that's also quite interesting, because it gives some insights about the mode of thinking of the authors. Blue stands for the “own team”, a company or government or anyone else who has knowledge of zero day bugs. Red is “the adversary” and then there is the public. This is of course a gross oversimplification. It's like a world where there are two nation states fighting each other and no other actors that have any interest in hacking IT systems. In reality there are multiple Red, Blue and in-between actors, with various adversarial and cooperative relations between them.

Sometimes the best answer is: We don't know

The line of reasoning here is roughly: If we don't have good data to answer a question, we'll just replace it with bad data.

I can fully understand the call for making decisions based on data. That is usually a good thing. However, it may simply be that this is a scenario where getting reliable data is incredibly hard or simply impossible. In such a situation the best thing one can do is admit that and live with it. I don't think it's helpful to rely on data that's so weak that it's basically meaningless.

The core of the problem is that we're talking about an industry that wants to be secret. This secrecy is in a certain sense in direct conflict with good scientific practice. Transparency and data sharing are cornerstones of good science.

I should mention here that shortly afterwards another study was published by Trey Herr and Bruce Schneier which also tries to answer the question of bug collisions. I haven't read it yet, from a brief look it seems less bad than the RAND report. However I have my doubts about it as well. It is only based on public bug findings, which is at least something that has a chance of being verifiable by others. It has the same problem that one can hardly draw conclusions about the non-public space based on that. (My personal tie in to that is that I had a call with Trey Herr a while ago where he asked me about some of my bug findings. I told him my doubts about this.)

The bigger picture: We need better science

IT security isn't a field that's rich of rigorous scientific data.

There's a lively debate right now going on in many fields of science about the integrity of their methods. Psychologists had to learn that many theories they believed for decades were based on bad statistics and poor methodology and are likely false. Whenever someone tries to replicate other studies the replication rates are abysmal. Smart people claim that the majority scientific outcomes are not true.

I don't see this debate happening in computer science. It's certainly not happening in IT security. Almost nobody is doing replications. Meta analyses, trials registrations or registered reports are mostly unheard of.

Instead we have cargo cult science like this RAND report thrown around as “cold hard data” we should rely upon. This is ridiculous.

I obviously have my own thoughts on the zero days debate. But my opinion on the matter here isn't what this is about. What I do think is this: We need good, rigorous science to improve the state of things. We largely don't have that right now. And bad science is a poor replacement for good science.

March 14, 2017
Andreas K. Hüttel a.k.a. dilfridge (homepage, bugs)

As nearly every year we'll present a poster on Lab::Measurement at the spring meeting of the German Physical Society again. This time the conference is in Dresden - so visit us on upcoming 23 March 2017, 15:00-19:00, poster session TT75, poster TT75.7!

March 13, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
Vodafone R205: opening it up (March 13, 2017, 00:03 UTC)

I have posted about using an R205 without a Vodafone blessed network, and I wrote a quick software inspection of the device. This time I’m writing some notes about the hardware itself.

I have originally expected to just destroy the device to try to gain access to it, but it turns out it’s actually simpler than expected to open: the back of the device is fastened through four Torx T5 screws, and then just a bit of pressure to tear the back apart from the front. No screws behind the label under the battery. I have managed to open and re-close the device without it looking much different, just a bit weathered down.

Unfortunately the first thing that becomes obvious is that the device is not designed to turn on without the battery plugged in. If you try to turn it on with just the USB connected – I tried that before disassembly, of course – the device only displays “BATTERY ERROR” and refuses to boot. This appears to be one of the errors coming from the bootloader of the board, as I can find it next to “TEMP INVALID” in the firmware strings.

Keeping the battery connected while the device is open is not possible by design. Particularly when you consider that all the interesting-looking pads are underneath the battery itself. The answer is thus to just go and solder some cables on the board and connect them to the battery — I care about my life enough not to intend to solder on the battery, that one can be connected with physical placement and tape. This is the time I had to make a call and sacrifice the device. Luckily, the answer was easy: I already have a backup device, another Vodafone Pocket WiFi, this time a R208, that my sister dismissed. Plus if I really wanted, I could get myself a newer 4G version as that’s what my SIM card supports.

There are two sets of pads that appear promising, and so I took a look at them with a simple multimeter. The first group is a 5-pads group, in which one of them correspond to ground, two appear to idle around 3V, and one appears to idle around 4V. This is not exactly your usual configuration of a serial port, but I have not managed to get more details yet. The other group is a 10-pad group with two grounds, and a number of idling pads at 1.85V, which is significantly more consistent with JTAG, but again I have not managed to inspect it yet.

Annotated image of the E586 board.

So I decided to get myself some solid core wires, and try to solder them on the five-pad configuration I saw on the board. Unfortunately the end result has been destructive, and so I had to discard the idea of getting any useful data from that board. Bummer. But, then I thought to myself that this device has to be fairly common, since Vodafone sold it anywhere from Ireland, to Italy to Australia at least. And indeed a quick look at eBay showed me a seller having, not the R205, but the Huawei E586 available for cheap. Indeed, a lot of four devices was being sold for $10 (plus €20 for postage and customs, sigh!). These were fully Huawei-branded E586 devices, with a quite different chassis and a Wind logo on them. Despite coming from New York State, this particular Wind-branded company was Canadian (now goes by Freedom Mobile); I’m not sure on the compatibility of the GSM network, but the package looked promising: four devices, but only one “complete” (battery and back cover). I bought it and it arrived just the other day.

An aside, it’s fun to note that I found just recently that Wind was used as a brand in Canada. The original brand comes from Italy, and I have been a customer of theirs for a number of years there. Indeed, my current Italian phone number is subscribed with Wind. The whole structure of co-owned brands seems to be falling apart though, with the Canadian brand gone, and with the Italian original company having been merged with Tre (Three Italy). I’m not sure on who owns what of that, but they appear to still advertise the Veon app, which matches the new name of the Russian company who owned them until now so who knows.

Opening the Wind devices is also significantly easier as it does not require as much force and does not have as many moving parts. Indeed, the whole chassis is mostly one plastic block, while the front comes away entirely. So indeed after I got home with them I opened one and looked into it, comparing it with the one I had already broken:

If you compare the two boards, you can see that on the top-right (front-facing) there is a small RF connector, which could be a Hirose U.FL or an otherwise similar connector; on the R205, this connector is on the back, making it not reachable by the user. The pad for both RF connectors are visible on as not used in the opposite board.

Next to the connector there is also a switch that is not present in the R205, which on the chassis is marked as reset. On the R205 the reset switch is towards the bottom, and there is nothing on the top side. The lower switch is marked as WPS on the chassis on the Wind device, which makes me think these are programmable somehow. I guess if I look at this deeply enough I’ll find out that these are just GPIOs for the CPU and they are just mapped differently in the firmware.

I have not managed to turn them up yet, also because I do not trust them that much. They appear to have at least the same bootloader since the BATTERY ERROR message appears on them just the same. On the other hand this gives me at least a secondary objective I can look into: if I can figure out how to extract the firmware from the resources of the update binary provided by Vodafone, and how the firmware upgrade process works, I should be able to flash a copy of the Vodafone firmware onto the Wind device as well, since they have the same board. And that would be a good starting point for it.

Having already ruined one of the boards also allows me to open up the RF shielding that is omnipresent on those boards and is hiding every detail, and it would be an interesting thing to document, and would allow to figure out if there is any chance of using OpenWRT or LEDE on it. I guess I’ll follow up with more details of the pictures, and more details of the software.

March 11, 2017
Diego E. Pettenò a.k.a. flameeyes (homepage, bugs)
Let's have a talk about TOTP (March 11, 2017, 01:03 UTC)

You probably noticed that I’m a firm believer in 2FA, and in particular on the usefulness of U2F against phishing. Unfortunately not all the services out there have upgraded to U2F to protect their users, though at least some of them managed to bring a modicum of extra safety against other threats by implementing TOTP 2FA/2SV (2-steps verification). Which is good, at least.

Unfortunately this can become a pain. In a previous post I have complained about the problems of SMS-based 2FA/2SV. In this post I’m complaining about the other kind: TOTP. Unlike the SMS, I find this is an implementation issue rather than a systemic one, but let’s see what’s going on.

I have changed my mobile phone this week, as I upgrade my work phone to one whose battery lasts more than half a day, which is important since my job requires me to be oncall and available during shifts. And as usual when this happens, I need to transfer my authenticator apps to the new phone.

Some of the apps are actually very friendly to this: Facebook and Twitter use a shared secret that, once login is confirmed, is passed onto their main app, which means you just need any logged in app to log in again and get a new copy. Neat.

Blizzard was even better. I have effectively copied my whole device config and data across with the Android transfer tool. The Battle.net authenticator copied over the shared key and didn’t require me to do anything at all to keep working. I like things that are magic!

The rest of the apps was not as nice though.

Amazon and Online.net allow you to add at any time a new app using the same shared key. The latter has an explicit option to re-key the 2FA to disable all older apps. Amazon does not tell you anything about it, and does not let you re-key explicitly — my guess is that it re-keys if you disable authentication apps altogether and re-enable it.

WordPress, EA/Origin, Patreon and TunnelBroker don’t allow you to change the app, or get the previously shared key. Instead you have to disable 2FA, then re-enable it. Leaving you “vulnerable” for a (hopefully) limited time. Of these, EA allows you to receive the 2SV code by email, so I decided I’ll take that over having to remember to port this authenticator over every time.

If you remember in the previous post I complained about the separate Authenticator apps that kept piling up for me. I realized that I don’t need as many: the login approval feature, which effectively Microsoft and LastPass provide, is neat and handy, but it’s not worth having two more separate apps for it, so I downgraded them to just use normal TOTP on the Google Authenticator app, which gets me the Android Wear support to see the code straight on my watch. I have particularly failed to remember when I last logged into a Microsoft product except for setting up the security parameters.

Steam on the other hand, was probably the most complete disaster of trying to migrate. Their app, similarly to the Battle.net one, is just a specially formatted TOTP with a shared key you’re not meant to see. Unfortunately to be able to move the Authenticator to a new phone, you need to disable it first — and you disable it from the logged-in app that has it enabled. Then you can re-enable it on a new phone. I assume there is some specific way to get recovery if that does not work, too. But I don’t count on it.

What does this all mean? TOTP is difficult, it’s hard for users, and it’s risky. Not having an obvious way to de-authenticate the app is bad. If you were at ENIGMA, you could have listened to a talk that was not recorded, on ground of the risky situations there described. The talk title was «Privacy and Security Practices of Individuals Coping with Intimate Partner Abuse». Among various topic that the talk touched upon, there was an important note on the power of 2FA/2SV for people being spied upon to gain certainty that somebody else is not logging in on their account. Not being able to de-authenticate TOTP apps goes against this certainty. Having to disable your 2FA to be able to change it to a new device makes it risky.

Then there are the features that become a compromise between usability and paranoia. As I said I love the Android Wear integration for the Authenticator app. But since the watch is not lockable, it means that anybody who could have access to my watch while I’m not attentive could have access to my TOTP. It’s okay for my use case, but it may not be for all. The Google Authenticator app also does not allow you to set a passcode and encrypt the shared keys, which means if you have enabled developer mode, run your phone unencrypted, or have a phone that is known vulnerable, your TOTP shared keys can be exposed.

What does this all mean? That there is no such thing as the perfect 100% solution that covers you against all possible threat models out there, but some solutions are better than others (U2F) and then compromises depend on what you’re defending against: a relative, or nation-states? If you remember I already went over this four years ago, and again the following year, and the one after talking about threat models. It’s a topic that I’m interested in, if it was not clear.

And a very similar concept was expressed by Zeynep Tufekci when talking about “low-profile activists”, wanting to protect their personal life, rather than the activism. This talk was recorded and is worth watching.

March 08, 2017
Marek Szuba a.k.a. marecki (homepage, bugs)
Hello world! (March 08, 2017, 02:12 UTC)

Welcome to Gentoo Blogs. This is your first post. Edit or delete it, then start blogging!

March 06, 2017
Sven Vermeulen a.k.a. swift (homepage, bugs)
Handling certificates in Gentoo Linux (March 06, 2017, 21:20 UTC)

I recently created a new article on the Gentoo Wiki titled Certificates which talks about how to handle certificate stores on Gentoo Linux. The write-up of the article (which might still change name later, because it does not handle everything about certificates, mostly how to handle certificate stores) was inspired by the observation that I had to adjust the certificate stores of both Chromium and Firefox separately, even though they both use NSS.

March 03, 2017
Nathan Zachary a.k.a. nathanzachary (homepage, bugs)

Overall, I’ve been quite happy with my 2017 Honda Civic EX-T. However, there are some cosmetic changes that I personally think make a world of difference. One of them is debadging it (or removing the “Civic” emblem from the back). Another area for improvement is to swap out the side markers, which by default (and according to law in most of the United States), is amber in colour. As it is the only area on the car that is that gross yellow/orange colour, I thought that it could be vastly improved by swapping it to either clear or some smoked black look. Initially, I ordered the ASEAN market OEM Honda clear side markers on eBay. However, I decided that on my White Orchid Pearl Civic, “smoked black” may look better, so I ordered them instead. Here’s a before-and-after of it:

2017 Honda Civic side marker changed to smoked or clear

Following the great instructions provided by a CivicX forum member, I got started. Though his instructions are spot-on, the procedure for swapping to the non-OEM smoked markers was actually a little easier. Basically, step 4 (cutting the tabs on the socket) was unnecessary. So, a simplified and concise list of the steps required for my particular swap is:

  • Turn the wheels inward to give you more room to access the wheel liner
  • Remove the three screws holding the wheel liner
  • Press on the side marker clip that holds it to the body, whilst simultaneously pushing the marker itself outward away from the body
  • Use a very small flat head screwdriver to depress the tab holding the bulb socket to the harness
  • Swap in a new bulb (if you have one, and I can recommend the Philips 194/T10 white LED bulbs, but realise that since they are white, they will not be “street legal” in many municipalities)
  • Test the polarity once you have inserted the bulb by simply turning on your headlights
  • Place the harness/new bulb/socket into the new side marker (noting that one notch is larger than the rest, which may require rotation of the side marker)
  • Align the new side marker accordingly, and make sure that it snaps into place

The only caveat I found is that the marker on the passenger’s side did not seem to want to snap into place as easily as did the one on the driver’s side. It took a little wiggling, and ultimately required me to press more firmly on the marker itself in order to get it to stay put.

For a process that only took approximately 30 minutes, though, I think that the swap made a world of difference to the overall appearance of the car. I also am happy with my choice to use the white LED bulb, as it shows quite nicely through the smoked lens:

2017 Honda Civic side marker changed to smoked or clear with white LED bulb

Cheers,
Zach

March 02, 2017
Sven Vermeulen a.k.a. swift (homepage, bugs)
cvechecker 3.7 released (March 02, 2017, 09:00 UTC)

After a long time of getting too little attention from me, I decided to make a new cvechecker release. There are few changes in it, but I am planning on making a new release soon with lots of clean-ups.

February 28, 2017
Denis Dupeyron a.k.a. calchan (homepage, bugs)
Gentoo is accepted to GSoC 2017 (February 28, 2017, 00:07 UTC)

There was good news in my mailbox today. The Gentoo Foundation was accepted to be a mentor organization for Google Summer of Code 2017!

What this means is we need you as a mentor, backup mentor or expert mentor. Whether you are a Gentoo developer and have done GSoC before does not matter at this point.

A mentor is somebody who will help during the selection of students, and will mentor a student during the summer. This should take at most one hour of your time on weekdays when student actually work on their project. What’s in it for you, you ask? A pretty exclusive Google T-shirt, a minion who does things you wouldn’t have the time or energy to do, but most importantly gratification and a lot of fun.

Backup mentors are for when the primary mentor of a student becomes unavailable for an extended period, typically for medical or family reasons. It rarely happens but it does happen. But a backup mentor can also be an experienced mentor (i.e., have done it at least once) who assists a primary mentor who is doing it for the first time.

Expert mentors have a very specific knowledge and are contacted on an as-needed basis to help with technical decisions.

You can be any combination of all that. However, our immediate need in the coming weeks is for people (again, not necessarily mentors or devs) who will help us evaluate student proposals.

If you’re a student, it’s the right time now to start thinking about what project idea you would want to work on during the summer. You can find ideas on our dedicated page, or you can come up with yours (these are the best!). One note though: you are going to be working on this full-time (i.e., 8 hours a day, we don’t allow for another even part-time job next to GSoC, although we do accommodate students who have a limited amount of classes or exams) for 3 months, so make sure your idea can keep you busy for this long. Whether you pick one of our ideas or come up with yours, it is strongly recommended to start discussing it with us on IRC.

As usual, we’d love to chat with you or answer your questions in #gentoo-soc on Freenode IRC. Make sure you stay long enough in the channel and give us enough time to respond to you. We are all volunteers and can’t maintain a 24/7 presence. It can take up to a few hours for one of us to see your request.

February 27, 2017
Thoughts on Mr Gates' Robot tax (February 27, 2017, 20:54 UTC)

In an article in QARTS Bill Gates, co-founder of Microsoft, propose that "The robot that takes your job should pay taxes". The issue also got a practical discussion outside of newspapers as the European Parliament rejected a similar proposal on February 16th, 2017 The debate is, however, an interesting one and in many ways an … Continue reading "Thoughts on Mr Gates' Robot tax"