Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/snap: proxy stdout when running app under strace #13501

Merged

Conversation

bboozzoo
Copy link
Contributor

Recent versions of sudo (1.9.14+) changed the terminal flags when switching to the child process which broke the output of some commands which had their output piped. This was addressed in the upstream in
https://www.sudo.ws/repos/sudo/rev/faa06b1e8913 which added detection of whether a stdout is on a pipe, and thus preserved the terminal flags. In our case, when running a command under strace, we expect strace logs on stderr hence fd 2 is a pipe which isn't picked up by sudo auto detection, thus terminal flags are not being preserved and the output is garbled like so:

[pid 838721] execve("/snap/hello-world/29/bin/echo", ["/snap/"...], ["DBUS_S"..., "DEBUGI"..., "DISPLA"..., "EDITOR"..., "HG=/us"..., "HOME=/"..., "INVOCA"..., "JOURNA"..., "KWIN_T"..., "LANG=e"..., "LC_MES"..., "LC_TIM"..., "LOGNAM"..., "MAIL=/"..., "MANAGE"..., "MEMORY"..., "MEMORY"..., "MOZ_EN"..., "MOZ_X1"..., "OLDPWD"..., "PAGER="..., "PATH=/"..., "PLASMA"..., "PWD=/h"..., "SHELL="..., "SHLVL="..., "SNAP=/"..., "SNAP_A"..., "SNAP_C"..., "SNAP_C"..., "SNAP_C"..., "SNAP_D"..., "SNAP_E"..., "SNAP_I"..., "SNAP_I"..., "SNAP_L"..., "SNAP_N"..., "SNAP_R"..., "SNAP_R"..., "SNAP_R"..., "SNAP_U"..., "SNAP_U"..., "SNAP_U"..., "SNAP_V"..., "SSH_AU"..., "SUDO_C"..., "SUDO_G"..., "SUDO_U"..., "SUDO_U"..., "SYSTEM"..., "TEMPDI"..., "TERM=t"..., "TERM_P"..., "TERM_P"..., "TMPDIR"..., "TMUX=/"..., "TMUX_P"..., "USER=r"..., "XAUTHO"..., "XDG_DA"..., "XDG_RU"..., "_=/usr"...] <unfinished ...>
                                                                                                                             [pid 838725] <... futex resumed>)       = ?
                                                                                                                                                                        [pid 838726] <... futex resumed>)       = ?
                                                                                                                                                                                                                   [pid 838727] <... futex resumed>)       = ?
                                                                                                                                                                                                                                                              [pid 838728] <... futex resumed>)       = ?

The patch makes stdout a pipe, which fixes the detection part. The obvious downside is that programs which now expect a tty on fd 1 will no longer work as expected. The issue is however limited to the cases when the app is running under strace.

@bboozzoo bboozzoo requested a review from zyga January 19, 2024 11:02
cmd.Stdout = Stdout
// note hijacking stdout, means it is no longer a tty and programs
// expecting stdout to be on a terminal (eg. bash) may misbehave at this
// point
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should print a warning to stderr to make it clear that using --strace has this behavior, as it is a change from previous years explicitly meant to avoid a bug.

go func() {
defer func() { filterDone <- true }()
defer func() { close(filterDone) }()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop the func and just defer close(...)

@@ -1013,10 +1020,17 @@ func (x *cmdRun) runCmdUnderStrace(origCmd []string, envForExec envForExecFunc)
}
io.Copy(Stderr, r)
}()

go func() {
defer func() { close(stdoutProxyDone) }()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto on needless fuc

@bboozzoo
Copy link
Contributor Author

FYI filed sudo-project/sudo#349

Recent versions of sudo (1.9.14+) changed the terminal flags when switching to
the child process which broke the output of some commands which had their output
piped. This was addressed in the upstream in
https://www.sudo.ws/repos/sudo/rev/faa06b1e8913 which added detection of whether
a stdout is on a pipe, and thus preserved the terminal flags. In our case, when
running a command under strace, we expect strace logs on stderr hence fd 2 is a
pipe which isn't picked up by sudo auto detection, thus terminal flags are not
being preserved and the output is garbled like so:

[pid 838721] execve("/snap/hello-world/29/bin/echo", ["/snap/"...], ["DBUS_S"..., "DEBUGI"..., "DISPLA"..., "EDITOR"..., "HG=/us"..., "HOME=/"..., "INVOCA"..., "JOURNA"..., "KWIN_T"..., "LANG=e"..., "LC_MES"..., "LC_TIM"..., "LOGNAM"..., "MAIL=/"..., "MANAGE"..., "MEMORY"..., "MEMORY"..., "MOZ_EN"..., "MOZ_X1"..., "OLDPWD"..., "PAGER="..., "PATH=/"..., "PLASMA"..., "PWD=/h"..., "SHELL="..., "SHLVL="..., "SNAP=/"..., "SNAP_A"..., "SNAP_C"..., "SNAP_C"..., "SNAP_C"..., "SNAP_D"..., "SNAP_E"..., "SNAP_I"..., "SNAP_I"..., "SNAP_L"..., "SNAP_N"..., "SNAP_R"..., "SNAP_R"..., "SNAP_R"..., "SNAP_U"..., "SNAP_U"..., "SNAP_U"..., "SNAP_V"..., "SSH_AU"..., "SUDO_C"..., "SUDO_G"..., "SUDO_U"..., "SUDO_U"..., "SYSTEM"..., "TEMPDI"..., "TERM=t"..., "TERM_P"..., "TERM_P"..., "TMPDIR"..., "TMUX=/"..., "TMUX_P"..., "USER=r"..., "XAUTHO"..., "XDG_DA"..., "XDG_RU"..., "_=/usr"...] <unfinished ...>
                                                                                                                             [pid 838725] <... futex resumed>)       = ?
                                                                                                                                                                        [pid 838726] <... futex resumed>)       = ?
                                                                                                                                                                                                                   [pid 838727] <... futex resumed>)       = ?
                                                                                                                                                                                                                                                              [pid 838728] <... futex resumed>)       = ?

The patch makes stdout a pipe, which fixes the detection part. The obvious
downside is that programs which now expect a tty on fd 1 will no longer work as
expected. The issue is however limited to the cases when the app is running
under strace.

Signed-off-by: Maciej Borzecki <[email protected]>
…utput

There are scenarios in which we are not processing the output of strace command,
specifically when the user has passed `--raw`. The user can also redirect strace
output to a file passing `-o` || `--output`, in which case processing is not
possible either. In both scenarios it makes no sense to set up a pipe on
stdout/stderr.

Signed-off-by: Maciej Borzecki <[email protected]>
@bboozzoo bboozzoo force-pushed the bboozzoo/sudo-workaround-strace-bad-output branch from 928f128 to f64af84 Compare January 26, 2024 15:43
@bboozzoo bboozzoo requested review from zyga and miguelpires January 29, 2024 08:16
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good. It is unfortunate we have to work around bugs in sudo, as we won't be able to drop the workaround anytime soon, but the approach taken now is a good balance between doing the right thing and not looking broken for users/developers.

Copy link
Contributor

@miguelpires miguelpires left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks

@bboozzoo
Copy link
Contributor Author

A bunch of unrelated failures in the tests. @pedronis @Meulengracht can you force merge?

@pedronis pedronis merged commit 4b0829f into canonical:master Jan 30, 2024
34 of 41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants