Endpoint security: Process environment variable crash

I'm attempting to extract the environment variables from an es_event_exec_t using the provided es_exec_env() function, but when I attempt to do this for certain processes my security extension seems to crash:

Code Type:             ARM-64 (Native)
Parent Process:        launchd [1]
User ID:               0
OS Version:            macOS 13.1 (22C65)

System Integrity Protection: disabled

Crashed Thread:        0  Dispatch queue: BBReaderQueue

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000

Thread 0 Crashed::  Dispatch queue: BBReaderQueue
0   libsystem_kernel.dylib        	       0x1938961b0 __pthread_kill + 8
1   libsystem_pthread.dylib       	       0x1938cccec pthread_kill + 288
2   libsystem_c.dylib             	       0x1938062c8 abort + 180
3   libsystem_c.dylib             	       0x193805620 __assert_rtn + 272
4   libEndpointSecurity.dylib     	       0x1a5518078 es_exec_env.cold.1 + 44
5   libEndpointSecurity.dylib     	       0x1a5515bf4 es_exec_env + 48
6   ESFramework              	       0x1015b443c parseExecEnvVars(event:) + 3084 (ExecEvent.swift:172)

Any ideas on what might be going wrong or where I might be able to start? I'm able to reproduce the problem by executing iTerm2.app which kicks off iTermServer-3.4.19 causing the crash.

Here's the basic program flow:

  • Receive incoming es_message_t and if it's an exec event
  • Create a new struct to model the exec event:
public struct ExecEvent: Identifiable, Codable, Hashable {
    public var id: UUID = UUID()
    public var process_path, env_variables: String?
    init(fromRawEvent rawEvent: UnsafePointer<es_message_t>) {
        es_retain_message(rawEvent)
        var execEvent: es_event_exec_t = rawEvent.pointee.event.exec
        self.process_path = String(cString: execEvent.target.pointee.executable.pointee.path.data)

        // MARK: Parse environment variables. Crashes for certain procs like `iTermServer-3.4.19`.
        self.env_variables = parseExecEnvVars(event: &execEvent)

        es_release_message(rawEvent)
    }
}

To grab the environment variables

public func parseExecEnvVars(event: inout es_event_exec_t) -> String {
    let numberOfVars: Int = Int(es_exec_arg_count(&event))
    let procPath: String = String(cString: event.target.pointee.executable.pointee.path.data)
    os_log("Path: \(procPath) --> has \(numberOfVars) env vars")

    var envVars: [String] = []
    for index in 0..<numberOfVars {
        let envVarVar: String = String(cString: es_exec_env(&event, UInt32(index)).data)
        os_log("#\(index): \(envVarVar)")
        envVars.append(envVarVar)
    }
    return envVars.joined(separator: "\n")
}
Answered by DTS Engineer in 741895022
let numberOfVars: Int = Int(es_exec_arg_count(&event))

Isn’t that supposed to be es_exec_env_count?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer
let numberOfVars: Int = Int(es_exec_arg_count(&event))

Isn’t that supposed to be es_exec_env_count?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Endpoint security: Process environment variable crash
 
 
Q