Commit | Line | Data |
---|---|---|
5ba3f43e A |
1 | #!/bin/bash |
2 | ||
3 | # | |
4 | # kasan_install: set up a system to run the KASan kernel. Run with "--uninstall" | |
5 | # to reverse the setup. | |
6 | # | |
7 | # Installs a symlink to the kernel kasan in /System/Library/Kernels/kernel.kasan | |
8 | # and adds kcsuffix=kasan to boot-args. | |
9 | # | |
10 | ||
11 | ||
12 | kernel_name=kernel.kasan | |
13 | kernel_src=/AppleInternal/CoreOS/xnu_kasan/${kernel_name} | |
14 | SLK=/System/Library/Kernels/ | |
15 | kernel_dst=${SLK}${kernel_name} | |
16 | ||
17 | if [[ `whoami` != root ]] ; then | |
18 | echo "Re-running with sudo" | |
19 | sudo "$0" "$@" | |
20 | exit $? | |
21 | fi | |
22 | ||
23 | sip_enabled() { | |
24 | csrutil status |grep -q enabled | |
25 | } | |
26 | ||
27 | prompt() { | |
28 | echo -n "$@ [y/N] " | |
29 | read ans | |
30 | case "$ans" in | |
31 | [yY]*) return 0 ;; | |
32 | *) return 1 ;; | |
33 | esac | |
34 | } | |
35 | ||
36 | kasan_install() { | |
37 | ||
38 | dosymlink=0 | |
39 | dobootargs=0 | |
40 | ||
41 | if [[ ! -f $kernel_src ]] ; then | |
42 | echo "No KASan kernel found at $kernel_src" | |
43 | exit 1 | |
44 | fi | |
45 | ||
46 | echo -n "Installing KASan kernel... " | |
47 | ||
48 | if [[ -L $kernel_dst && $kernel_dst -ef $kernel_src ]] ; then | |
49 | echo "already installed." | |
50 | elif [[ -f $kernel_dst ]] ; then | |
51 | prompt "file exists. Overwrite?" && { | |
52 | echo -n "Overwriting KASan kernel... " | |
53 | dosymlink=1 | |
54 | } | |
55 | else | |
56 | dosymlink=1 | |
57 | fi | |
58 | ||
59 | # Use a temporary directory with a symlink to kernel.kasan. We can ditto | |
60 | # from there into /S/L/K, even with SIP enabled. | |
61 | [[ $dosymlink -eq 1 ]] && { | |
62 | tmp=$(mktemp -d) || exit $? | |
63 | ln -s "$kernel_src" "$tmp" || exit $? | |
64 | ditto "$tmp" "$SLK" || exit $? | |
65 | rm -r "$tmp" | |
66 | echo "done." | |
67 | } | |
68 | ||
69 | ||
70 | echo -n "Checking KASan boot args... " | |
71 | ||
72 | bootargs=$(nvram boot-args | cut -f2) | |
73 | cursuffix=$(echo $bootargs | sed -n 's/.*kcsuffix=\([^ ]\)/\1/p') | |
74 | ||
75 | if [[ "$cursuffix" == kasan ]] ; then | |
76 | echo "already set." | |
77 | elif [[ -n "$cursuffix" ]] ; then | |
78 | prompt "custom kcsuffix ($cursuffix) is set. Overwrite?" && { | |
79 | bootargs=$(echo "$bootargs" | sed 's/[ ]*kcsuffix=[^ ]*//') | |
80 | dobootargs=1 | |
81 | } | |
82 | else | |
83 | prompt "not set. Modify?" && { | |
84 | dobootargs=1 | |
85 | } | |
86 | fi | |
87 | ||
88 | [[ $dobootargs -eq 1 ]] && { | |
89 | echo -n "Adding boot arg kcsuffix=kasan... " | |
90 | newlen=$(echo -n "$bootargs kcsuffix=kasan" |wc -c) | |
91 | if [[ $newlen -ge 512 ]] ; then | |
92 | echo "boot-args too long. Bailing." | |
93 | exit 3 | |
94 | fi | |
95 | ||
96 | nvram boot-args="$bootargs kcsuffix=kasan" || exit $? | |
97 | echo "done." | |
98 | } | |
99 | ||
100 | [[ $dosymlink -eq 1 ]] && { | |
101 | echo -n "Triggering kernel cache rebuild... " | |
102 | touch /System/Library/Extensions || exit $? | |
103 | echo "done." | |
104 | } | |
105 | ||
106 | } | |
107 | ||
108 | ||
109 | kasan_uninstall() { | |
110 | ||
111 | echo -n "Removing kasan kernel... " | |
112 | ||
113 | dorm=0 | |
114 | ||
115 | if [[ -L $kernel_dst && $kernel_dst -ef $kernel_src ]] ; then | |
116 | dorm=1 | |
117 | elif [[ -f $kernel_dst ]] ; then | |
118 | prompt "unexpected file. Remove anyway?" && { | |
119 | dorm=1 | |
120 | } | |
121 | else | |
122 | echo "not installed." | |
123 | fi | |
124 | ||
125 | [[ $dorm -eq 1 ]] && { | |
126 | if rm "$kernel_dst" ; then | |
127 | echo "done." | |
128 | else | |
129 | if sip_enabled ; then | |
130 | echo "failed due to SIP - this is normal." | |
131 | fi | |
132 | fi | |
133 | } | |
134 | ||
135 | ||
136 | echo -n "Removing boot args... " | |
137 | ||
138 | bootargs=$(nvram boot-args | cut -f2) | |
139 | cursuffix=$(echo $bootargs | sed -n 's/.*kcsuffix=\([^ ]\)/\1/p') | |
140 | ||
141 | if [[ $cursuffix == "kasan" ]] ; then | |
142 | prompt "remove kcsuffix=kasan?" && { | |
143 | echo -n "Removing kcsuffix... " | |
144 | bootargs=$(echo "$bootargs" | sed 's/[ ]*kcsuffix=[^ ]*//') | |
145 | nvram boot-args="$bootargs" | |
146 | echo "done." | |
147 | } | |
148 | else | |
149 | echo "not set." | |
150 | fi | |
151 | ||
152 | } | |
153 | ||
154 | case "$1" in | |
155 | *uninstall|*del*|*remove|*rm) | |
156 | kasan_uninstall ;; | |
157 | *) | |
158 | kasan_install ;; | |
159 | esac |