About setXattr and cxattr

I checked the /var/log/installer.log and found this after upgrading the initial installation of macOS High Sierra 10.13:

Begin script: setXattr
installd[610]: postinstall: Detected Seed Program Enrollement: DeveloperSeed in /Volumes/HSDPX/Users/Shared/.SeedEnrollment.plist
installd[610]: postinstall: /private/tmp/PKInstallSandbox.4ddTpG/Scripts/com.apple.pkg.InstallAssistantAuto.XPuvds/postinstall_actions/setXattr: line 22: ./Tools/cxattr: No such file or directory
installd[610]: postinstall: Failed to set xattr on: /Volumes/HSDPX/Applications/Install macOS High Sierra Beta.app
End script: setXattr

But no worries. High Sierra works just fine so that is not the problem. Still. I want to learn/know what is going on and where this error is coming from. I searched the backups that I made and found the script (setAttr) in InstallOSAuto.pkg Here it is:

#!/bin/bash

APP_BUNDLE_PATH="$3/Applications/Install macOS 10.13 Beta.app"
SEED_PROGRAM_KEY="SeedProgram"
SEED_PLIST="$3/Users/Shared/.SeedEnrollment.plist"
if [ $(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d '.' -f 1,2) == "10.9" ]; then
    SEED_PLIST="$3/Library/Application Support/App Store/.SeedEnrollment.plist"
fi

if [ ! -e "${SEED_PLIST}" ]; then
    echo "Seed Program Enrollement plist not found."
    exit 0
fi

SEED_PROGRAM=$(/usr/libexec/PlistBuddy -c "Print ${SEED_PROGRAM_KEY}" "${SEED_PLIST}")
if [ $? -ne "0" ]; then
    SEED_PROGRAM=0
fi

if [ "${SEED_PROGRAM}" != "0" ]; then
    echo "Detected Seed Program Enrollement: ${SEED_PROGRAM} in ${SEED_PLIST}"
    ./Tools/cxattr -w "${SEED_PROGRAM_KEY}" "${SEED_PROGRAM}" "${APP_BUNDLE_PATH}"
    if [ $? -ne "0" ]; then
        echo "Failed to set xattr on: ${APP_BUNDLE_PATH}"
    fi
else
    echo "Seed Program Enrollment not detected in ${SEED_PLIST}"
fi

What this script does, basically, is to set an attribute (SeedProgram) on the High Sierra installer app, and it does this like so for the BetaSeed:

./Tools/cxattr -w SeedProgram BetaSeed /Applications/Install\ macOS\ 10.13\ Beta.app

Here is the one for the DeveloperSeed:

./Tools/cxattr -w SeedProgram DeveloperSeed /Applications/Install\ macOS\ 10.13\ Beta.app

And here is the one for the CustomerSeed:

./Tools/cxattr -w SeedProgram CustomerSeed /Applications/Install\ macOS\ 10.13\ Beta.app

The cxattr tool is a compiled program but /usr/bin/xattr is just a Python script. Here it is:

#!/usr/bin/python

import sys, os
import glob, re

partA = """\
python version %d.%d.%d can't run %s.  Try the alternative(s):

"""
partB = """
Run "man python" for more information about multiple version support in
Mac OS X.
"""

sys.stderr.write(partA % (sys.version_info[:3] + (sys.argv[0],)))

dir, base = os.path.split(sys.argv[0])
specialcase = (base == 'python-config')
if specialcase:
    pat = "python*-config"
else:
    pat = base + '*'
g = glob.glob(os.path.join(dir, pat))
# match a single digit, dot and possibly multiple digits, because we might
# have 2to32.6, where the program is 2to3 and the version is 2.6.
vpat = re.compile("\d\.\d+")
n = 0
for i in g:
    vers = vpat.search(i)
    if vers is None:
	continue
    sys.stderr.write("%s (uses python %s)\n" % (i, i[vers.start():vers.end()]))
    n = 1
if n == 0:
    sys.stderr.write("(Error: no alternatives found)\n")

sys.stderr.write(partB)
sys.exit(1)

The good thing is that we don’t need the cxattr tool. No. We can also use: usr/bin/xattr:

xattr -w SeedProgram BetaSeed /Applications/Install\ macOS\ 10.13\ Beta.app

That is. After the installer is done – there is no Python during the installation phases. Anyway. You can list the attributes that are set with:

xattr -l /Applications/Install\ macOS\ 10.13\ Beta.app

Or you can do that with hexadecimal output:

xattr -lx /Applications/Install\ macOS\ 10.13\ Beta.app

Removing the SeedProgram attribute (or any other attribute that is set) can be done with:

xattr -d SeedProgram /Applications/Install\ macOS\ 10.13\ Beta.app

It seems that only the initial installer came with the cxattr tool. All later updates of High Sierra do not include the cxattr tool.

