-
Notifications
You must be signed in to change notification settings - Fork 4
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
Port to Darwin #95
Port to Darwin #95
Conversation
27f67aa
to
3109d20
Compare
Use raw syscalls to retrieve the command line under Darwin, since macOS does not provide a `/proc` filesystem. The code to do this is from https://github.com/elastic/go-sysinfo which can be sanity checked against: https://github.com/apple-oss-distributions/adv_cmds/blob/adv_cmds-205/ps/print.c#L115 I've verified with these changes that `pam_sshca.so` works as expected under macOS 13 (Ventura) on an arm64 host. Issues: 1. The Linux `pam.d/sudo` configuration line: "auth [success=done default=die] pam_sshca.so" Does not work on Darwin. Instead use one of the following: "auth requisite /path/to/pam_sshca.so" Or: "auth required /path/to/pam_sshca.so" Neither is identical to `[success=done default=die]` whose semantics are impossible under Darwin. See the `pam.conf` man pages on Linux and macOS for details. 2. The `log/syslog` module does not work under macOS >= 12 (Monterey). Log messages are silently dropped: golang/go#59229 3. The `kern.procargs2` syscall returns incorrect data under macOS 10.15 (Catalina) due to a bug in that OS version. The code won't panic under that OS version but it won't return a command line: elastic/go-sysinfo#172
3109d20
to
200accc
Compare
|
||
var unknownCommand = []byte("unknown command") | ||
|
||
func getCmdLine() []byte { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does os.Args
not work to obtain the command line arguments because this is a shared object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I believe the intention here was to log the actual command that was run under "sudo" when static keys were used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@psasidhar is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs some coding style change to follow the project standard. Can be done as a follow up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add unit tests wherever possible?
// sysctl returns "invalid argument" for both "no such process" | ||
// and "operation not permitted" errors. | ||
msg.Printlf(msg.WARN, "No such process or operation not permitted: %w", err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we log the error when it is not an "invalid argument" error?
// exe | ||
lines := strings.Split(string(data), "\x00") | ||
exe := lines[0] | ||
lines = lines[1:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we do a length check for lines
?
data = data[4:] | ||
|
||
// exe | ||
lines := strings.Split(string(data), "\x00") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: since we need to return a byte slice, can we use bytes.Split
and keep everything in a byte slice?
} else if len(cmd) == 0 { | ||
cmd = []byte("empty command") | ||
msg.Printlf(msg.WARN, "/proc/%d/cmdline is empty", os.Getpid()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we do an early return here and after line 17 to keep things consistent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
cmd = cmd[:len(cmd)-1] | ||
// Replace '\0' with ' '. | ||
cmd = bytes.Replace(cmd, []byte{0}, []byte{' '}, -1) | ||
cmd := getCmdLine() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we pass os.Getpid()
as a param to getCmdLine()
?
) | ||
|
||
func getCmdLine() []byte { | ||
cmd, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", os.Getpid())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use https://pkg.go.dev/os#ReadFile instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied from pam_sshca.go
and I didn't want to change anything.
Let's address the comments in a follow-up PR |
Use raw syscalls to retrieve the command line under Darwin, since macOS
does not provide a
/proc
filesystem.The code to do this is from https://github.com/elastic/go-sysinfo which
can be sanity checked against:
https://github.com/apple-oss-distributions/adv_cmds/blob/adv_cmds-205/ps/print.c#L115
I've verified with these changes that
pam_sshca.so
works as expectedunder macOS 13 (Ventura) on an arm64 host.
Issues:
The Linux
pam.d/sudo
configuration line:Does not work on Darwin. Instead use one of the following:
Or:
Neither is identical to
[success=done default=die]
whosesemantics are impossible under Darwin. See the
pam.conf
man pageson Linux and macOS for details.
The
log/syslog
module does not work under macOS >= 12 (Monterey).Log messages are silently dropped:
log/syslog: local messages (syslog.New()) do not work on macOS Monterey/Ventura golang/go#59229
The
kern.procargs2
syscall returns incorrect data under macOS10.15 (Catalina) due to a bug in that OS version. The code won't
panic under that OS version but it won't return a command line:
providers/darwin - kern.procargs2 guard against runtime panic elastic/go-sysinfo#172