Bash ignores exit trap on success when part of a command string

Bug #1641832 reported by Lee Trager on 2016-11-15
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
bash (Ubuntu)
Critical
Matthias Klose

Bug Description

The MAAS team uses a script, lp:maas-images, which generates the images available at images.maas.io. As part of this process we use the following to convert a SquashFS image to an ext4 image.

sudo bash -ec 'src="$1"; img="$2"; trgmp="$3";
    mounts=""
    cleanup() { for m in $mounts; do umount "$m"; done; }
    trap cleanup EXIT
    mount -o loop "$img" "$trgmp"
    mounts="$trgmp"
    unsquashfs -force -xattrs -dest "$trgmp" "$src"' \
    "squashimg-to-image" "$squashimg" "$output" "$trgmp"
ret=$?
rm -Rf "$mtmp" || return
return $ret

Prior to 4.4-1ubuntu1 the trap would always cause the cleanup function to always be called. Its now only called on failure. This causes the mount to remain and the following rm to fail. If I add 'false' to the end of the command script or downgrade to 4.3-15ubuntu1 the cleanup occurs.

Steve Langasek (vorlon) wrote :

Per <http://pubs.opengroup.org/onlinepubs/007904975/utilities/trap.html> the expected behavior is that an 'EXIT' trap is called at exit from the shell regardless of circumstances. This appears to be a regression in bash.

Matthias, can you follow this up, please?

Changed in bash (Ubuntu):
assignee: nobody → Matthias Klose (doko)
importance: Undecided → Critical
status: New → Triaged
Steve Langasek (vorlon) wrote :

Can someone show a minimal test case for this bug? The following command works as expected under either 4.3 or 4.4:

$ bash -ec 'cleanup() { echo foo; }; trap cleanup EXIT; echo bar'
bar
foo
$

Steve Langasek (vorlon) wrote :

The following seems like it should be a non-destructive reproducer case for the bug, based tightly on the original example, but it also doesn't let me reproduce the problem - the 'cleanup' trap definitely still triggers.

$ sudo bash -ec 'src="$1"; img="$2"; trgmp="$3";
    mounts=""
    cleanup() { for m in $mounts; do echo umount "$m"; done; }
    trap cleanup EXIT
    echo mount -o loop "$img" "$trgmp"
    mounts="$trgmp"
    echo unsquashfs -force -xattrs -dest "$trgmp" "$src"' "squashimg-to-image" foo bar baz
mount -o loop bar baz
unsquashfs -force -xattrs -dest baz foo
umount baz
$

Lee Trager (ltrager) wrote :

I'm having trouble coming up with a simpler test case myself. Here is how you can reproduce with lp:maas-images on Zesty with bash-4.4-1ubuntu1

mkdir maas-images
cd maas-images
bzr init
bzr branch lp:maas-images
cd
export PATH=/home/ubuntu/maas-images/trunk/bin:$PATH
wget http://cloud-images.ubuntu.com/daily/server/zesty/20161111/zesty-server-cloudimg-amd64.squashfs
meph2-build --image-format squashfs-image -vv --enable-di amd64 zesty 20161111 zesty-server-cloudimg-amd64.squashfs out.d

If you execute that with 4.4-1ubuntu1 it fails due to the loop back mount still being mounted(mount | grep maas). If you downgrade to 4.3-15ubuntu1 or use the patch from lp:~ltrager/maas-images/workaround_lp1641832 umount is called and the script executes successfully.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package bash - 4.4-2ubuntu1

---------------
bash (4.4-2ubuntu1) zesty; urgency=medium

  * Merge with Debian; remaining changes:
    - skel.bashrc:
      - Run lesspipe.
      - Enable ls aliases.
      - Set options in ll alias to -alF.
      - Define an alert alias.
      - Enabled colored grep aliases.
    - etc.bash.bashrc:
      - Add sudo hint.

bash (4.4-2) unstable; urgency=medium

  * Apply upstream patches 001 - 005.
    - Closes: #844299, LP: #1641832.
  * Don't build with PIE. Closes: #842037.

 -- Matthias Klose <email address hidden> Tue, 15 Nov 2016 20:06:17 +0100

Changed in bash (Ubuntu):
status: Triaged → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers