The Case of GCC-5.1 and the Two C++ ABIs

Recently, Arch Linux updated to gcc-5.1. This brought a lot of new features, but the one that I am focusing on today is the new C++ ABI that appears when the compiler is built using default option.

Supporting the C++11 standard required incompatible changes to libstdc++ ABI. Instead of bumping the library soname (I still do not understand why that was not done…), the GCC developers decided to have a dual ABI. This is achieved using C++11 inlined namespaces which will give a different mangled name allowing types that differ across the two ABIs to coexist. When that is insufficient, a new abi_tag attribute is used which adds [abi:cxx11] to the mangled name.

With the initial upload of gcc-5.1 to the Arch repos, we configured GCC to use the old ABI by default. Now the initial slew of bugs have been dealt with (or mostly dealt with…), we want to switch to the new ABI. Because this was going to be a much larger rebuild than usual, one of the Arch developers (Evangelos Foutras) developed a server that automatically orders the rebuilds, and provides the next rebuild when a client requests it (this may be the future of rebuild automation in Arch).

This discovered an issue when building software using the new C++ ABI with clang, which builds against the new ABI (as instructed in the GCC header file), but does not know about the abi_tag attribute. This results in problems such as (for example) any function in a library with a std::string return type will be mangled with a [abi:cxx11] ABI tag. Clang does not handle these ABI tags, so will not add the tag to the mangled name and then linking will fail.

This issue was pointed out on a GCC mailing list in April, and a bug was filed independently for LLVM/clang. Until it is fixed, Arch Linux will not be able to switch to the new ABI. Note, this also has consequences for all older versions of GCC wanting to compile C++ software against system libraries…

What Is It?!

[allan@server]$ rm sample-apps/
rm: cannot remove `sample-apps/': Is a directory
[allan@server]$ rmdir sample-apps/
rmdir: failed to remove `sample-apps/': Not a directory

Edit: it was a symlink to a directory. The error messages could be improved!

Keeping Packages Vanilla – 2. Configuration

Normally when you write an article and label it with part one, it is followed soon after with a part two. Well, a lot more than two years later, I discovered this draft…. So this is part two of me rambling about what I think it means to keep packages “vanilla”. See here for the first part in which I discussed patching. Looking at configure options and dependencies is probably less clear than patching, but lets see if I come to a conclusion in this wall of text!

As I said in the previous post, in an ideal world we could just do “./configure; make; make install” and all packages would build perfectly and interact with each other the way they are supposed to. I will attempt to categorize the various options that can be added to configure and by how they change the package. This will be mostly done by looking at examples from the packages I maintain (or now, packages that I used to maintain) for Arch Linux.

The first type of configure option that will (almost) always be used is setting paths for where various files are located. Most Linux distributions will build their packages with “--prefix=/usr” and perhaps several other configuration options to set file paths. Arch Linux is not a fan of the /libexec directory so uses --libexecdir=/usr/lib where needed. (It appears that moving away from that directory is becoming widespread these days, right after the draft FHS added it…) There used to be a lot of moving of man and info pages to the “right place”, but that is automatically done in most packages these days. I doubt that anyone would consider these types of configuration options to make a package non-vanilla, unless they were set to very extreme values.

The second set of configure flags are those that enable additional features. For example, GMP can be built using the configure flag --enable-cxx to enable C++ support. That builds an additional library and adds an extra header to the package, but does not alter the primary library. Similarly, using --enable-pcre16 and --enable-pcre32 when configuring PCRE adds 16 and 32 bit character support libraries. Given these options have no effect on the primary part of the software and just add completely separate parts to it, it would be hard to argue that such configuration options are not vanilla.

So lets move onto configuration options that actually alter the software. Lets start with glibc, binutils and gcc which all have

--with-bugurl=https://bugs.archlinux.org/

set in the Arch Linux packages. Is that vanilla? It can be argued that I am setting a value not considered by upstream, but clearly upstream thought allowing the package to set such a value was a good idea given there is a configuration option. So I’d say that is still vanilla.

How about Less which is configured with --with-regex=pcre and adds a dependency to the software. There is actually quite a number of possible values for this configuration option:

--with-regex={auto,gnu,pcre,posix,regcmp,re_comp,regcomp,regcomp-local,none}

Looking at that list, I would suppose auto is the most vanilla, as that is what happens if you do not specify the option. But it is also the least deterministic, in that it will pick a different option based on what is installed on your system. In fact, on my system it picks “posix” by default, which was a moderate surprise to me. Given that these options are all provided by the software developer (and so should all be supported), I think you could make the case they all are vanilla. But I would be surprised to see (at least) the last five options used on any Linux system, so calling them vanilla is a stretch.

