The return values are used in ways that assume they are positive.
In practice, it is not possible to have a negative return value
other than -1 due to the size of the buffers being read from or
written to. Also add overflow checks when updating the buffer len.
Quiets several coverity warnings.
We rely on the include path to find many of these headers. It
especially doesn't make sense to use #include "foo.h" for headers
in the top-level include directory.
We now pass a pointer to the context where necessary. There are a
few cases where we need to request the context from sudoers via
sudoers_get_context() for the plugin API functions. If the plugin
API was able to pass around a closure pointer this would not be
necessary.
This prevents visudo from creating a new zero-length sudoers file
if the user exited the editor without making any changes. Files
created via a @include directive are preserved, even if empty, to
avoid a parse error. GitHub issue #294.
The format value has to be a string literal, every time.
Otherwise, you are not using these functions correctly. To reinforce this fact, I putrestrict over every non-contrib example of this I could find.
The command is now always run in its own process group. If visudo
is run in the foreground, the command is run in the foreground too.
Otherwise, run the command in the background. There is a race
between the tcsetpgrp() call in the parent and the execve() in the
child. If we lose the race and the command needs the controlling
terminal, it will be stopped with SIGTTOU or SIGTTIN, which the
waitpid() loop will handle.
Since visudo doesn't alter the terminal settings it is possible for
the terminal to have the ONLCR bit set in the output control flags.
In that case, we will get a CR, not a NL when the user presses
enter/return. One way this can happen is if visudo is run in the
background from a shell that supports line editing and the editor
restores the (cbreak-style) terminal mode when it finishes.
We just need a way for the policy (and visudo) to override the
default sudoers path. This adds a getter to be used in file.c when
sudoers is first opened.
When adminconfdir is enabled, the destination pathh may be different
from the path we opened. We always store an edited file in the
adminconfdir (if enabled). This makes it possible to use visudo
when /etc/sudoers is located on a read-only file system.
Otherwise, visudo will get SIGTTOU if it tries to write to the
terminal after the editor finishes. Also avoid races by setting
the process group ID in both the parent and child, and grant the
controlling terminal in the parent, not the child.
We use "--" to separate the editor and arguments from the files to edit.
If the editor arguments include "--", sudo can be tricked into allowing
the user to edit a file not permitted by the security policy.
Thanks to Matthieu Barjole and Victor Cutillas of Synacktiv
(https://synacktiv.com) for finding this bug.