changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > infra / scripts/get-linux.sh

changeset 371: 7dcabf3e0edc
parent: 989b1b4782dc
author: Richard Westhaver <ellis@rwest.io>
date: Tue, 24 Sep 2024 15:53:24 -0400
permissions: -rwxr-xr-x
description: no link in bootstrap.sh
1 #!/usr/bin/env bash
2 # get-linux
3 
4 # from https://git.kernel.org/pub/scm/linux/kernel/git/mricon/korg-helpers.git/tree/get-verified-tarball
5 
6 # there are minimal modifications to this script - be careful, it
7 # pulls from the upstream kernel source archives.
8 
9 # --------------------
10 # Get Linux kernel tarball and cryptographically verify it,
11 # retrieving the PGP keys using the Web Key Directory (WKD)
12 # protocol if they are not already in the keyring.
13 #
14 # Pass the kernel version as the only parameter, or
15 # we'll grab the latest stable kernel.
16 #
17 # Example: ./get-linux 4.4.145
18 #
19 # Configurable parameters
20 # -----------------------
21 # What kernel version do you want?
22 HOST_VER=$(uname -r | cut -d- -f1)
23 VER="${1:-$HOST_VER}"
24 
25 # Where to download the tarball and verification data.
26 TARGETDIR=${2:-.stash/src/linux-$VER}
27 
28 # For CI and other automated infrastructure, you may want to
29 # create a keyring containing the keys belonging to:
30 # - autosigner@kernel.org
31 # - torvalds@kernel.org
32 # - gregkh@kernel.org
33 #
34 # To generate the keyring with these keys, do:
35 # gpg --export autosigner@ torvalds@ gregkh@ > keyring.gpg
36 # (or use full keyids for maximum certainty)
37 #
38 # Once you have keyring.gpg, install it on your CI system and set
39 # USEKEYRING to the full path to it. If unset, we generate our own
40 # from GNUPGHOME.
41 # need to run make linux-keys first
42 USEKEYRING=${3}
43 
44 # If you set this to empty value, we'll make a temporary
45 # directory and fetch the verification keys from the
46 # Web Key Directory each time. Also, see the USEKEYRING=
47 # configuration option for an alternative that doesn't
48 # rely on WKD.
49 GNUPGHOME="$HOME/.gnupg"
50 
51 # Point this at your GnuPG binary version 2.1.11 or above.
52 # If you are using USEKEYRING, GnuPG-1 will work, too.
53 GPGBIN="/usr/bin/gpg2"
54 GPGVBIN="/usr/bin/gpgv2"
55 # We need a compatible version of sha256sum, too
56 SHA256SUMBIN="/usr/bin/sha256sum"
57 # And curl
58 CURLBIN="/usr/bin/curl"
59 # And we need the xz binary
60 XZBIN="/usr/bin/xz"
61 
62 # You shouldn't need to modify this, unless someone
63 # other than Linus or Greg start releasing kernels.
64 DEVKEYS="torvalds@kernel.org gregkh@kernel.org"
65 # Don't add this to DEVKEYS, as it plays a wholly
66 # different role and is NOT a key that should be used
67 # to verify kernel tarball signatures (just the checksums).
68 SHAKEYS="autosigner@kernel.org"
69 
70 if [[ -z ${VER} ]]; then
71  # Assume you want the latest stable
72  VER=$(${CURLBIN} -sL https://www.kernel.org/finger_banner \
73  | grep 'latest stable version' \
74  | awk -F: '{gsub(/ /,"", $0); print $2}')
75 fi
76 if [[ -z ${VER} ]]; then
77  echo "Could not figure out the latest stable version."
78  exit 1
79 fi
80 
81 MAJOR="$(echo ${VER} | cut -d. -f1)"
82 if [[ ${MAJOR} -lt 3 ]]; then
83  echo "This script only supports kernel v3.x.x and above"
84  exit 1
85 fi
86 
87 if [[ ! -d ${TARGETDIR} ]]; then
88  echo "${TARGETDIR} does not exist"
89  exit 1
90 fi
91 
92 TARGET="${TARGETDIR}/linux-${VER}.tar.xz"
93 # Do we already have this file?
94 if [[ -f ${TARGET} ]]; then
95  echo "File ${TARGETDIR}/linux-${VER}.tar.xz already exists."
96  exit 0
97 fi
98 
99 # Start by making sure our GnuPG environment is sane
100 if [[ ! -x ${GPGBIN} ]]; then
101  echo "Could not find gpg in ${GPGBIN}"
102  exit 1
103 fi
104 if [[ ! -x ${GPGVBIN} ]]; then
105  echo "Could not find gpgv in ${GPGVBIN}"
106  exit 1
107 fi
108 
109 # NOTE 2023-11-19: we make a folder in /tmp/ due to a strange bug
110 # encountered when using the TARGETDIR. Need to test on
111 TMPDIR=$(mktemp -d)
112 echo "Using TMPDIR=${TMPDIR}"
113 # Are we using a keyring?
114 if [[ -z ${USEKEYRING} ]]; then
115  if [[ -z ${GNUPGHOME} ]]; then
116  GNUPGHOME="${TMPDIR}/gnupg"
117  elif [[ ! -d ${GNUPGHOME} ]]; then
118  echo "GNUPGHOME directory ${GNUPGHOME} does not exist"
119  echo -n "Create it? [Y/n]"
120  read YN
121  if [[ ${YN} == 'n' ]]; then
122  echo "Exiting"
123  rm -rf ${TMPDIR}
124  exit 1
125  fi
126  fi
127  mkdir -p -m 0700 ${GNUPGHOME}
128  echo "Making sure we have all the necessary keys"
129  ${GPGBIN} --batch --quiet \
130  --homedir ${GNUPGHOME} \
131  --auto-key-locate wkd \
132  --locate-keys ${DEVKEYS} ${SHAKEYS}
133  # If this returned non-0, we bail
134  if [[ $? != "0" ]]; then
135  echo "Something went wrong fetching keys"
136  rm -rf ${TMPDIR}
137  exit 1
138  fi
139  # Make a temporary keyring and set USEKEYRING to it
140  USEKEYRING=${TMPDIR}/keyring.gpg
141  ${GPGBIN} --batch --export ${DEVKEYS} ${SHAKEYS} > ${USEKEYRING}
142 fi
143 # Now we make two keyrings -- one for the autosigner, and
144 # the other for kernel developers. We do this in order to
145 # make sure that we never verify kernel tarballs using the
146 # autosigner keys, only using developer keys.
147 SHAKEYRING=${TMPDIR}/shakeyring.gpg
148 ${GPGBIN} --batch \
149  --no-default-keyring --keyring ${USEKEYRING} \
150  --export ${SHAKEYS} > ${SHAKEYRING}
151 DEVKEYRING=${TMPDIR}/devkeyring.gpg
152 ${GPGBIN} --batch \
153  --no-default-keyring --keyring ${USEKEYRING} \
154  --export ${DEVKEYS} > ${DEVKEYRING}
155 
156 # Now that we know we can verify them, grab the contents
157 TXZ="https://cdn.kernel.org/pub/linux/kernel/v${MAJOR}.x/linux-${VER}.tar.xz"
158 SIG="https://cdn.kernel.org/pub/linux/kernel/v${MAJOR}.x/linux-${VER}.tar.sign"
159 SHA="https://www.kernel.org/pub/linux/kernel/v${MAJOR}.x/sha256sums.asc"
160 
161 # Before we verify the developer signature, we make sure that the
162 # tarball matches what is on the kernel.org master. This avoids
163 # CDN cache poisoning that could, in theory, use vulnerabilities in
164 # the XZ binary to alter the verification process or compromise the
165 # system performing the verification.
166 SHAFILE=${TMPDIR}/sha256sums.asc
167 echo "Downloading the checksums file for linux-${VER}"
168 if ! ${CURLBIN} -sL -o ${SHAFILE} ${SHA}; then
169  echo "Failed to download the checksums file"
170  rm -rf ${TMPDIR}
171  exit 1
172 fi
173 echo "Verifying the checksums file"
174 COUNT=$(${GPGVBIN} --keyring=${SHAKEYRING} --status-fd=1 ${SHAFILE} \
175  | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)')
176 if [[ ${COUNT} -lt 2 ]]; then
177  echo "FAILED to verify the sha256sums.asc file."
178  rm -rf ${TMPDIR}
179  exit 1
180 fi
181 # Grab only the tarball we want from the full list
182 SHACHECK=${TMPDIR}/sha256sums.txt
183 grep "linux-${VER}.tar.xz" ${SHAFILE} > ${SHACHECK}
184 
185 echo
186 echo "Downloading the signature file for linux-${VER}"
187 SIGFILE=${TMPDIR}/linux-${VER}.tar.asc
188 if ! ${CURLBIN} -sL -o ${SIGFILE} ${SIG}; then
189  echo "Failed to download the signature file"
190  rm -rf ${TMPDIR}
191  exit 1
192 fi
193 echo "Downloading the XZ tarball for linux-${VER}"
194 TXZFILE=${TMPDIR}/linux-${VER}.tar.xz
195 if ! ${CURLBIN} -L -o ${TXZFILE} ${TXZ}; then
196  echo "Failed to download the tarball"
197  rm -rf ${TMPDIR}
198  exit 1
199 fi
200 
201 pushd ${TMPDIR} >/dev/null
202 echo "Verifying checksum on linux-${VER}.tar.xz"
203 if ! ${SHA256SUMBIN} -c ${SHACHECK}; then
204  echo "FAILED to verify the downloaded tarball checksum"
205  popd >/dev/null
206  rm -rf ${TMPDIR}
207  exit 1
208 fi
209 popd >/dev/null
210 
211 echo
212 echo "Verifying developer signature on the tarball"
213 COUNT=$(${XZBIN} -cd ${TXZFILE} \
214  | ${GPGVBIN} --keyring=${DEVKEYRING} --status-fd=1 ${SIGFILE} - \
215  | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)')
216 if [[ ${COUNT} -lt 2 ]]; then
217  echo "FAILED to verify the tarball!"
218  rm -rf ${TMPDIR}
219  exit 1
220 fi
221 mv -f ${TXZFILE} ${TARGET}
222 rm -rf ${TMPDIR}
223 echo
224 echo "Successfully downloaded and verified ${TARGET}"