dash command variable assignments remain in the shell after command execution completed

Bug #1516300 reported by Alexko
256
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dash (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

If a shell function is invoked with variable assignments preceding it, the assignments remain in the shell after the command execution completed. This is unexpected behavior and might be a potential security issue, since it allows to modify the user environment in a subtle unexpected way. For example, consider the following commands that shouldn't change the SHELL value outside function foo, yet it does in Ubuntu 14.04

echo $SHELL # check our default shell, gives /bin/bash

foo () { printenv | grep SHELL; } # no side effects, can be anything
SHELL=/bin/sh foo

echo $SHELL # now gives /bin/sh, but expected to give /bin/bash as before

I checked bash and zsh, none of them have this problem. sh in freebsd and debian handle this case correctly. So far, it seems the issue is limited to Ubuntu dash.

lsb_release -rd
Description: Ubuntu 14.04.3 LTS
Release: 14.04

apt-cache policy dash
dash:
  Installed: 0.5.7-4ubuntu1
  Candidate: 0.5.7-4ubuntu1
  Version table:
 *** 0.5.7-4ubuntu1 0
        500 http://us.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
        100 /var/lib/dpkg/status

Alexko (allkos)
Changed in dash (Ubuntu):
status: New → Opinion
Revision history for this message
Alexko (allkos) wrote :

I found that POSIX allows this, so I changed the status to opinion

"If no command name results, or if the command name is a special built-in or function, variable assignments shall affect the current execution environment."
http://pubs.opengroup.org/onlinepubs/9699919799/

I still think it would be better to keep those assignments local to the function as other shell do. As it stands, it is not immediately obvious from looking at the command line if those assignments will affect or not affect the current execution environment. Wrapping some command into a shell function, changes semantics of how those assignments are handled to the opposite without any visible changes to the command line.

information type: Private Security → Public Security
Revision history for this message
Seth Arnold (seth-arnold) wrote :

This might represent a behaviour that's still unwanted in our dash packages, especially if Debian's dash packages differ. So I'm setting it back to 'new' in the hopes that someone from Foundations can give it a look and decide if this deserves an SRU.

It certainly surprises me.

Thanks

Changed in dash (Ubuntu):
status: Opinion → New
Changed in dash (Ubuntu):
status: New → Confirmed
Revision history for this message
Seth Arnold (seth-arnold) wrote :

I gave this a test with Ubuntu 14.04, 16.04, 18.04, 20.04, LTS releases, and Debian 10 and Debian 11, in lxd.

Ubuntus before 20.04 all showed the described behaviour.

Ubuntu 20.04 LTS worked the same as both Debian releases.

The versions of dash in each release make this make some sense:

$ for h in u14 u16 u18 u20 d10 d11 ; do echo $h ; lxc exec $h -- dpkg -l dash | awk '/^ii/ {print $2, $3;}' ; done
u14
dash 0.5.7-4ubuntu1
u16
dash 0.5.8-2.1ubuntu2
u18
dash 0.5.8-2.10
u20
dash 0.5.10.2-6
d10
dash 0.5.10.2-5
d11
dash 0.5.10.2-7

What's even more surprising to me is that the functionality of passing a variable in to the function doesn't even work in dash. Compare the bash with the dash:

u20-bash$ foo () { printenv | grep SHELL; }
u20-bash$ echo $SHELL
/bin/bash
u20-bash$ foo
u20-bash$ SHELL=foo foo
SHELL=foo
u20-bash$ echo $SHELL
/bin/bash

u20-dash$ foo () { printenv | grep SHELL; }
u20-dash$ foo
u20-dash$ SHELL=foo foo
u20-dash$ echo $SHELL

u20-dash$

I'm surprised at such a fundamental difference in behaviour between the two, but it's now been five years with no other reports, so perhaps no one depends upon the behaviour and changes which shell they use to execute scripts.

It might be best to just leave it alone.

Thanks

To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

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