What is the conclusion? I suppose that configuration options are mostly put there to be used by the upstream developers so any use of them would be considered vanilla. But keep in mind what a software developer would expect. Picking strange configurations compared to what is usual for your operating system is likely to get you (virtual) weird looks from upstream, so that can not be considered a vanilla configuration.

Perhaps this part is more boring than the discussion of patching. But the second part of a trilogy is rarely the greatest. Part 3 should appear soon…

Help Me Out By Sending A Postcard

I am teaching my daughter about the world and all the different countries there are. She also likes receiving mail, so we came up with the idea of collecting postcards from all over the world.

If you would like to help me out by sending her a post card, all the details are on her website. Thanks!

Updating Arch Kernel On Digital Ocean

I have not bothered updating my Linux kernel package here since my VPS provider – Digital Ocean – went crazy and deprecated Arch Linux as an install option. That is obviously a bad thing…

This backfired on me today. It turns out that systemd-218 does not like an old i686 kernels (I had 3.13.7) and I could not log in. I am not the only one to notice this, so there may be a genuine bug there. It also seems that DO recovery console is a bit useless if you have a problem other than a network issue. Good thing I have DO system backups set to run every week (in a completely unrelated incident… I think one comment on one of my posts got lost and restoring from my more regular WordPress backup is too much effort).

So how to run a newer kernel – I have no idea what DO do in the background, but your installed kernel needs to match the one you select in the DO control panel. I think the kernel and initrd are stored externally and if this does not match the installed version, your system’s modules fail to load. This is how I know the rescue console is good when networking fails!

Kexec to the rescue! You can do a fancy systemd type thing (see Arch wiki page), but I just provided a script in /usr/bin/init. To do this, install kexec-tools and remove systemd-sysvcompat. Then paste this into /usr/bin/init:

#!/bin/sh
 
kexec --load /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --append="root=LABEL=DOROOT init=/usr/lib/systemd/systemd" &&
mount -o ro,remount / &&
kexec -e
 
exec /usr/lib/systemd/systemd

Give that file 755 permissions, and all is done.

Now if all that does not put you off, and you really want to install Arch Linux on DO, here is a script that coverts a Debain droplet to an Arch one! You can also use my referral link

Edit: when checking this article before posting I found this and this. I’m not as clever as I thought, or these people are at least equally clever.

Improvements on Manjaro Security Updates

I’ll give credit where it is due. I had previously criticized Manjaro for holding back all package updates as this ignored security issues. But it appears that Manjaro has a new security policy, which means that packages that are rated as “Critical” or “High” in the Arch Security Advisories get pushed through their “quality assurance” process more quickly.

Fanmail

Posting so more people can get entertainment value from this email.

From: Daniel Skowroński <daniel@dsinf.net>
Subject: –asroot

Hi Allan,
I’d like to say you are moron if you were thinking that commiting 61ba5c961e4a3536c4bbf41edb348987a9993fdb to pacman was good idea!
I am Arch Linux user becouse it allows me to do virtually anything so I manage some of my arch-based servers from root account. I also have netbook with root account only for my own reasons. And you’ve destroyed not only my routine but also several programs that were depending on that. Screw you with reverting package version or using patch from aur – it’s supposed to work out-of-the-box even on Arch.

No greetings,
Daniel Skowroński

PS. You could have at least let anybody else sign-off that imbecile commit…

Who You Gonna Call?

GHOSTbusters

Nobody… Arch Linux has the latest glibc release (2.20) so is not affected by the GHOST bug, which was fixed upstream in glibc-2.18 (without realising the security implications).

For those that want to know more about security issues and updates in Arch Linux, check out the arch-security mailing list.

Replacing “makepkg –asroot”

An alarming number of people have noticed, the pacman-4.2 release removed the --asroot option from makepkg. This means that you can no longer build packages as the root user. There are good reasons for this and the option was only included due to issue we had building under fakeroot (only the package() function gets fun under fakeroot these days, and there has been no issues with fakeroot in a while anyway).

Even if your PKGBUILD file is not malicious, there are good examples of when something goes wrong by accident. Remember the bumblebee bug that deleted /usr due to an extra space? Or just this week a steam bug that deletes a user home directory? Do you still want to run code as root? OK then… I am going to show you how not to!

Firstly, we need a build directory. I suggest /home/build. Putting this directory directly under /root will not work unless you want to relax its 700 permissions to allow the nobody user read/write access1. I suppose you could as you are running as root… but I will use /home/build. Create the directory and set permissions with the following:

mkdir /home/build
chgrp nobody /home/build
chmod g+ws /home/build
setfacl -m u::rwx,g::rwx /home/build
setfacl -d --set u::rwx,g::rwx,o::- /home/build

Not that people running makepkg as root need to know what code is doing to run it… I’ll explain what is happening here. Firstly create a /home/build directory, make it owned by the nobody group and ensure that group has write permissions. Also add the sticky flag to the group permissions so all files created in that directory also are owned by the nobody group. Then we set ACLs to ensure all files and directories created in /home/build have group read/write permissions.

Now to building you package! Get you PKGBUILD in your new build directory and run makepkg as the nobody user. You can do this using su but using sudo has the advantage of being able to alias this command. Installing sudo does not create a security risk as you are running as root! You also do not need to configure anything as root will have full sudo permissions by default2. Build your package using:

sudo -u nobody makepkg

Done… I’d add “alias makepkg='sudo -u nobody makepkg” to your ~/.bashrc so you never have to type this again.

There is still a problem here. If you download and manually extract a package sourceball, or use an AUR helper such as cower to do so, the group write permissions get lost:

[root@arya build]# cower -d pacman-git
:: pacman-git downloaded to /home/build
 
[root@arya build]# ls -ld pacman-git/
drwxr-xr-x+ 2 root nobody 4096 Mar 21 2013 pacman-git/

Doing “chmod -R g+w pacman-git/” will fix this. There is probably a way to avoid this – at least when manually extracting the tarball, but I have no interest in figuring it out. Otherwise, it is a two line function.

And if this does not satisfy you, revert that patch that removed --asroot. It should still revert cleanly.


1 makepkg checks directory write permissions using the full path so fails if any parent directories are not writable. I guess this could be fixed if someone was interested.

2 Note that to have makepkg install missing dependencies and install your built package without being queried the password for the nobody user (which would be difficult to answer…), you will need to configure nobody to run sudo pacman without a password.

Two PGP Keyrings for Package Management in Arch Linux

Both the pacman package manager and the makepkg tool for building packages verify files using PGP signatures. However, these two pieces of software do it using different keyrings. There seems to be a lot of confusion about this and misinformation is spreading at a rapid pace, so I’ll attempt to clarify it here!

Pacman Package File Signature Verification
By default, pacman is set-up to verify every package using a PGP signature. It has its own keychain for this purpose, located at /etc/pacman.d/gnupg/. This keychain is initialized during the Arch Linux install – a root key is created and the Arch Linux master keys are locally signed by the root key. The master keys sign all Arch Developer and Trusted User keys, creating an effective web-of-trust from your pacman root key to each of the packager keys allowing verification of package files.

If you want to allow the installation of package files from a non-official repository, you need to either disable signature verification (don’t do that…), or trust the packagers signing key. To do this you first need to verify their key ID, which should be well publicized. Then you import it into the pacman keyring using “pacman-key --recv-key <KEYID>” and signify that you trust the key by locally signing it with your pamcan root key by running “pacman-key --lsign <KEYID>“.

Makepkg Source File Signature Verification
When building a package, the source files are often (and should be!) signed, with a signature file available for download alongside the source file. This typically has the same name as the source file with the extension .sig or .asc.makepkg will automatically verify the signature if it is downloaded in the sources array. e.g.:

source=(http://ftp.gnu.org/gnu/libc/${pkgname}-${pkgver}.tar.xz{,.sig})

However, makepkg needs some information to verify the source signature. It will need the public PGP key of the person who signed the source file, and that key to be trusted. The difference here is that you do not trust whoever provided the source file to provide packages for your system (or at least you should not the vast majority of the time), so your user’s keyring is used. To get the key use “gpg --recv-key <KEYID>” and trust it (once suitably verified) using “gpg --lsign <KEYID>“.

If you provide a package to the AUR, it would be a lot of work for everyone to suitably verify a PGP key and locally sign it. To demonstrate that you have verified the key, you can add the following to the PKGBUILD:

validpgpkeys=('F37CDAB708E65EA183FD1AF625EF0A436C2A4AFF') # Carlos O'Donell

Now makepkg will trust that key, even if it is not trusted in the package builder’s PGP keyring. The builder will still need to download the key, but that can be automated in their gpg.conf file.

Hopefully that clarifies the two separate types of PGP signature verification happening in pacman and makepkg and explains why they should be separate… Now can people stop recommending that the pacman keyring is imported into the user’s keyring and vice versa?