Skip to content

Issue with sudo env <command> environment handling #453

@Lockszmith-GH

Description

@Lockszmith-GH

I encountered this while using a long env variable created by vivid - see this for background.

If I use sudo with env to call a command (I'll provide test output with echo, but it can be anything), I get a lot of screens-full of LS_COLORS' content repeated spewed on the terminal (wc -c counted 4,309,250 characters), it starts with:

envp[3] mismatch, expected "LS_COLORS=*~=0;38;2;102;102;102:bd=0;38;2;71;190;169;48;2;51;51;51:ca=0...

After reporting this issue in the env project, it was pinpointed to be sourced in sudo.

(click to expand) - Below is a reproduction that shows the issue is triggered when LS_COLORS is more than 4086 characters long.
# make sure commands are being run 'vanilla'
❯ type env
env is /usr/bin/env

❯ type sudo
sudo is /usr/bin/sudo

# Setup vivid's theme
❯ export VIVID_THEME='alabaster_dark'
❯ export LS_COLORS="$( vivid generate )"
# if no vivid on your system, you can reproduce with
❯ export LS_COLORS="$( head -c 12462 </dev/zero | tr '\0' 'A' )"

## Testing with LS_COLORS as it is passed on by default by sudo

# vivid's LS_COLORS theme's length
❯ echo -n "$LS_COLORS" | wc -c
12462

# sudo + env without LS_COLORS
❯ (LS_COLORS= sudo env sh -c 'echo "Everything is OK"' 1>/dev/null) 2>&1 | wc -c
0

# sudo + env with vivid's LS_COLORS untouched
❯ (sudo env echo "Everything is OK" 1>/dev/null) 2>&1 | wc -c
4309214
zsh: killed     ( sudo env echo "Everything is OK" > /dev/null; ) 2>&1 |
zsh: done       wc -c

# Demonstrate how wc -c counts
❯ echo -n "${LS_COLORS:0:1}" | wc -c
1
❯ echo "${LS_COLORS:0:1}" | wc -c
2

# Demonstrate how I reduce the length of LS_COLORS to 4085
❯ echo -n "${LS_COLORS:0:4085}" | wc -c
4085

# This is still OK: sudo + env with vivid's LS_COLORS cut to 4085
❯ (LS_COLORS="${LS_COLORS:0:4085}" sudo env echo "Everything is OK" 1>/dev/null) 2>&1 | wc -c
0

# Breaks! : sudo + env with vivid's LS_COLORS cut to 4086
❯ (LS_COLORS="${LS_COLORS:0:4086}" sudo env echo "Everything is OK" 1>/dev/null) 2>&1 | wc -c
12324
zsh: killed     ( LS_COLORS="${LS_COLORS:0:4086}" sudo env echo "Everything is OK" > /dev/nul |
zsh: done       wc -c

# Breaks! : This demonstrate that some duplication is occurring, as an increase in 1 character, increased the output with 2 characters in length
❯ (LS_COLORS="${LS_COLORS:0:4087}" sudo env echo "Everything is OK" 1>/dev/null) 2>&1 | wc -c
12326
zsh: killed     ( LS_COLORS="${LS_COLORS:0:4087}" sudo env echo "Everything is OK" > /dev/nul |
zsh: done       wc -c

❯ (LS_COLORS="${LS_COLORS:0:4088}" sudo env echo "Everything is OK" 1>/dev/null) 2>&1 | wc -c
12328
zsh: killed     ( LS_COLORS="${LS_COLORS:0:4088}" sudo env echo "Everything is OK" > /dev/nul |
zsh: done       wc -c

Further testing revealed it was not about LS_COLORS, and I reproduced it with an explicitly passed env variable:

❯ (sudo env -i "A=${LS_COLORS:0:4093}" echo "OK" 1>/dev/null) 2>&1 | wc -c
0

❯ (sudo env -i "AA=${LS_COLORS:0:4093}" echo "OK" 1>/dev/null) 2>&1 | wc -c
12324
zsh: killed     ( sudo env -i "AA=${LS_COLORS:0:4093}" echo "OK" > /dev/null; ) 2>&1 |
zsh: done       wc -c

The -i means 'clean environment' - nothing passed to the command.
When I add a letter to the assignment (the name of the variable in this case), it breaks the same way.

'AA=' that's 3 characters + the 4093 characters from my testing = 4096.
Searching for a possible limit that matches - found this page with some good details.

And it seems 4096 is indeed a known limit:

true | xargs --show-limits
Your environment variables take up 13861 bytes
POSIX upper limit on argument length (this system): 2081243
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2067382
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647

At least nothing is random:

POSIX smallest allowable upper limit on argument length (all systems): 4096

More information about what I'm running:

❯ env --version
env (GNU coreutils) 9.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Richard Mlynarik, David MacKenzie, and Assaf Gordon.

❯ sudo --version
Sudo version 1.9.13p3
Sudoers policy plugin version 1.9.13p3
Sudoers file grammar version 50
Sudoers I/O plugin version 1.9.13p3
Sudoers audit plugin version 1.9.13p3

For now, I've set an alias for sudo and things are not breaking:

alias sudo='sudo "LS_COLORS=${LS_COLORS:0:4085}" '

Why open this issue?

Is this a known issue? (I couldn't find anybody else encountering this)
or is this a bug?
I'm looking for some explanation on what is happening here, and what precisely is triggering this behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions