SessionCreate doesn't seem to create a session; am I holding it wrong?

I'm doing this:


@import Security;

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        OSStatus result;
        SecuritySessionId sessionId;
        SessionAttributeBits attrs;
        result = SessionGetInfo(callerSecuritySession, &sessionId, &attrs);
        printf("Current session ID: %d\n", (int)sessionId);
        result = SessionCreate(0, 0);
        printf("This just happened: %d\n", (int)result);
        result = SessionGetInfo(callerSecuritySession, &sessionId, &attrs);
        printf("Later session ID: %d\n", (int)sessionId);
        const char *sessionString = getenv("SECURITYSESSIONID");
        printf("session from the env: %s\n", sessionString);
    }
    return 0;
}


My expectations are:


  1. SessionCreate() returns either errSessionSuccess, or one of the errors described in the header.
  2. The caller's security session identifier has changed between the two calls to SessionGetInfo().
  3. The security session identifier is written in hex to the environment (I'm looking at Authorization.cpp in Security-58286.220.15, which makes me believe this will happen).


Reality has served to disappoint me on all fronts. Here's what actually happens on 10.14.3:


Current session ID: 100008
This just happened: 100001
Later session ID: 100008
session from the env: (null)


Am I doing something incorrectly? My goal at the moment is simply to be able to create a new security session and enter it, leaving the session in which my process was launched.

Accepted Reply

Fair enough.

WARNING The following assumes that you’re just playing around. Do not try to ship a product based on anything discussed below.

Your approach to process isolation makes sense from a historical perspective, but it’s unlikely to yield useful results on a modern Apple system. The modern way to do process isolation is via the sandbox. The sandbox architecture has multiple layers:

  • Deep in the kernel, there’s a mandatory access control (MAC) mechanism that the sandbox plugs in to.

    This is not KPI (although, as noted in QA1574, the headers were in the public SDK for a long time) but most of the code is visible in Darwin.

  • The generic sandbox mechanism plugs into that. This supports a Scheme-like language for expressing sandbox constraints.

    This is so not API, although it’s fun to poke around in

    /usr/share/sandbox
    to see how it works (-:
  • Layered on top of that is the App Sandbox, which allows apps (and app-like things) to express their sandbox requirements in terms of entitlements.

    This is the only part of this stack that’s considered API. See the App Sandbox Design Guide for details.

Many built-in subsystems use the generic sandbox mechanism to implement a sandbox that’s customised for their needs. You can find echoes of this in the public SDK (for example,

sandbox_init
man page) and in Darwin. If you’re just playing around, you could pull on those threads and see where they lead you.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Security session management on macOS is complex, and the underlying implementation has changed a bunch of times since

SessionCreate
was introduced. Frankly, I’m unsurprised that this API isn’t doing what you want.

You wrote:

My goal at the moment is simply to be able to create a new security session and enter it, leaving the session in which my process was launched.

Can you explain more about the big picture here? What context are you using this from? And what high-level goal are you trying to achieve by starting a new security session?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks eskimo, my high-level goal is to pursue this exercise: given a disk image containing a filesystem, can I run an executable on that filesystem in a way that is isolated from the host operating system as much as possible? And, preferably, can I not need to be root to set up this isolated environment? This is an attempt to produce what is sometimes called a containerisation environment.


So what I _think_ I want to do is:


- attach my disk image

- chroot to its filesystem

- abandon any current authorization privileges*

- exec the target program


* is the point at which I want to create a new security session. There are other ways in which I think I could do the same (particularly, I could /bin/login -f), but I'm not _sure_ that they do the same, so I was exploring SessionCreate to see what it actually does.

Thanks for the details.

my high-level goal is to pursue this exercise

Is this as an academic exercise? Or is the ultimate goal to create a shipping product?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

the former, at least for the moment.

Fair enough.

WARNING The following assumes that you’re just playing around. Do not try to ship a product based on anything discussed below.

Your approach to process isolation makes sense from a historical perspective, but it’s unlikely to yield useful results on a modern Apple system. The modern way to do process isolation is via the sandbox. The sandbox architecture has multiple layers:

  • Deep in the kernel, there’s a mandatory access control (MAC) mechanism that the sandbox plugs in to.

    This is not KPI (although, as noted in QA1574, the headers were in the public SDK for a long time) but most of the code is visible in Darwin.

  • The generic sandbox mechanism plugs into that. This supports a Scheme-like language for expressing sandbox constraints.

    This is so not API, although it’s fun to poke around in

    /usr/share/sandbox
    to see how it works (-:
  • Layered on top of that is the App Sandbox, which allows apps (and app-like things) to express their sandbox requirements in terms of entitlements.

    This is the only part of this stack that’s considered API. See the App Sandbox Design Guide for details.

Many built-in subsystems use the generic sandbox mechanism to implement a sandbox that’s customised for their needs. You can find echoes of this in the public SDK (for example,

sandbox_init
man page) and in Darwin. If you’re just playing around, you could pull on those threads and see where they lead you.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"