#!/bin/bash
kernel_name=kernel.kasan
kernel_src=/AppleInternal/CoreOS/xnu_kasan/${kernel_name}
SLK=/System/Library/Kernels/
kernel_dst=${SLK}${kernel_name}
if [[ `whoami` != root ]] ; then
echo "Re-running with sudo"
sudo "$0" "$@"
exit $?
fi
sip_enabled() {
csrutil status |grep -q enabled
}
prompt() {
echo -n "$@ [y/N] "
read ans
case "$ans" in
[yY]*) return 0 ;;
*) return 1 ;;
esac
}
kasan_install() {
dosymlink=0
dobootargs=0
if [[ ! -f $kernel_src ]] ; then
echo "No KASan kernel found at $kernel_src"
exit 1
fi
echo -n "Installing KASan kernel... "
if [[ -L $kernel_dst && $kernel_dst -ef $kernel_src ]] ; then
echo "already installed."
elif [[ -f $kernel_dst ]] ; then
prompt "file exists. Overwrite?" && {
echo -n "Overwriting KASan kernel... "
dosymlink=1
}
else
dosymlink=1
fi
[[ $dosymlink -eq 1 ]] && {
tmp=$(mktemp -d) || exit $?
ln -s "$kernel_src" "$tmp" || exit $?
ditto "$tmp" "$SLK" || exit $?
rm -r "$tmp"
echo "done."
}
echo -n "Checking KASan boot args... "
bootargs=$(nvram boot-args | cut -f2)
cursuffix=$(echo $bootargs | sed -n 's/.*kcsuffix=\([^ ]\)/\1/p')
if [[ "$cursuffix" == kasan ]] ; then
echo "already set."
elif [[ -n "$cursuffix" ]] ; then
prompt "custom kcsuffix ($cursuffix) is set. Overwrite?" && {
bootargs=$(echo "$bootargs" | sed 's/[ ]*kcsuffix=[^ ]*//')
dobootargs=1
}
else
prompt "not set. Modify?" && {
dobootargs=1
}
fi
[[ $dobootargs -eq 1 ]] && {
echo -n "Adding boot arg kcsuffix=kasan... "
newlen=$(echo -n "$bootargs kcsuffix=kasan" |wc -c)
if [[ $newlen -ge 512 ]] ; then
echo "boot-args too long. Bailing."
exit 3
fi
nvram boot-args="$bootargs kcsuffix=kasan" || exit $?
echo "done."
}
[[ $dosymlink -eq 1 ]] && {
echo -n "Triggering kernel cache rebuild... "
touch /System/Library/Extensions || exit $?
echo "done."
}
}
kasan_uninstall() {
echo -n "Removing kasan kernel... "
dorm=0
if [[ -L $kernel_dst && $kernel_dst -ef $kernel_src ]] ; then
dorm=1
elif [[ -f $kernel_dst ]] ; then
prompt "unexpected file. Remove anyway?" && {
dorm=1
}
else
echo "not installed."
fi
[[ $dorm -eq 1 ]] && {
if rm "$kernel_dst" ; then
echo "done."
else
if sip_enabled ; then
echo "failed due to SIP - this is normal."
fi
fi
}
echo -n "Removing boot args... "
bootargs=$(nvram boot-args | cut -f2)
cursuffix=$(echo $bootargs | sed -n 's/.*kcsuffix=\([^ ]\)/\1/p')
if [[ $cursuffix == "kasan" ]] ; then
prompt "remove kcsuffix=kasan?" && {
echo -n "Removing kcsuffix... "
bootargs=$(echo "$bootargs" | sed 's/[ ]*kcsuffix=[^ ]*//')
nvram boot-args="$bootargs"
echo "done."
}
else
echo "not set."
fi
}
case "$1" in
*uninstall|*del*|*remove|*rm)
kasan_uninstall ;;
*)
kasan_install ;;
esac