Ok. It’s not like we really need it, but I thought to share my findings with you here. Just in case you are wondering where that error is coming from 😉

Advertisement

SIP (System Integrity Protection) changes for High Sierra…

SIP (System Integrity Protection) in High Sierra has changed (extended).

I’m not going into much detail here, but you can take a look at the updated csrstat command line tool that I wrote earlier.

FYI: I implemented functional SIP support in bootloaders like RevoBoot, Chameleon/Enoch and the macosxbootloader. This a full month before anyone else wrote about it. After that I also shared my findings with Clover devs and Clover end-users so that they could set the correct values in their Clover.plist

I kept following the changes that Apple made, and figured out the meaning of CSR_ALLOW_DEVICE_CONFIGURATION and other important bits.

In fact. If I don’t blog about SIP changes, then they stay unnoticed. It seems. Seriously. Go Google for it 😉

p.s. I was made aware of a link in Chameleon/Enoch that shouldn’t be there, but that is not fair. Remember this guys. It was Pike who helped you with this, and nobody else!

Script to install macOS High Sierra DP-3 (17A306f)

I wrote a new handy script (install_1013_DP3_17A306f.sh) to install macOS High Sierra Beta DP-3 (the DeveloperSeed and BetaSeed use the same Apple download links).

The installer.pkg created by the script will simulate the App Store download and installation method and all you have to do is:

1.) Run script
2.) Launch installer.pkg
3.) Reboot

This procedure installed macOS High Sierra Beta DP-3 over a previously installed (broken) copy of macOS High Sierra DP-1. Worked for me. Please confirm.

Please note that the App Store.app downloads files to: /Library/Updates but the script uses: /tmp/ The files will be gone after a reboot, and thus you may want to make a backup of the files!

I also wrote a handy script (update_DP3_17A306f.sh) to update macOS Beta DP2-1 to DP3.

p.s. I don’t need to use the scripts to get macOS High Sierra Beta DP-3 installed because the installer from the App Store works as well.

Thanks!

Do I use APFS?

Yes and no. On my 2016 MacBook Pro with Touch Bar and Touch ID. Yes. Of course, but not on a hack. Absolutely not.

The reason for this is that APFS is developed for Apple hardware, with Apple firmware. Third party solid state media do not come with/support the Apple firmware, which will try to fix errors for you (think strong ECC) but that won’t happen on third party SSD’s. At least not in the same degree.

Many people will be sorry one day soon… and I am not going to be one of them. No thanks.

Let’s take cp as example. Blistering fast, but then again. it won’t actually copy the file. It’s more like a symbolic link (to some degree) and thus if a file is damaged… from a hardware point of view, then you are toast, since there is no way of telling that the content of that file didn’t change. This due to the lack of user data checksums.

Error in com.apple.touristd.sb

I noticed an error in the console that I wanted to stop showing up. It’s this one:

Failed to enter sandbox: /System/Library/Sandbox/Profiles/com.apple.touristd.sb:68:2: illegal argument: (allow iokit-open "RootDomainUserClient")

Note the last part.

(allow iokit-open "RootDomainUserClient")

That should read:

(allow iokit-open (iokit-user-client-class "RootDomainUserClient"))

I am rather surprised that nobody at Apple checked it.

AppleSMCRTC.kext panics…

Are you getting panics with some text about AppleSMCRTC.kext (adds support for boot argument rtc=0x03) and some dependancy failures for AppleSMC.kext (supports boot arguments smc= and smcdebug=0xf0) and AppleACPIPlatform.kext? Well. Someone asked me to look into this, and I did. Let’s start by showing you the ACPI device that Apple started to use (taken from the DSDT from the iMac19,1):

Device (ARTC)
{
	Name (_HID, "ACPI000E")
	Method (_GCP, 0, NotSerialized) // Get Capability (AppleACPIPlatform.kext)
	{
		// Bit [0] - 1 = AC wake implemented, 0 = not supported
		// Bit [1] - 1 = DC wake implemented, 0 = not supported
		// Bit [2] - 1 = Get/Set real time features implemented, 0 = not supported
		// Bit [3] - 1 = Real time accuracy in milliseconds, 0 = Real time accuracy in seconds
		// Bit [4] - 1 = _GWS returns correct values for wakes from S4/S5 caused by timer. 0 = not supported
		// Bit [5] to Bit [31] are reserved and must be 0.
		Return (0x05)
	}
	
	Method (_GRT, 0, Serialized) // Get Real Time (AppleACPIPlatform.kext)
	{
		Name (BUFF, Buffer (0x10) {})
		Store (^^EC.YRLB, Index (BUFF, Zero))
		Store (^^EC.YRMB, Index (BUFF, One))
		Store (^^EC.MNTH, Index (BUFF, 0x02))
		Store (^^EC.DAYB, Index (BUFF, 0x03))
		Store (^^EC.HOUR, Index (BUFF, 0x04))
		Store (^^EC.MINT, Index (BUFF, 0x05))
		Store (^^EC.SECD, Index (BUFF, 0x06))
		Store (^^EC.PAD0, Index (BUFF, 0x07))
		Store (^^EC.MSLB, Index (BUFF, 0x08))
		Store (^^EC.MSMB, Index (BUFF, 0x09))
		Store (^^EC.TZLB, Index (BUFF, 0x0A))
		Store (^^EC.TZMB, Index (BUFF, 0x0B))
		Store (^^EC.DAYL, Index (BUFF, 0x0C))
		Store (^^EC.PAD1, Index (BUFF, 0x0D))
		Store (^^EC.PAD2, Index (BUFF, 0x0E))
		Store (^^EC.PAD3, Index (BUFF, 0x0F))
		Return (BUFF)
	}
	
	Method (_SRT, 1, Serialized) // Set Real Time (AppleACPIPlatform.kext)
	{
		Store (Index (Arg0, Zero), ^^EC.YRLB)
		Store (Index (Arg0, One), ^^EC.YRMB)
		Store (Index (Arg0, 0x02), ^^EC.MNTH)
		Store (Index (Arg0, 0x03), ^^EC.DAYB)
		Store (Index (Arg0, 0x04), ^^EC.HOUR)
		Store (Index (Arg0, 0x05), ^^EC.MINT)
		Store (Index (Arg0, 0x06), ^^EC.SECD)
		Store (Index (Arg0, 0x08), ^^EC.MSLB)
		Store (Index (Arg0, 0x09), ^^EC.MSMB)
		Store (Index (Arg0, 0x0A), ^^EC.TZLB)
		Store (Index (Arg0, 0x0B), ^^EC.TZMB)
		Store (Index (Arg0, 0x0C), ^^EC.DAYL)
		Return (Zero)
	}
	
	Method (_STV, 2, Serialized) // Set Timer Value (AppleSMCRTC.kext)
	{
		Store (And (Arg1, 0xFF), ^^EC.ALR0)
		Store (And (ShiftRight (Arg1, 0x08), 0xFF), ^^EC.ALR1)
		Store (And (ShiftRight (Arg1, 0x10), 0xFF), ^^EC.ALR2)
		Store (And (ShiftRight (Arg1, 0x18), 0xFF), ^^EC.ALR3)
		Return (Zero)
	}
	
	Method (_CWS, 1, Serialized) // Clear Wake alarm status (AppleSMCRTC.kext)
	{
		Store (Zero, ^^EC.TMRF)
		Store (Zero, ^^EC.TMRW)
		Return (Zero)
	}
}

Our hacks do not have such device and thus AppleSMCRTC.kext will fail. What I did notice is that there was no problem when I used the prelinkedkernel, but when I tried to boot without a prelinkedkernel, and let RevoBoot load the individual kexts, then it failed to boot. A real Mac boots with the prelinkedkernel. Not by loading individual kexts. That explains why it works on a Mac.

The next thing I did was to run:

LZVN -d /System/Library/Prelinkedkernels/prelinkedkernel list

Low and behold. AppleSMC.kext is included. This despite the fact that the OSBundleRequired is set to “Safe Boot“. Hmm. Interesting.

Note: IOBluetoothHostControllerTransport.kext, IOBluetoothHostControllerUSBTransport.kext and IOBluetoothFamily.kext are three other kexts that are included in the prelinkedkernel – with OSBundleRequired set to “Safe Boot”.

This breaks the load of individual kexts, because then it won’t get loaded. Not if you boot without a prelinkedkernel. Which is what I do most of the time. Anyway. Adding a few lines of new code to RevoBoot worked around this problem (for me).

In short. It turned out that DP-2 was changed and as a result AppleSMC.kext no longer loads – on certain computers – due to the fact that the OSBundleRequired is set to “Safe Boot“. Changing it into “Root” solved the problem. As a workaround. Forcing it to load from the boot loader solved it – with the OSBundleRequired set to “Safe Boot”.

Note: The OSBundleRequired this did not change, but it no longer loads in High Sierra.

There may be other reasons that AppleSMC.kext isn’t loading, but you should try the work around. Or in case Chameleon or Clover – whichever boot loader you use – can force a kext to load. Then use that. You may also check your ACPI tabled for

Name (_HID, "ACPI000E")

because if you have that set on a different kind of device, which shouldn’t be the case, then that driver will try to load for the wrong kind of device 😉

Edit: The exact cause of the error will (hopefully) be documented later. My first thought is that the kextd (daemon) has changed, and now no longer loads the kexts that we need for our hardware. Apple may also have changed kextcache (command line tool) to make it include all kexts that are required, but I have yet to check this myself.

I also added a tiny SSDT, to inject the missing ACPI device, and used boot arguments rtc=0x03 and smcdebug=0xf0 to find the output of the kexts in the log.