cryptsetup ftbfs in focal

Bug #1891473 reported by Matthias Klose
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
cryptsetup (Ubuntu)
Fix Released
High
Guilherme G. Piccoli
Focal
Fix Released
High
Guilherme G. Piccoli
Groovy
Fix Released
High
Guilherme G. Piccoli

Related branches

CVE References

Matthias Klose (doko)
tags: added: ftbfs rls-ff-incoming
Matthias Klose (doko)
Changed in cryptsetup (Ubuntu):
status: New → Confirmed
importance: Undecided → High
tags: removed: rls-ff-incoming
Revision history for this message
Guilherme G. Piccoli (gpiccoli) wrote :

This started after PPA builders got upgraded to Bionic, this worked before.

tags: added: id-5f358712d1ea131fd27e581f
Changed in cryptsetup (Ubuntu Focal):
status: New → Confirmed
importance: Undecided → High
Revision history for this message
Guilherme G. Piccoli (gpiccoli) wrote :

I've noticed the problem happens in both Focal and Groovy builds. It's related with the restricted environment (read restricted as "containerized" environment), the failure happens in the "cryptsetup luksDump" against the "luks2-metadata-size-4m.img" image during the metadata validation test.

I'm testing in a Bionic VM with Focal LXD container; I was able to dump such image in the local build, and when try to run the lunksDump thing it fails inside the container but works in a Focal native system, with the apt-installed cryptsetup package.

Investigation continues.
Cheers,

Guilherme

Changed in cryptsetup (Ubuntu Focal):
status: Confirmed → In Progress
Changed in cryptsetup (Ubuntu Groovy):
status: Confirmed → In Progress
Changed in cryptsetup (Ubuntu Focal):
assignee: nobody → Guilherme G. Piccoli (gpiccoli)
Changed in cryptsetup (Ubuntu Groovy):
assignee: nobody → Guilherme G. Piccoli (gpiccoli)
Revision history for this message
Guilherme G. Piccoli (gpiccoli) wrote :
Download full text (5.0 KiB)

After some investigation, seems we were able to narrow down the issue.

* tl;dr: After the upgrade of the PPA builder to Bionic, the memlock limit (ulimit -l) was bumped from a ridiculous low value (64) to something bigger (16M). Happens that cryptsetup then succeeded in its call to mlockall(), so all allocations got restricted by such limit, which is still a bit low and it ends up leading to allocation failures.
When the limit is very low (like in Xenial), the lock procedure fails, and cryptsetup allocations are not subject to this restriction, so everything just works.

See section "Conclusion" for alternatives on how to fix this

* Details:
I manage to reproduce that by collecting the luks2-validation images in a local environment, running a Bionic VM + LXD (a Focal container). By collecting the strace of luksDump in both environments, we got the following:

### LXD - NOT working
...
openat(AT_FDCWD, "./luks2-metadata-size-4m.img", O_RDONLY|O_DIRECT) = 5
fstat(5, {st_mode=S_IFREG|0644, st_size=16777216, ...}) = 0
fstat(6, {st_mode=S_IFREG|0644, st_size=16777216, ...}) = 0
lseek(5, 0, SEEK_SET) = 0
read(5, "LUKS\272\276\0\2\0\0\0\0\0@\0\0\0\0\0\0\0\0\0\n\0\0\0\0\0\0\0\0"..., 4096) = 4096
mmap(NULL, 4194304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
brk(0x55e789c38000) = 0x55e78982d000
mmap(NULL, 4325376, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
lseek(5, 16384, SEEK_SET) = 16384
read(5, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
lseek(5, 32768, SEEK_SET) = 32768
read(5, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
lseek(5, 65536, SEEK_SET) = 65536
read(5, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
...

### VM - working
...
openat(AT_FDCWD, "./luks2-metadata-size-4m.img", O_RDONLY|O_DIRECT) = 5
fstat(5, {st_mode=S_IFREG|0644, st_size=16777216, ...}) = 0
fstat(6, {st_mode=S_IFREG|0644, st_size=16777216, ...}) = 0
lseek(5, 0, SEEK_SET) = 0
read(5, "LUKS\272\276\0\2\0\0\0\0\0@\0\0\0\0\0\0\0\0\0\n\0\0\0\0\0\0\0\0"..., 4096) = 4096
mmap(NULL, 4194304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6b06031000
lseek(5, 4096, SEEK_SET) = 4096
mmap(NULL, 4198400, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6b05c30000

So: as mmap fails, lseeks start to be attempted with wrong sizes, 2K^N, where N=4,5,...

In cryptsetup code: on luks2_disk_metadata.c, function LUKS2_disk_hdr_read(), we fail and try all known offsets, as per the below code:

[...]
   * No header size, check all known offsets.
                 */
                for (r = -EINVAL,i = 0; r < 0 && i < ARRAY_SIZE(hdr2_offsets); i++)
[...]

This explains why we see that many lseeks in the LXD failing case, with multiple offsets.

But then, why we fail? In the failing case, on funtion LUKS2_disk_hdr_read(), we fail right in the first header read, as per code in lib/luks2/luks2_disk_metadata.c:

[...]
      ...

Read more...

Revision history for this message
Guilherme G. Piccoli (gpiccoli) wrote :

Email sent to Ubuntu-devel ML seeking opinions on the approach we should take to fix this issue: https://lists.ubuntu.com/archives/ubuntu-devel/2020-September/041159.html .

Revision history for this message
Guilherme G. Piccoli (gpiccoli) wrote :

We also face problems in ppc64el, even more tests fail - in general PowerPC is a more memory-consuming arch, especially given the default page size in such arch is 64K. Three tests fail there due to low host mlock limit in Bionic; I've written a patch to fix that in the package, in case somebody (like security) needs to release cryptsetup urgently due to a bug. I'll attach it here.

Also, the consensus on the ubuntu-devel thread on how to fix properly the PPA builder issues was to bump systemd memlock limit on Bionic, making it on-par with more recent releases. This is being addressed in LP #1830746 (https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1830746).

Cheers,

Guilherme

Revision history for this message
Guilherme G. Piccoli (gpiccoli) wrote :
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package cryptsetup - 2:2.2.2-3ubuntu2.2

---------------
cryptsetup (2:2.2.2-3ubuntu2.2) focal-security; urgency=medium

  * SECURITY UPDATE: Out-of-bounds write
    - debian/patches/CVE-2020-14382-*.patch: check segment gaps regardless of
      heap space in lib/luks2/luks2_json_metadata.c.
    - CVE-2020-14382
  * debian/patches/decrease_memlock_ulimit.patch
    Fixed FTBFS due a restrict environment in the new Bionic Builder (LP: #1891473)
    tests/luks2-validation.test, tests/compat-test, tests/tcrypt-compat-test.
    - Thanks Guilherme G. Piccoli.

 -- <email address hidden> (Leonidas S. Barbosa) Thu, 10 Sep 2020 08:47:50 -0300

Changed in cryptsetup (Ubuntu Focal):
status: In Progress → Fix Released
Changed in cryptsetup (Ubuntu Groovy):
status: In Progress → Fix Committed
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package cryptsetup - 2:2.3.3-1ubuntu5

---------------
cryptsetup (2:2.3.3-1ubuntu5) groovy; urgency=medium

  * SECURITY UPDATE: Out-of-bounds write
    - debian/patches/CVE-2020-14382-*.patch: check segment gaps regardless of
      heap space in lib/luks2/luks2_json_metadata.c.
    - CVE-2020-14382
  * debian/patches/decrease_memlock_ulimit.patch
    Fixed FTBFS due a restrict environment in the new Bionic Builder (LP: #1891473)
    tests/luks2-validation.test, tests/compat-test, tests/tcrypt-compat-test.
    - Thanks Guilherme G. Piccoli.

 -- <email address hidden> (Leonidas S. Barbosa) Wed, 09 Sep 2020 09:29:17 -0300

Changed in cryptsetup (Ubuntu Groovy):
status: Fix Committed → Fix Released
tags: added: fr-236
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.