Skip to content

Commit 446fe46

Browse files
authored
Limit KeyctlString() to DESCRIBE / GET_SECURITY
KeyctlString() treats the query data buffer filled by the keyctl(2) syscall as C-Style string with a trailing NULL byte. This is only true for two cmds - KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY. Both are guaranteed to return at least an empty (C) string (i.e. a one-byte-sized buffer containing only a NULL byte) if the requested attribute is not set at all. Other cmds that can be passed to the system call - KEYCTL_READ most prominently - return explicitly-sized binary data; NULL bytes have no special meaning for these queries and are _part_ of the returned data, irrespective of where in the buffer they occur. Returning nothing (zero-length) can also be permitted; example of this is a KEYCTL_READ on an empty keyring. If KeyctlString() is called with any of the keyctl(2) query commands other than the two that are guaranteed to return C-style strings, it will either: * panic (attempting to strip trailing null bytes from zero-sized buffers), or * truncate the returned data in error (for KEYCTL_READ of a key payload). Therefore, restrict the use.
1 parent 2296e01 commit 446fe46

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

unix/syscall_linux.go

+7
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,13 @@ func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {
13811381
// KeyctlString calls keyctl commands which return a string.
13821382
// These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY.
13831383
func KeyctlString(cmd int, id int) (string, error) {
1384+
// Other queries - particularly KEYCTL_READ - can either return zero-length data,
1385+
// or explicitly-sized buffers of binary data (which may include NULL bytes).
1386+
// This function misbehaves then (panics or truncates returns), so explicitly
1387+
// allow only the two cmds documented to return NUL-terminated (C-type) strings.
1388+
if cmd != unix.KEYCTL_DESCRIBE || cmd != unix.KEYCTL_GET_SECURITY {
1389+
return "", EINVAL
1390+
}
13841391
// We must loop as the string data may change in between the syscalls.
13851392
// We could allocate a large buffer here to reduce the chance that the
13861393
// syscall needs to be called twice; however, this is unnecessary as

0 commit comments

Comments
 (0)