diff --git a/.pipelines/containerSourceData/kubevirt/Dockerfile-kubevirt-virt-launcher b/.pipelines/containerSourceData/kubevirt/Dockerfile-kubevirt-virt-launcher
index 18f51d905ad..16d29e35b28 100644
--- a/.pipelines/containerSourceData/kubevirt/Dockerfile-kubevirt-virt-launcher
+++ b/.pipelines/containerSourceData/kubevirt/Dockerfile-kubevirt-virt-launcher
@@ -7,11 +7,6 @@ FROM $BASE_IMAGE
@INCLUDE_MAIN_RUN_INSTRUCTION@
-# XXX Once edk2 is moved to SPECS this will not be needed
-RUN tdnf -y install azurelinux-repos-extended.noarch \
- && tdnf -y install edk2-ovmf \
- && tdnf clean all
-
# Setup permissions and capabilities for non-root VMIs. KubeVirt sets
# XDG_* directories to /var/run.
RUN cd /var && rm -rf run && ln -s ../run . \
diff --git a/.pipelines/containerSourceData/kubevirt/virt-launcher.pkg b/.pipelines/containerSourceData/kubevirt/virt-launcher.pkg
index d6cfdfdef22..11775c0ba0e 100644
--- a/.pipelines/containerSourceData/kubevirt/virt-launcher.pkg
+++ b/.pipelines/containerSourceData/kubevirt/virt-launcher.pkg
@@ -1,5 +1,6 @@
augeas
ca-certificates
+edk2-ovmf
iptables
kubevirt-container-disk
kubevirt-virt-launcher
diff --git a/.pipelines/containerSourceData/memcached/Dockerfile-Memcached b/.pipelines/containerSourceData/memcached/Dockerfile-Memcached
index 26a0f496a7a..a756b4a8e57 100644
--- a/.pipelines/containerSourceData/memcached/Dockerfile-Memcached
+++ b/.pipelines/containerSourceData/memcached/Dockerfile-Memcached
@@ -7,7 +7,7 @@ FROM $BASE_IMAGE
@INCLUDE_MAIN_RUN_INSTRUCTION@
-RUN useradd memcache
+RUN tdnf install -y shadow-utils && useradd memcache && tdnf remove -y shadow-utils && tdnf clean all
USER memcache
diff --git a/.pipelines/containerSourceData/multus/Dockerfile-Multus b/.pipelines/containerSourceData/multus/Dockerfile-Multus
index 1f379ffaddb..4b52a3fbd75 100644
--- a/.pipelines/containerSourceData/multus/Dockerfile-Multus
+++ b/.pipelines/containerSourceData/multus/Dockerfile-Multus
@@ -11,7 +11,6 @@ RUN ln -s /usr/bin/python3 /usr/bin/python
RUN mkdir -p /usr/src/multus-cni/bin \
&& cp /usr/bin/multus /usr/src/multus-cni/bin/ \
- && cp /usr/bin/install_multus /install_multus \
- && cp /usr/bin/thin_entrypoint /thin_entrypoint
+ && cp /usr/bin/multus-entrypoint /multus-entrypoint
-ENTRYPOINT [ "/thin_entrypoint" ]
+ENTRYPOINT [ "/multus-entrypoint" ]
diff --git a/.pipelines/containerSourceData/nodejs/distroless/nodejs.pkg b/.pipelines/containerSourceData/nodejs/distroless/nodejs.pkg
index a3dd92d9c6e..331605e8f16 100644
--- a/.pipelines/containerSourceData/nodejs/distroless/nodejs.pkg
+++ b/.pipelines/containerSourceData/nodejs/distroless/nodejs.pkg
@@ -1,3 +1,4 @@
distroless-packages-base
nodejs
+nodejs-npm
prebuilt-ca-certificates
diff --git a/.pipelines/containerSourceData/nodejs/nodejs.pkg b/.pipelines/containerSourceData/nodejs/nodejs.pkg
index 54515b67eee..5d0b9374c8c 100644
--- a/.pipelines/containerSourceData/nodejs/nodejs.pkg
+++ b/.pipelines/containerSourceData/nodejs/nodejs.pkg
@@ -1,2 +1,3 @@
ca-certificates
nodejs
+nodejs-npm
diff --git a/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md b/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md
index 34333b9711e..e6f4b0a8053 100644
--- a/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md
+++ b/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md
@@ -5,7 +5,7 @@ The Azure Linux SPEC files originated from a variety of sources with varying lic
| CentOS | [MIT](https://www.centos.org/legal/#licensing-policy) | crash-ptdump-command
delve
fstrm
nodejs-nodemon
rhnlib
rt-setup
rt-tests
rtctl
tuned |
| Ceph source | [LGPL2.1](https://github.com/ceph/ceph/blob/master/COPYING-LGPL2.1) | ceph |
| Debian | [MIT](https://opensource.org/licenses/MIT) | prometheus-process-exporter |
-| Fedora | [Fedora MIT License Declaration](https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#License_of_Fedora_SPEC_Files) | a52dec
abseil-cpp
accountsservice
acpica-tools
acpid
adcli
adobe-mappings-cmap
adobe-mappings-pdf
advancecomp
adwaita-icon-theme
afflib
aide
alsa-firmware
alsa-plugins
amtk
amtterm
annobin
ansible-freeipa
archivemount
argparse-manpage
arptables
arpwatch
asio
aspell
aspell-en
at
at-spi2-atk
at-spi2-core
atf
atk
atop
attr
audiofile
augeas
authbind
authd
authselect
autoconf213
avahi
babeltrace
babeltrace2
babl
baekmuk-ttf-fonts
bats
bcache-tools
biosdevname
blosc
bluez
bmake
bogofilter
bolt
boom-boot
booth
botan2
breezy
brotli
buildah
busybox
bwidget
byacc
ca-certificates
cachefilesd
cairomm
calamares
capstone
catatonit
catch
catch1
cdrdao
celt051
cereal
certmonger
cfitsio
cgdcbxd
chan
CharLS
checkpolicy
checksec
chrony
cim-schema
cjkuni-uming-fonts
cjose
ck
cldr-emoji-annotation
clucene
clutter
clutter-gst3
clutter-gtk
cmocka
cogl
collectd
colm
color-filesystem
colord
colorize
compat-lua
compiler-rt
conda
conmon
conntrack-tools
console-setup
container-exception-logger
containernetworking-plugins
convmv
corosync
corosync-qdevice
cpp-hocon
cppcheck
cpprest
cpptest
cpuid
criu
crypto-policies
cryptsetup
cscope
ctags
CUnit
cups
custodia
Cython
dbus-c++
dbus-python
dbxtool
dconf
dcraw
debootstrap
deltarpm
desktop-file-utils
device-mapper-persistent-data
dietlibc
diffstat
ding-libs
discount
distribution-gpg-keys
dleyna-connector-dbus
dleyna-core
dmraid
dnf
dnf-plugins-core
docbook-dtds
docbook-simple
docbook-slides
docbook-style-dsssl
docbook-utils
docbook2X
docbook5-schemas
docbook5-style-xsl
dogtail
dos2unix
dotconf
dovecot
dpdk
dpkg
driverctl
dropwatch
drpm
duktape
dumpet
dvd+rw-tools
dwarves
dwz
dyninst
ebtables
edac-utils
edk2
efax
efi-rpm-macros
egl-wayland
eglexternalplatform
elinks
enca
enchant
enchant2
enscript
environment-modules
evemu
execstack
exempi
exiv2
extra-cmake-modules
fabtests
facter
fakechroot
fakeroot
fapolicyd
fdk-aac-free
fdupes
fence-virt
fetchmail
fftw
filebench
fio
fipscheck
firewalld
flac
flatbuffers
flite
fltk
fmt
fontawesome-fonts
fontawesome4-fonts
fontpackages
fonts-rpm-macros
foomatic-db
freeglut
freeipmi
freeradius
freetds
freexl
fribidi
fros
frr
fsverity-utils
fuse-overlayfs
fuse-sshfs
fuse-zip
fuse3
future
fxload
gavl
gbenchmark
gconf-editor
GConf2
gcovr
gcr
gdal
gdisk
gdk-pixbuf2
generic-logos
genwqe-tools
geoclue2
GeoIP
GeoIP-GeoLite-data
geolite2
geos
gfs2-utils
ghc-srpm-macros
giflib
gl-manpages
glew
glm
glog
glslang
glusterfs
gnome-desktop-testing
gnome-doc-utils
gnome-icon-theme
gnome-keyring
gnu-efi
go-rpm-macros
gom
google-api-python-client
google-crosextra-caladea-fonts
google-crosextra-carlito-fonts
google-guice
google-noto-cjk-fonts
google-noto-emoji-fonts
google-roboto-slab-fonts
gphoto2
gpm
gpsbabel
graphene
graphite2
graphviz
grubby
gsettings-desktop-schemas
gsl
gsm
gspell
gssdp
gssntlmssp
gstreamer1
gstreamer1-plugins-base
gtk-vnc
gtk2
gtk3
gtkspell
gupnp
gupnp-av
gupnp-dlna
gupnp-igd
hardening-check
hdf
hdf5
heimdal
help2man
hexedit
hicolor-icon-theme
hiera
highlight
hivex
hostname
hping3
hsakmt
htop
hunspell
hunspell-af
hunspell-ar
hunspell-as
hunspell-ast
hunspell-az
hunspell-be
hunspell-bg
hunspell-bn
hunspell-br
hunspell-ca
hunspell-cop
hunspell-csb
hunspell-cv
hunspell-cy
hunspell-da
hunspell-de
hunspell-dsb
hunspell-el
hunspell-en
hunspell-eo
hunspell-es
hunspell-et
hunspell-eu
hunspell-fa
hunspell-fj
hunspell-fo
hunspell-fr
hunspell-fur
hunspell-fy
hunspell-ga
hunspell-gd
hunspell-gl
hunspell-grc
hunspell-gu
hunspell-gv
hunspell-haw
hunspell-hi
hunspell-hil
hunspell-hr
hunspell-hsb
hunspell-ht
hunspell-hu
hunspell-hy
hunspell-ia
hunspell-id
hunspell-is
hunspell-it
hunspell-kk
hunspell-km
hunspell-kn
hunspell-ko
hunspell-ku
hunspell-ky
hunspell-la
hunspell-lb
hunspell-ln
hunspell-mai
hunspell-mg
hunspell-mi
hunspell-mk
hunspell-ml
hunspell-mn
hunspell-mos
hunspell-mr
hunspell-ms
hunspell-mt
hunspell-nds
hunspell-ne
hunspell-nl
hunspell-no
hunspell-nr
hunspell-nso
hunspell-ny
hunspell-om
hunspell-or
hunspell-pa
hunspell-pl
hunspell-pt
hunspell-quh
hunspell-ro
hunspell-ru
hunspell-rw
hunspell-se
hunspell-shs
hunspell-si
hunspell-sk
hunspell-sl
hunspell-smj
hunspell-so
hunspell-sq
hunspell-sr
hunspell-sv
hunspell-sw
hunspell-ta
hunspell-te
hunspell-tet
hunspell-th
hunspell-tk
hunspell-tl
hunspell-tn
hunspell-tpi
hunspell-ts
hunspell-uk
hunspell-uz
hunspell-ve
hunspell-vi
hunspell-wa
hunspell-xh
hunspell-yi
hwdata
hwloc
hyperscan
hyperv-daemons
hyphen
hyphen-as
hyphen-bg
hyphen-bn
hyphen-ca
hyphen-da
hyphen-de
hyphen-el
hyphen-es
hyphen-fa
hyphen-fo
hyphen-fr
hyphen-ga
hyphen-gl
hyphen-grc
hyphen-gu
hyphen-hi
hyphen-hsb
hyphen-hu
hyphen-ia
hyphen-id
hyphen-is
hyphen-it
hyphen-kn
hyphen-ku
hyphen-lt
hyphen-mi
hyphen-ml
hyphen-mn
hyphen-mr
hyphen-nl
hyphen-or
hyphen-pa
hyphen-pl
hyphen-pt
hyphen-ro
hyphen-ru
hyphen-sa
hyphen-sk
hyphen-sl
hyphen-sv
hyphen-ta
hyphen-te
hyphen-tk
hyphen-uk
ibus
ibus-chewing
ibus-hangul
ibus-kkc
ibus-libzhuyin
ibus-m17n
ibus-rawcode
ibus-sayura
ibus-table
ibus-table-chinese
icc-profiles-openicc
icon-naming-utils
icoutils
iftop
iio-sensor-proxy
ilmbase
im-chooser
imaptest
imsettings
indent
infinipath-psm
inih
iniparser
intel-cmt-cat
intel-ipsec-mb
ioping
IP2Location
ipa-pgothic-fonts
ipcalc
ipmitool
iprutils
iptraf-ng
iptstate
irssi
iscsi-initiator-utils
isns-utils
iso-codes
isomd5sum
iw
iwd
jabberpy
jakarta-servlet
jasper
javapackages-bootstrap
javapackages-tools
jbigkit
jdom2
jemalloc
jfsutils
jimtcl
jose
js-jquery
jsoncpp
Judy
jurand
kata-containers
kde-filesystem
kde-settings
kexec-tools
keybinder3
keycloak-httpd-client-install
kf
kf-kconfig
kf-kcoreaddons
kf-ki18n
kf-kwidgetsaddons
kpmcore
kronosnet
ksh
kyotocabinet
kyua
ladspa
lame
langtable
lapack
lasso
latencytop
lato-fonts
lcms2
lcov
ldns
leatherman
ledmon
lensfun
leveldb
lftp
libabw
libaec
libao
libappstream-glib
libarrow
libart_lgpl
libasyncns
libatasmart
libavc1394
libblockdev
libbpf
libbsd
libburn
libbytesize
libcacard
libcanberra
libcdio
libcdio-paranoia
libcdr
libcgroup
libchewing
libcli
libcmis
libcmpiutil
libcomps
libcroco
libdaemon
libdap
libdatrie
libdazzle
libdbi
libdbi-drivers
libdbusmenu
libdc1394
libdeflate
libdmx
libdnf
libdrm
libdvdnav
libdvdread
libdwarf
libeasyfc
libecap
libecb
libell
libEMF
libeot
libepoxy
libepubgen
libesmtp
libetonyek
libev
libevdev
libexif
libexttextcat
libfabric
libfontenc
libfreehand
libftdi
libgadu
libgdither
libgee
libgee06
libgeotiff
libgexiv2
libgit2
libgit2-glib
libglade2
libglvnd
libgovirt
libgphoto2
libgsf
libgta
libguestfs
libgusb
libgxim
libgxps
libhangul
libhugetlbfs
libibcommon
libical
libICE
libicns
libid3tag
libIDL
libidn2
libiec61883
libieee1284
libimobiledevice
libindicator
libinput
libiodbc
libipt
libiptcdata
libiscsi
libisoburn
libisofs
libjcat
libkcapi
libkeepalive
libkkc
libkkc-data
libkml
liblangtag
libldb
libldm
liblerc
liblockfile
liblognorm
liblouis
liblqr-1
liblzf
libmad
libmediaart
libmicrohttpd
libmikmod
libmodman
libmodplug
libmodulemd1
libmpcdec
libmspub
libmtp
libmusicbrainz5
libmwaw
libnbd
libnet
libnetfilter_log
libnfs
libnotify
libntlm
libnumbertext
libnvme
liboauth
libodfgen
libofa
libogg
liboggz
liboil
libomxil-bellagio
libopenraw
liboping
libosinfo
libotf
libotr
libpagemaker
libpaper
libpciaccess
libpeas
libpfm
libpinyin
libplist
libpmemobj-cpp
libpng12
libpng15
libproxy
libpsm2
libpwquality
libqb
libqxp
libraqm
LibRaw
libraw1394
libreport
libreswan
librevenge
librsvg2
librx
libsamplerate
libsass
libsecret
libsemanage
libsigc++20
libsigsegv
libslirp
libSM
libsmbios
libsmi
libsndfile
libsodium
libspiro
libsrtp
libssh
libstaroffice
libstemmer
libstoragemgmt
libtdb
libteam
libtevent
libthai
libtnc
libtomcrypt
libtommath
libtpms
libtracecmd
libtraceevent
libtracefs
libtranslit
libucil
libunicap
libuninameslist
liburing
libusbmuxd
libuser
libutempter
libvarlink
libverto
libvirt-dbus
libvirt-glib
libvirt-java
libvirt-python
libvisio
libvisual
libvoikko
libvorbis
libvpx
libwacom
libwnck3
libwpd
libwpe
libwpg
libwps
libwvstreams
libX11
libXau
libXaw
libxcb
libXcomposite
libxcrypt
libXcursor
libXdamage
libXdmcp
libXext
libxfce4util
libXfixes
libXfont2
libXft
libXi
libXinerama
libxkbcommon
libxkbfile
libxklavier
libxmlb
libXmu
libXpm
libXrandr
libXrender
libXres
libXScrnSaver
libxshmfence
libXt
libXtst
libXv
libXxf86vm
libyami
libyang
libyubikey
libzip
libzmf
lilv
linuxconsoletools
linuxptp
lksctp-tools
lldpd
lockdev
logwatch
lpsolve
lrzsz
lua
lua-expat
lua-filesystem
lua-json
lua-lpeg
lua-lunit
lua-rpm-macros
lua-term
luajit
lujavrite
luksmeta
lutok
lv2
lzip
lzop
m17n-db
m17n-lib
mac-robber
mailcap
mailx
malaga
malaga-suomi-voikko
mallard-rng
man-pages-cs
man-pages-es
man-pages-it
man-pages-ja
man-pages-ko
man-pages-pl
man-pages-ru
man-pages-zh-CN
mandoc
mariadb-connector-c
mariadb-connector-odbc
marisa
maven-compiler-plugin
maven-jar-plugin
maven-resolver
maven-resources-plugin
maven-surefire
maven-wagon
mcelog
mcpp
mcstrans
mdadm
mdds
mdevctl
meanwhile
mecab
mecab-ipadic
media-player-info
memcached
memkind
mesa
mesa-libGLU
metis
microcode_ctl
microdnf
minicom
minizip
mksh
mobile-broadband-provider-info
mock
mock-core-configs
mod_auth_gssapi
mod_auth_mellon
mod_auth_openidc
mod_authnz_pam
mod_fcgid
mod_http2
mod_intercept_form_submit
mod_lookup_identity
mod_md
mod_security
mod_security_crs
mod_wsgi
mokutil
mozjs
mpage
mrtg
mstflint
mt-st
mtdev
mtools
mtr
mtx
munge
mutt
mythes
mythes-bg
mythes-ca
mythes-cs
mythes-da
mythes-de
mythes-el
mythes-en
mythes-eo
mythes-es
mythes-fr
mythes-ga
mythes-hu
mythes-mi
mythes-ne
mythes-nl
mythes-pl
mythes-pt
mythes-ro
mythes-ru
mythes-sk
mythes-sl
mythes-sv
mythes-uk
nbd
nbdkit
neon
netavark
netcdf
netcf
netlabel_tools
netpbm
netsniff-ng
nfs4-acl-tools
nftables
nilfs-utils
nkf
nload
nlopt
nodejs-packaging
nss-mdns
nss-pam-ldapd
nss_nis
nss_wrapper
ntfs-3g
ntfs-3g-system-compression
numad
numatop
numpy
nvmetcli
nvml
oath-toolkit
ocaml
ocaml-alcotest
ocaml-astring
ocaml-augeas
ocaml-base
ocaml-bigarray-compat
ocaml-bisect-ppx
ocaml-calendar
ocaml-camlp-streams
ocaml-camlp5
ocaml-camomile
ocaml-cinaps
ocaml-cmdliner
ocaml-compiler-libs-janestreet
ocaml-cppo
ocaml-csexp
ocaml-csv
ocaml-ctypes
ocaml-curses
ocaml-dune
ocaml-extlib
ocaml-fileutils
ocaml-findlib
ocaml-fmt
ocaml-fpath
ocaml-gettext
ocaml-integers
ocaml-libvirt
ocaml-luv
ocaml-lwt
ocaml-markup
ocaml-mmap
ocaml-num
ocaml-ocamlbuild
ocaml-ocplib-endian
ocaml-ounit
ocaml-parsexp
ocaml-pp
ocaml-ppx-derivers
ocaml-ppx-here
ocaml-ppx-let
ocaml-ppxlib
ocaml-re
ocaml-react
ocaml-result
ocaml-seq
ocaml-sexplib
ocaml-sexplib0
ocaml-srpm-macros
ocaml-stdio
ocaml-stdlib-random
ocaml-topkg
ocaml-tyxml
ocaml-uutf
ocaml-xml-light
ocaml-zarith
ocl-icd
oddjob
ogdi
omping
opa
opal
open-vm-tools
openblas
opencc
opencl-filesystem
opencl-headers
opencryptoki
opencsd
opendnssec
OpenEXR
openjade
openjpeg2
openmpi
openobex
openoffice-lv
openrdate
opensc
openslp
opensm
opensp
openssl
openssl-ibmpkcs11
openssl-pkcs11
openwsman
optipng
opus
opusfile
orangefs
ORBit2
orc
os-prober
osinfo-db
osinfo-db-tools
overpass-fonts
p11-kit
p7zip
pacemaker
pacrunner
pakchois
pam_krb5
pam_wrapper
papi
paps
parallel
patchelf
patchutils
pbzip2
pcp
pcsc-lite
pcsc-lite-ccid
PEGTL
perl
perl-Algorithm-C3
perl-Algorithm-Diff
perl-Alien-Build
perl-Alien-pkgconf
perl-AnyEvent
perl-AnyEvent-AIO
perl-AnyEvent-BDB
perl-App-cpanminus
perl-App-FatPacker
perl-AppConfig
perl-Archive-Extract
perl-Archive-Zip
perl-Authen-SASL
perl-B-COW
perl-B-Debug
perl-B-Hooks-EndOfScope
perl-B-Hooks-OP-Check
perl-B-Keywords
perl-B-Lint
perl-bareword-filehandles
perl-BDB
perl-Bit-Vector
perl-boolean
perl-Browser-Open
perl-BSD-Resource
perl-Business-ISBN
perl-Business-ISBN-Data
perl-Bytes-Random-Secure
perl-Capture-Tiny
perl-Carp-Clan
perl-CBOR-XS
perl-Class-Accessor
perl-Class-C3
perl-Class-C3-XS
perl-Class-Data-Inheritable
perl-Class-Factory-Util
perl-Class-Inspector
perl-Class-ISA
perl-Class-Load
perl-Class-Load-XS
perl-Class-Method-Modifiers
perl-Class-Singleton
perl-Class-Tiny
perl-Class-XSAccessor
perl-Clone
perl-Color-ANSI-Util
perl-Color-RGB-Util
perl-ColorThemeBase-Static
perl-ColorThemeRole-ANSI
perl-ColorThemes-Standard
perl-ColorThemeUtil-ANSI
perl-Compress-Bzip2
perl-Compress-LZF
perl-Compress-Raw-Lzma
perl-Config-AutoConf
perl-Config-INI
perl-Config-INI-Reader-Multiline
perl-Config-IniFiles
perl-Config-Simple
perl-Config-Tiny
perl-Const-Fast
perl-Convert-ASN1
perl-Convert-Bencode
perl-Coro
perl-Coro-Multicore
perl-CPAN-Changes
perl-CPAN-DistnameInfo
perl-CPAN-Meta-Check
perl-Cpanel-JSON-XS
perl-Crypt-CBC
perl-Crypt-DES
perl-Crypt-IDEA
perl-Crypt-OpenSSL-Bignum
perl-Crypt-OpenSSL-Guess
perl-Crypt-OpenSSL-Random
perl-Crypt-OpenSSL-RSA
perl-Crypt-PasswdMD5
perl-Crypt-Random-Seed
perl-CSS-Tiny
perl-Data-Dump
perl-Data-Munge
perl-Data-OptList
perl-Data-Peek
perl-Data-Section
perl-Data-UUID
perl-Date-Calc
perl-Date-ISO8601
perl-Date-Manip
perl-DateTime
perl-DateTime-Format-Builder
perl-DateTime-Format-DateParse
perl-DateTime-Format-HTTP
perl-DateTime-Format-IBeat
perl-DateTime-Format-ISO8601
perl-DateTime-Format-Mail
perl-DateTime-Format-Strptime
perl-DateTime-Locale
perl-DateTime-TimeZone
perl-DateTime-TimeZone-SystemV
perl-DateTime-TimeZone-Tzfile
perl-DBD-MySQL
perl-Devel-CallChecker
perl-Devel-Caller
perl-Devel-CheckBin
perl-Devel-CheckLib
perl-Devel-Cycle
perl-Devel-EnforceEncapsulation
perl-Devel-GlobalDestruction
perl-Devel-GlobalDestruction-XS
perl-Devel-Hide
perl-Devel-Leak
perl-Devel-LexAlias
perl-Devel-Size
perl-Devel-StackTrace
perl-Devel-Symdump
perl-Digest-BubbleBabble
perl-Digest-CRC
perl-Digest-HMAC
perl-Digest-SHA1
perl-Dist-CheckConflicts
perl-DynaLoader-Functions
perl-Email-Address
perl-Email-Date-Format
perl-Encode-Detect
perl-Encode-EUCJPASCII
perl-Encode-IMAPUTF7
perl-Encode-Locale
perl-Env-ShellWords
perl-Error
perl-EV
perl-Eval-Closure
perl-Event
perl-Exception-Class
perl-Expect
perl-ExtUtils-Config
perl-ExtUtils-Depends
perl-ExtUtils-Helpers
perl-ExtUtils-InstallPaths
perl-ExtUtils-PkgConfig
perl-FCGI
perl-Fedora-VSP
perl-FFI-CheckLib
perl-File-BaseDir
perl-File-BOM
perl-File-chdir
perl-File-CheckTree
perl-File-Copy-Recursive
perl-File-DesktopEntry
perl-File-Find-Object
perl-File-Find-Object-Rule
perl-File-Find-Rule
perl-File-Find-Rule-Perl
perl-File-Inplace
perl-File-Listing
perl-File-MimeInfo
perl-File-pushd
perl-File-ReadBackwards
perl-File-Remove
perl-File-ShareDir
perl-File-ShareDir-Install
perl-File-Slurp
perl-File-Slurp-Tiny
perl-File-Slurper
perl-File-Type
perl-Font-TTF
perl-FreezeThaw
perl-GD
perl-GD-Barcode
perl-generators
perl-Getopt-ArgvFile
perl-gettext
perl-Graphics-ColorNamesLite-WWW
perl-GSSAPI
perl-Guard
perl-Hook-LexWrap
perl-HTML-Parser
perl-HTML-Tagset
perl-HTML-Tree
perl-HTTP-Cookies
perl-HTTP-Daemon
perl-HTTP-Date
perl-HTTP-Message
perl-HTTP-Negotiate
perl-Image-Base
perl-Image-Info
perl-Image-Xbm
perl-Image-Xpm
perl-Import-Into
perl-Importer
perl-inc-latest
perl-indirect
perl-Inline-Files
perl-IO-AIO
perl-IO-All
perl-IO-CaptureOutput
perl-IO-Compress-Lzma
perl-IO-HTML
perl-IO-Multiplex
perl-IO-SessionData
perl-IO-Socket-INET6
perl-IO-String
perl-IO-stringy
perl-IO-Tty
perl-IPC-Run
perl-IPC-Run3
perl-IPC-System-Simple
perl-JSON
perl-JSON-Color
perl-JSON-MaybeXS
perl-LDAP
perl-libnet
perl-libwww-perl
perl-libxml-perl
perl-Lingua-EN-Inflect
perl-List-MoreUtils-XS
perl-local-lib
perl-Locale-Codes
perl-Locale-Maketext-Gettext
perl-Locale-Msgfmt
perl-Locale-PO
perl-Log-Message
perl-Log-Message-Simple
perl-LWP-MediaTypes
perl-LWP-Protocol-https
perl-Mail-AuthenticationResults
perl-Mail-DKIM
perl-Mail-IMAPTalk
perl-Mail-SPF
perl-MailTools
perl-Math-Int64
perl-Math-Random-ISAAC
perl-MIME-Charset
perl-MIME-Lite
perl-MIME-Types
perl-Mixin-Linewise
perl-MLDBM
perl-Mock-Config
perl-Module-Build-Tiny
perl-Module-CPANfile
perl-Module-Implementation
perl-Module-Install-AuthorRequires
perl-Module-Install-AuthorTests
perl-Module-Install-AutoLicense
perl-Module-Install-GithubMeta
perl-Module-Install-ManifestSkip
perl-Module-Install-ReadmeFromPod
perl-Module-Install-ReadmeMarkdownFromPod
perl-Module-Install-Repository
perl-Module-Install-TestBase
perl-Module-Load-Util
perl-Module-Manifest
perl-Module-Manifest-Skip
perl-Module-Package
perl-Module-Package-Au
perl-Module-Pluggable
perl-Module-Runtime
perl-Module-Signature
perl-Mojolicious
perl-Moo
perl-Mozilla-CA
perl-Mozilla-LDAP
perl-MRO-Compat
perl-multidimensional
perl-namespace-autoclean
perl-namespace-clean
perl-Net-CIDR-Lite
perl-Net-Daemon
perl-Net-DNS
perl-Net-DNS-Resolver-Mock
perl-Net-DNS-Resolver-Programmable
perl-Net-HTTP
perl-Net-IMAP-Simple
perl-Net-IMAP-Simple-SSL
perl-Net-IP
perl-Net-LibIDN2
perl-Net-Patricia
perl-Net-SMTP-SSL
perl-Net-SNMP
perl-Net-Telnet
perl-Newt
perl-NNTPClient
perl-NTLM
perl-Number-Compare
perl-Object-Deadly
perl-Object-HashBase
perl-Package-Anon
perl-Package-Constants
perl-Package-DeprecationManager
perl-Package-Generator
perl-Package-Stash
perl-Package-Stash-XS
perl-PadWalker
perl-Paper-Specs
perl-PAR-Dist
perl-Parallel-Iterator
perl-Params-Classify
perl-Params-Util
perl-Params-Validate
perl-Params-ValidationCompiler
perl-Parse-PMFile
perl-Parse-RecDescent
perl-Parse-Yapp
perl-Path-Tiny
perl-Perl-Critic
perl-Perl-Critic-More
perl-Perl-Destruct-Level
perl-Perl-MinimumVersion
perl-Perl4-CoreLibs
perl-PerlIO-gzip
perl-PerlIO-utf8_strict
perl-PkgConfig-LibPkgConf
perl-Pod-Coverage
perl-Pod-Coverage-TrustPod
perl-Pod-Escapes
perl-Pod-Eventual
perl-Pod-LaTeX
perl-Pod-Markdown
perl-Pod-Parser
perl-Pod-Plainer
perl-Pod-POM
perl-Pod-Spell
perl-PPI
perl-PPI-HTML
perl-PPIx-QuoteLike
perl-PPIx-Regexp
perl-PPIx-Utilities
perl-prefork
perl-Probe-Perl
perl-Razor-Agent
perl-Readonly
perl-Readonly-XS
perl-Ref-Util
perl-Ref-Util-XS
perl-Regexp-Pattern-Perl
perl-Return-MultiLevel
perl-Role-Tiny
perl-Scope-Guard
perl-Scope-Upper
perl-SGMLSpm
perl-SNMP_Session
perl-Socket6
perl-Software-License
perl-Sort-Versions
perl-Specio
perl-Spiffy
perl-strictures
perl-String-CRC32
perl-String-Format
perl-String-ShellQuote
perl-String-Similarity
perl-Sub-Exporter
perl-Sub-Exporter-Progressive
perl-Sub-Identify
perl-Sub-Info
perl-Sub-Install
perl-Sub-Name
perl-Sub-Quote
perl-Sub-Uplevel
perl-SUPER
perl-Switch
perl-Syntax-Highlight-Engine-Kate
perl-Sys-CPU
perl-Sys-MemInfo
perl-Sys-Virt
perl-Taint-Runtime
perl-Task-Weaken
perl-Term-Size-Any
perl-Term-Size-Perl
perl-Term-Table
perl-Term-UI
perl-TermReadKey
perl-Test-Base
perl-Test-ClassAPI
perl-Test-CPAN-Meta
perl-Test-CPAN-Meta-JSON
perl-Test-Deep
perl-Test-Differences
perl-Test-DistManifest
perl-Test-Distribution
perl-Test-EOL
perl-Test-Exception
perl-Test-Exit
perl-Test-FailWarnings
perl-Test-Fatal
perl-Test-File
perl-Test-File-ShareDir
perl-Test-Harness
perl-Test-HasVersion
perl-Test-InDistDir
perl-Test-Inter
perl-Test-LeakTrace
perl-Test-LongString
perl-Test-Manifest
perl-Test-Memory-Cycle
perl-Test-MinimumVersion
perl-Test-MockObject
perl-Test-MockRandom
perl-Test-Needs
perl-Test-NoTabs
perl-Test-NoWarnings
perl-Test-Object
perl-Test-Output
perl-Test-Pod
perl-Test-Pod-Coverage
perl-Test-Portability-Files
perl-Test-Requires
perl-Test-RequiresInternet
perl-Test-Script
perl-Test-Simple
perl-Test-SubCalls
perl-Test-Synopsis
perl-Test-Taint
perl-Test-TrailingSpace
perl-Test-utf8
perl-Test-Vars
perl-Test-Warn
perl-Test-Without-Module
perl-Test2-Plugin-NoWarnings
perl-Test2-Suite
perl-Test2-Tools-Explain
perl-Text-CharWidth
perl-Text-CSV_XS
perl-Text-Diff
perl-Text-Glob
perl-Text-Iconv
perl-Text-Soundex
perl-Text-Unidecode
perl-Text-WrapI18N
perl-Tie-IxHash
perl-TimeDate
perl-Tree-DAG_Node
perl-Unicode-EastAsianWidth
perl-Unicode-LineBreak
perl-Unicode-Map8
perl-Unicode-String
perl-Unicode-UTF8
perl-UNIVERSAL-can
perl-UNIVERSAL-isa
perl-Unix-Syslog
perl-URI
perl-Variable-Magic
perl-Version-Requirements
perl-WWW-RobotRules
perl-XML-Catalog
perl-XML-DOM
perl-XML-Dumper
perl-XML-Filter-BufferText
perl-XML-Generator
perl-XML-Grove
perl-XML-Handler-YAWriter
perl-XML-LibXML
perl-XML-LibXSLT
perl-XML-NamespaceSupport
perl-XML-Parser-Lite
perl-XML-RegExp
perl-XML-SAX
perl-XML-SAX-Base
perl-XML-SAX-Writer
perl-XML-Simple
perl-XML-TokeParser
perl-XML-TreeBuilder
perl-XML-Twig
perl-XML-Writer
perl-XML-XPath
perl-XML-XPathEngine
perl-XString
perl-YAML-LibYAML
perl-YAML-PP
perl-YAML-Syck
perltidy
pesign
phodav
php
php-pear
php-pecl-zip
physfs
picosat
pinfo
pipewire
pixman
pkcs11-helper
pkgconf
plexus-cipher
plexus-containers
plexus-sec-dispatcher
plotutils
pmdk-convert
pmix
pngcrush
pngnq
po4a
podman
poetry
policycoreutils
polkit-pkla-compat
polkit-qt-1
portreserve
postfix
potrace
powertop
ppp
pps-tools
pptp
priv_wrapper
procmail
prometheus
prometheus-node-exporter
ps_mem
psacct
pssh
psutils
ptlib
publicsuffix-list
pugixml
pulseaudio
puppet
pwgen
pyatspi
pybind11
pycairo
pyelftools
pyflakes
pygobject3
PyGreSQL
pykickstart
pylint
pyparted
pyproject-rpm-macros
pyserial
python-absl-py
python-aiodns
python-aiohttp
python-alsa
python-argcomplete
python-astroid
python-astunparse
python-async-generator
python-augeas
python-azure-sdk
python-beautifulsoup4
python-betamax
python-blinker
python-blivet
python-cached_property
python-charset-normalizer
python-cheetah
python-click
python-cmd2
python-colorama
python-CommonMark
python-conda-package-handling
python-configshell
python-cpuinfo
python-cups
python-curio
python-cytoolz
python-d2to1
python-dbus-client-gen
python-dbus-python-client-gen
python-dbus-signature-pyparsing
python-dbusmock
python-ddt
python-debtcollector
python-decorator
python-distlib
python-dmidecode
python-dns
python-dtopt
python-dulwich
python-editables
python-enchant
python-entrypoints
python-ethtool
python-evdev
python-extras
python-faker
python-fasteners
python-fastjsonschema
python-fields
python-filelock
python-fixtures
python-flake8
python-flask
python-flit
python-flit-core
python-fluidity-sm
python-frozendict
python-funcsigs
python-gast
python-genshi
python-google-auth
python-google-auth-oauthlib
python-greenlet
python-gssapi
python-h5py
python-hatch-fancy-pypi-readme
python-hatch-vcs
python-hatchling
python-hs-dbus-signature
python-html5lib
python-httplib2
python-humanize
python-hwdata
python-importlib-metadata
python-inotify
python-into-dbus-python
python-IPy
python-iso8601
python-isodate
python-isort
python-itsdangerous
python-justbases
python-justbytes
python-jwcrypto
python-jwt
python-kdcproxy
python-kerberos
python-kmod
python-kubernetes
python-lark
python-lazy-object-proxy
python-ldap
python-linux-procfs
python-lit
python-looseversion
python-markdown
python-markdown-it-py
python-mccabe
python-mdurl
python-memcached
python-mimeparse
python-mock
python-monotonic
python-more-itertools
python-mpmath
python-msal
python-msrestazure
python-mutagen
python-networkx
python-nose2
python-ntlm-auth
python-oauth2client
python-openpyxl
python-openstackdocstheme
python-oslo-i18n
python-oslo-sphinx
python-paramiko
python-pathspec
python-pefile
python-pexpect
python-pkgconfig
python-platformdirs
python-pluggy
python-podman-api
python-poetry-core
python-process-tests
python-productmd
python-ptyprocess
python-pycares
python-pycosat
python-pydbus
python-pymongo
python-PyMySQL
python-pyperclip
python-pyroute2
python-pyrsistent
python-pysocks
python-pytest-benchmark
python-pytest-cov
python-pytest-expect
python-pytest-flake8
python-pytest-flakes
python-pytest-forked
python-pytest-mock
python-pytest-relaxed
python-pytest-runner
python-pytest-subtests
python-pytest-timeout
python-pytest-xdist
python-pytoml
python-pyudev
python-pywbem
python-qrcode
python-rdflib
python-recommonmark
python-requests-file
python-requests-ftp
python-requests-kerberos
python-requests-mock
python-requests-oauthlib
python-requests-toolbelt
python-requests_ntlm
python-responses
python-retrying
python-rfc3986
python-rich
python-rpm-generators
python-rpmfluff
python-rtslib
python-ruamel-yaml
python-ruamel-yaml-clib
python-s3transfer
python-schedutils
python-semantic_version
python-should_dsl
python-simpleline
python-slip
python-sniffio
python-sortedcontainers
python-soupsieve
python-sphinx
python-sphinx-epytext
python-sphinx-theme-py3doc-enhanced
python-sphinx_rtd_theme
python-sphinxcontrib-apidoc
python-sphinxcontrib-applehelp
python-sphinxcontrib-devhelp
python-sphinxcontrib-htmlhelp
python-sphinxcontrib-httpdomain
python-sphinxcontrib-jsmath
python-sphinxcontrib-qthelp
python-sphinxcontrib-serializinghtml
python-sqlalchemy
python-suds
python-systemd
python-tempita
python-templated-dictionary
python-termcolor
python-testpath
python-testresources
python-testscenarios
python-testtools
python-tidy
python-toml
python-tomli
python-toolz
python-tornado
python-tox
python-tox-current-env
python-tqdm
python-trio
python-trove-classifiers
python-typing-extensions
python-uamqp
python-unittest2
python-uritemplate
python-urwid
python-varlink
python-versioneer
python-virt-firmware
python-voluptuous
python-waitress
python-webencodings
python-webtest
python-wheel
python-whoosh
python-winrm
python-wrapt
python-xlrd
python-xmltodict
python-yubico
python-zipp
python-zmq
python-zstd
python3-mallard-ducktype
python3-pytest-asyncio
python3-typed_ast
pyusb
pywbem
pyxattr
qemu
qhull
qpdf
qperf
qr-code-generator
qt-rpm-macros
qt5-qtconnectivity
qt5-qtsensors
qt5-qtserialport
qtbase
qtdeclarative
qtsvg
qttools
quagga
quota
radvd
ragel
raptor2
rarian
rasdaemon
rasqal
rcs
rdist
rdma-core
re2
re2c
realmd
rear
recode
redland
resource-agents
rest
rhash
rlwrap
rp-pppoe
rpm-mpi-hooks
rpmdevtools
rpmlint
rtkit
rtl-sdr
ruby-augeas
rubygem-bson
rubygem-coderay
rubygem-diff-lcs
rubygem-flexmock
rubygem-hpricot
rubygem-introspection
rubygem-liquid
rubygem-maruku
rubygem-metaclass
rubygem-mongo
rubygem-mustache
rubygem-mysql2
rubygem-pkg-config
rubygem-rake
rubygem-rake-compiler
rubygem-ronn
rubygem-rouge
rubygem-rspec
rubygem-rspec-expectations
rubygem-rspec-mocks
rubygem-rspec-support
rubygem-thread_order
rusers
rust-cbindgen
samba
sanlock
sassist
satyr
sbc
sblim-cim-client2
sblim-cmpi-base
sblim-cmpi-devel
sblim-cmpi-fsvol
sblim-cmpi-network
sblim-cmpi-nfsv3
sblim-cmpi-nfsv4
sblim-cmpi-params
sblim-cmpi-sysfs
sblim-cmpi-syslog
sblim-indication_helper
sblim-sfcb
sblim-sfcc
sblim-sfcCommon
sblim-testsuite
sblim-wbemcli
scl-utils
scotch
screen
scrub
SDL
SDL2
SDL_sound
sdparm
seabios
secilc
selinux-policy
sendmail
serd
setools
setserial
setuptool
sgabios
sgml-common
sgpio
shared-mime-info
sharutils
sip
sisu
skkdic
sleuthkit
slirp4netns
smartmontools
smc-tools
socket_wrapper
softhsm
sombok
sord
sos
sound-theme-freedesktop
soundtouch
sox
soxr
sparsehash
spausedd
speex
speexdsp
spice-protocol
spice-vdagent
spirv-headers
spirv-tools
splix
squashfs-tools
squid
sratom
sscg
star
startup-notification
stunnel
subscription-manager
suitesparse
SuperLU
supermin
switcheroo-control
swtpm
symlinks
sympy
sysfsutils
systemd
systemd-bootchart
t1lib
t1utils
taglib
tang
targetcli
tbb
tcl-pgtcl
tclx
teckit
telnet
thrift
tidy
time
tini
tinycdb
tix
tk
tlog
tmpwatch
tn5250
tofrodos
tokyocabinet
trace-cmd
tss2
ttembed
ttmkfdir
tuna
twolame
uchardet
uclibc-ng
ucpp
ucs-miscfixed-fonts
ucx
udftools
udica
udisks2
uglify-js
uid_wrapper
unicode-emoji
unicode-ucd
unique3
units
upower
uriparser
urlview
usb_modeswitch
usb_modeswitch-data
usbguard
usbip
usbmuxd
usbredir
usermode
ustr
uthash
uuid
uw-imap
v4l-utils
vhostmd
vino
virglrenderer
virt-p2v
virt-top
virt-what
virt-who
vitess
vmem
volume_key
vorbis-tools
vte291
vulkan-headers
vulkan-loader
watchdog
wavpack
wayland
wayland-protocols
web-assets
webrtc-audio-processing
websocketpp
wget
whois
wireguard-tools
wireless-regdb
wireshark
woff2
wordnet
words
wpebackend-fdo
wsmancli
wvdial
x3270
xapian-core
Xaw3d
xcb-proto
xcb-util
xcb-util-image
xcb-util-keysyms
xcb-util-renderutil
xcb-util-wm
xdelta
xdg-dbus-proxy
xdg-utils
xdp-tools
xerces-c
xfconf
xfsdump
xhtml1-dtds
xkeyboard-config
xmlstarlet
xmltoman
xmvn
xorg-x11-apps
xorg-x11-drv-libinput
xorg-x11-font-utils
xorg-x11-fonts
xorg-x11-proto-devel
xorg-x11-server
xorg-x11-server-utils
xorg-x11-util-macros
xorg-x11-utils
xorg-x11-xauth
xorg-x11-xbitmaps
xorg-x11-xinit
xorg-x11-xkb-utils
xorg-x11-xtrans-devel
xrestop
xterm
xxhash
yajl
yaml-cpp
yasm
yelp-tools
yelp-xsl
ykclient
yp-tools
ypbind
ypserv
z3
zenity
zerofree
zfs-fuse
zipper
zopfli
zziplib |
+| Fedora | [Fedora MIT License Declaration](https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#License_of_Fedora_SPEC_Files) | a52dec
abseil-cpp
accountsservice
acpica-tools
acpid
adcli
adobe-mappings-cmap
adobe-mappings-pdf
advancecomp
adwaita-icon-theme
afflib
aide
alsa-firmware
alsa-plugins
amtk
amtterm
annobin
ansible-freeipa
archivemount
arptables
arpwatch
asio
aspell
aspell-en
at
at-spi2-atk
at-spi2-core
atf
atk
atop
attr
audiofile
augeas
authbind
authd
authselect
autoconf213
avahi
babeltrace
babeltrace2
babl
baekmuk-ttf-fonts
bats
bcache-tools
biosdevname
blosc
bluez
bmake
bogofilter
bolt
boom-boot
booth
botan2
breezy
brotli
buildah
busybox
bwidget
byacc
ca-certificates
cachefilesd
cairomm
calamares
capnproto
capstone
catatonit
catch
catch1
cdrdao
celt051
cereal
certmonger
cfitsio
cgdcbxd
chan
CharLS
checkpolicy
checksec
chrony
cim-schema
cjkuni-uming-fonts
cjose
ck
cldr-emoji-annotation
clucene
clutter
clutter-gst3
clutter-gtk
cmocka
cogl
collectd
colm
color-filesystem
colord
colorize
compat-lua
compiler-rt
conda
conmon
conntrack-tools
console-setup
container-exception-logger
containernetworking-plugins
convmv
corosync
corosync-qdevice
cpp-hocon
cppcheck
cpprest
cpptest
cpuid
criu
crypto-policies
cryptsetup
cscope
ctags
CUnit
cups
custodia
Cython
dbus-c++
dbus-python
dbxtool
dconf
dcraw
debootstrap
deltarpm
desktop-file-utils
device-mapper-persistent-data
dietlibc
diffstat
ding-libs
discount
distribution-gpg-keys
dleyna-connector-dbus
dleyna-core
dmraid
dnf
dnf-plugins-core
docbook-dtds
docbook-simple
docbook-slides
docbook-style-dsssl
docbook-utils
docbook2X
docbook5-schemas
docbook5-style-xsl
dogtail
dos2unix
dotconf
dovecot
dpdk
dpkg
driverctl
dropwatch
drpm
duktape
dumpet
dvd+rw-tools
dwarves
dwz
dyninst
ebtables
edac-utils
edk2
efax
efi-rpm-macros
egl-wayland
eglexternalplatform
elinks
enca
enchant
enchant2
enscript
environment-modules
evemu
execstack
exempi
exiv2
extra-cmake-modules
fabtests
facter
fakechroot
fakeroot
fapolicyd
fdk-aac-free
fdupes
fence-virt
fetchmail
fftw
filebench
fio
fipscheck
firewalld
flac
flatbuffers
flite
fltk
fmt
fontawesome-fonts
fontawesome4-fonts
fontpackages
fonts-rpm-macros
foomatic-db
freeglut
freeipmi
freeradius
freetds
freexl
fribidi
fros
frr
fsverity-utils
fuse-overlayfs
fuse-sshfs
fuse-zip
fuse3
future
fxload
gavl
gbenchmark
gconf-editor
GConf2
gcovr
gcr
gdal
gdisk
gdk-pixbuf2
generic-logos
genwqe-tools
geoclue2
GeoIP
GeoIP-GeoLite-data
geolite2
geos
gfs2-utils
ghc-srpm-macros
giflib
gl-manpages
glew
glm
glog
glslang
glusterfs
gnome-desktop-testing
gnome-doc-utils
gnome-icon-theme
gnome-keyring
gnu-efi
go-rpm-macros
gom
google-api-python-client
google-crosextra-caladea-fonts
google-crosextra-carlito-fonts
google-guice
google-noto-cjk-fonts
google-noto-emoji-fonts
google-roboto-slab-fonts
gphoto2
gpm
gpsbabel
graphene
graphite2
graphviz
grubby
gsettings-desktop-schemas
gsl
gsm
gspell
gssdp
gssntlmssp
gstreamer1
gstreamer1-plugins-base
gtk-vnc
gtk2
gtk3
gtkspell
gupnp
gupnp-av
gupnp-dlna
gupnp-igd
hardening-check
hdf
hdf5
heimdal
help2man
hexedit
hicolor-icon-theme
hiera
highlight
hivex
hostname
hping3
hsakmt
htop
hunspell
hunspell-af
hunspell-ar
hunspell-as
hunspell-ast
hunspell-az
hunspell-be
hunspell-bg
hunspell-bn
hunspell-br
hunspell-ca
hunspell-cop
hunspell-csb
hunspell-cv
hunspell-cy
hunspell-da
hunspell-de
hunspell-dsb
hunspell-el
hunspell-en
hunspell-eo
hunspell-es
hunspell-et
hunspell-eu
hunspell-fa
hunspell-fj
hunspell-fo
hunspell-fr
hunspell-fur
hunspell-fy
hunspell-ga
hunspell-gd
hunspell-gl
hunspell-grc
hunspell-gu
hunspell-gv
hunspell-haw
hunspell-hi
hunspell-hil
hunspell-hr
hunspell-hsb
hunspell-ht
hunspell-hu
hunspell-hy
hunspell-ia
hunspell-id
hunspell-is
hunspell-it
hunspell-kk
hunspell-km
hunspell-kn
hunspell-ko
hunspell-ku
hunspell-ky
hunspell-la
hunspell-lb
hunspell-ln
hunspell-mai
hunspell-mg
hunspell-mi
hunspell-mk
hunspell-ml
hunspell-mn
hunspell-mos
hunspell-mr
hunspell-ms
hunspell-mt
hunspell-nds
hunspell-ne
hunspell-nl
hunspell-no
hunspell-nr
hunspell-nso
hunspell-ny
hunspell-om
hunspell-or
hunspell-pa
hunspell-pl
hunspell-pt
hunspell-quh
hunspell-ro
hunspell-ru
hunspell-rw
hunspell-se
hunspell-shs
hunspell-si
hunspell-sk
hunspell-sl
hunspell-smj
hunspell-so
hunspell-sq
hunspell-sr
hunspell-sv
hunspell-sw
hunspell-ta
hunspell-te
hunspell-tet
hunspell-th
hunspell-tk
hunspell-tl
hunspell-tn
hunspell-tpi
hunspell-ts
hunspell-uk
hunspell-uz
hunspell-ve
hunspell-vi
hunspell-wa
hunspell-xh
hunspell-yi
hwdata
hwloc
hyperscan
hyperv-daemons
hyphen
hyphen-as
hyphen-bg
hyphen-bn
hyphen-ca
hyphen-da
hyphen-de
hyphen-el
hyphen-es
hyphen-fa
hyphen-fo
hyphen-fr
hyphen-ga
hyphen-gl
hyphen-grc
hyphen-gu
hyphen-hi
hyphen-hsb
hyphen-hu
hyphen-ia
hyphen-id
hyphen-is
hyphen-it
hyphen-kn
hyphen-ku
hyphen-lt
hyphen-mi
hyphen-ml
hyphen-mn
hyphen-mr
hyphen-nl
hyphen-or
hyphen-pa
hyphen-pl
hyphen-pt
hyphen-ro
hyphen-ru
hyphen-sa
hyphen-sk
hyphen-sl
hyphen-sv
hyphen-ta
hyphen-te
hyphen-tk
hyphen-uk
ibus
ibus-chewing
ibus-hangul
ibus-kkc
ibus-libzhuyin
ibus-m17n
ibus-rawcode
ibus-sayura
ibus-table
ibus-table-chinese
icc-profiles-openicc
icon-naming-utils
icoutils
iftop
iio-sensor-proxy
ilmbase
im-chooser
imaptest
imsettings
indent
infinipath-psm
inih
iniparser
intel-cmt-cat
intel-ipsec-mb
ioping
IP2Location
ipa-pgothic-fonts
ipcalc
ipmitool
iprutils
iptraf-ng
iptstate
irssi
iscsi-initiator-utils
isns-utils
iso-codes
isomd5sum
iw
iwd
jabberpy
jakarta-servlet
jasper
javapackages-bootstrap
javapackages-tools
jbigkit
jdom2
jemalloc
jfsutils
jimtcl
jose
js-jquery
jsoncpp
Judy
jurand
kata-containers
kde-filesystem
kde-settings
kexec-tools
keybinder3
keycloak-httpd-client-install
kf
kf-kconfig
kf-kcoreaddons
kf-ki18n
kf-kwidgetsaddons
kpmcore
kronosnet
ksh
kyotocabinet
kyua
ladspa
lame
langtable
lapack
lasso
latencytop
lato-fonts
lcms2
lcov
ldns
leatherman
ledmon
lensfun
leveldb
lftp
libabw
libaec
libao
libappstream-glib
libarrow
libart_lgpl
libasyncns
libatasmart
libavc1394
libblockdev
libbpf
libbsd
libburn
libbytesize
libcacard
libcanberra
libcdio
libcdio-paranoia
libcdr
libcgroup
libchewing
libcli
libcmis
libcmpiutil
libcomps
libcroco
libdaemon
libdap
libdatrie
libdazzle
libdbi
libdbi-drivers
libdbusmenu
libdc1394
libdeflate
libdmx
libdnf
libdrm
libdvdnav
libdvdread
libdwarf
libeasyfc
libecap
libecb
libell
libEMF
libeot
libepoxy
libepubgen
libesmtp
libetonyek
libev
libevdev
libexif
libexttextcat
libfabric
libfontenc
libfreehand
libftdi
libgadu
libgdither
libgee
libgee06
libgeotiff
libgexiv2
libgit2
libgit2-glib
libglade2
libglvnd
libgovirt
libgphoto2
libgsf
libgta
libguestfs
libgusb
libgxim
libgxps
libhangul
libhugetlbfs
libibcommon
libical
libICE
libicns
libid3tag
libIDL
libidn2
libiec61883
libieee1284
libimobiledevice
libindicator
libinput
libiodbc
libipt
libiptcdata
libiscsi
libisoburn
libisofs
libjcat
libkcapi
libkeepalive
libkkc
libkkc-data
libkml
liblangtag
libldb
libldm
liblerc
liblockfile
liblognorm
liblouis
liblqr-1
liblzf
libmad
libmediaart
libmicrohttpd
libmikmod
libmodman
libmodplug
libmodulemd1
libmpcdec
libmspub
libmtp
libmusicbrainz5
libmwaw
libnbd
libnet
libnetfilter_log
libnfs
libnotify
libntlm
libnumbertext
libnvme
liboauth
libodfgen
libofa
libogg
liboggz
liboil
libomxil-bellagio
libopenraw
liboping
libosinfo
libotf
libotr
libpagemaker
libpaper
libpciaccess
libpeas
libpfm
libpinyin
libplist
libpmemobj-cpp
libpng12
libpng15
libproxy
libpsm2
libpwquality
libqb
libqxp
libraqm
LibRaw
libraw1394
libreport
libreswan
librevenge
librsvg2
librx
libsamplerate
libsass
libsecret
libsemanage
libsigc++20
libsigsegv
libslirp
libSM
libsmbios
libsmi
libsndfile
libsodium
libspiro
libsrtp
libssh
libstaroffice
libstemmer
libstoragemgmt
libtdb
libteam
libtevent
libthai
libtnc
libtomcrypt
libtommath
libtpms
libtracecmd
libtraceevent
libtracefs
libtranslit
libucil
libunicap
libuninameslist
liburing
libusbmuxd
libuser
libutempter
libvarlink
libverto
libvirt-dbus
libvirt-glib
libvirt-java
libvirt-python
libvisio
libvisual
libvoikko
libvorbis
libvpx
libwacom
libwnck3
libwpd
libwpe
libwpg
libwps
libwvstreams
libX11
libXau
libXaw
libxcb
libXcomposite
libxcrypt
libXcursor
libXdamage
libXdmcp
libXext
libxfce4util
libXfixes
libXfont2
libXft
libXi
libXinerama
libxkbcommon
libxkbfile
libxklavier
libxmlb
libXmu
libXpm
libXrandr
libXrender
libXres
libXScrnSaver
libxshmfence
libXt
libXtst
libXv
libXxf86vm
libyami
libyang
libyubikey
libzip
libzmf
lilv
linuxconsoletools
linuxptp
lksctp-tools
lldpd
lockdev
logwatch
lpsolve
lrzsz
lua
lua-expat
lua-filesystem
lua-json
lua-lpeg
lua-lunit
lua-rpm-macros
lua-term
luajit
lujavrite
luksmeta
lutok
lv2
lzip
lzop
m17n-db
m17n-lib
mac-robber
mailcap
mailx
malaga
malaga-suomi-voikko
mallard-rng
man-pages-cs
man-pages-es
man-pages-it
man-pages-ja
man-pages-ko
man-pages-pl
man-pages-ru
man-pages-zh-CN
mandoc
mariadb-connector-c
mariadb-connector-odbc
marisa
maven-compiler-plugin
maven-jar-plugin
maven-resolver
maven-resources-plugin
maven-surefire
maven-wagon
mcelog
mcpp
mcstrans
mdadm
mdds
mdevctl
meanwhile
mecab
mecab-ipadic
media-player-info
memcached
memkind
mesa
mesa-libGLU
metis
microcode_ctl
microdnf
minicom
minizip
mksh
mobile-broadband-provider-info
mock
mock-core-configs
mod_auth_gssapi
mod_auth_mellon
mod_auth_openidc
mod_authnz_pam
mod_fcgid
mod_http2
mod_intercept_form_submit
mod_lookup_identity
mod_md
mod_security
mod_security_crs
mod_wsgi
mokutil
mozjs
mpage
mrtg
mstflint
mt-st
mtdev
mtools
mtr
mtx
munge
mutt
mythes
mythes-bg
mythes-ca
mythes-cs
mythes-da
mythes-de
mythes-el
mythes-en
mythes-eo
mythes-es
mythes-fr
mythes-ga
mythes-hu
mythes-mi
mythes-ne
mythes-nl
mythes-pl
mythes-pt
mythes-ro
mythes-ru
mythes-sk
mythes-sl
mythes-sv
mythes-uk
nbd
nbdkit
neon
netavark
netcdf
netcf
netlabel_tools
netpbm
netsniff-ng
nfs4-acl-tools
nftables
nilfs-utils
nkf
nload
nlopt
nodejs-packaging
nss-mdns
nss-pam-ldapd
nss_nis
nss_wrapper
ntfs-3g
ntfs-3g-system-compression
numad
numatop
numpy
nvmetcli
nvml
oath-toolkit
ocaml
ocaml-alcotest
ocaml-astring
ocaml-augeas
ocaml-base
ocaml-bigarray-compat
ocaml-bisect-ppx
ocaml-calendar
ocaml-camlp-streams
ocaml-camlp5
ocaml-camomile
ocaml-cinaps
ocaml-cmdliner
ocaml-compiler-libs-janestreet
ocaml-cppo
ocaml-csexp
ocaml-csv
ocaml-ctypes
ocaml-curses
ocaml-dune
ocaml-extlib
ocaml-fileutils
ocaml-findlib
ocaml-fmt
ocaml-fpath
ocaml-gettext
ocaml-integers
ocaml-libvirt
ocaml-luv
ocaml-lwt
ocaml-markup
ocaml-mmap
ocaml-num
ocaml-ocamlbuild
ocaml-ocplib-endian
ocaml-ounit
ocaml-parsexp
ocaml-pp
ocaml-ppx-derivers
ocaml-ppx-here
ocaml-ppx-let
ocaml-ppxlib
ocaml-re
ocaml-react
ocaml-result
ocaml-seq
ocaml-sexplib
ocaml-sexplib0
ocaml-srpm-macros
ocaml-stdio
ocaml-stdlib-random
ocaml-topkg
ocaml-tyxml
ocaml-uutf
ocaml-xml-light
ocaml-zarith
ocl-icd
oddjob
ogdi
omping
opa
opal
open-vm-tools
openblas
opencc
opencl-filesystem
opencl-headers
opencryptoki
opencsd
opendnssec
OpenEXR
openjade
openjpeg2
openmpi
openobex
openoffice-lv
openrdate
opensc
openslp
opensm
opensp
openssl
openssl-ibmpkcs11
openssl-pkcs11
openwsman
optipng
opus
opusfile
orangefs
ORBit2
orc
os-prober
osinfo-db
osinfo-db-tools
overpass-fonts
p11-kit
p7zip
pacemaker
pacrunner
pakchois
pam_krb5
pam_wrapper
papi
paps
parallel
patchelf
patchutils
pbzip2
pcp
pcsc-lite
pcsc-lite-ccid
PEGTL
perl
perl-Algorithm-C3
perl-Algorithm-Diff
perl-Alien-Build
perl-Alien-pkgconf
perl-AnyEvent
perl-AnyEvent-AIO
perl-AnyEvent-BDB
perl-App-cpanminus
perl-App-FatPacker
perl-AppConfig
perl-Archive-Extract
perl-Archive-Zip
perl-Authen-SASL
perl-B-COW
perl-B-Debug
perl-B-Hooks-EndOfScope
perl-B-Hooks-OP-Check
perl-B-Keywords
perl-B-Lint
perl-bareword-filehandles
perl-BDB
perl-Bit-Vector
perl-boolean
perl-Browser-Open
perl-BSD-Resource
perl-Business-ISBN
perl-Business-ISBN-Data
perl-Bytes-Random-Secure
perl-Capture-Tiny
perl-Carp-Clan
perl-CBOR-XS
perl-Class-Accessor
perl-Class-C3
perl-Class-C3-XS
perl-Class-Data-Inheritable
perl-Class-Factory-Util
perl-Class-Inspector
perl-Class-ISA
perl-Class-Load
perl-Class-Load-XS
perl-Class-Method-Modifiers
perl-Class-Singleton
perl-Class-Tiny
perl-Class-XSAccessor
perl-Clone
perl-Color-ANSI-Util
perl-Color-RGB-Util
perl-ColorThemeBase-Static
perl-ColorThemeRole-ANSI
perl-ColorThemes-Standard
perl-ColorThemeUtil-ANSI
perl-Compress-Bzip2
perl-Compress-LZF
perl-Compress-Raw-Lzma
perl-Config-AutoConf
perl-Config-INI
perl-Config-INI-Reader-Multiline
perl-Config-IniFiles
perl-Config-Simple
perl-Config-Tiny
perl-Const-Fast
perl-Convert-ASN1
perl-Convert-Bencode
perl-Coro
perl-Coro-Multicore
perl-CPAN-Changes
perl-CPAN-DistnameInfo
perl-CPAN-Meta-Check
perl-Cpanel-JSON-XS
perl-Crypt-CBC
perl-Crypt-DES
perl-Crypt-IDEA
perl-Crypt-OpenSSL-Bignum
perl-Crypt-OpenSSL-Guess
perl-Crypt-OpenSSL-Random
perl-Crypt-OpenSSL-RSA
perl-Crypt-PasswdMD5
perl-Crypt-Random-Seed
perl-CSS-Tiny
perl-Data-Dump
perl-Data-Munge
perl-Data-OptList
perl-Data-Peek
perl-Data-Section
perl-Data-UUID
perl-Date-Calc
perl-Date-ISO8601
perl-Date-Manip
perl-DateTime
perl-DateTime-Format-Builder
perl-DateTime-Format-DateParse
perl-DateTime-Format-HTTP
perl-DateTime-Format-IBeat
perl-DateTime-Format-ISO8601
perl-DateTime-Format-Mail
perl-DateTime-Format-Strptime
perl-DateTime-Locale
perl-DateTime-TimeZone
perl-DateTime-TimeZone-SystemV
perl-DateTime-TimeZone-Tzfile
perl-DBD-MySQL
perl-Devel-CallChecker
perl-Devel-Caller
perl-Devel-CheckBin
perl-Devel-CheckLib
perl-Devel-Cycle
perl-Devel-EnforceEncapsulation
perl-Devel-GlobalDestruction
perl-Devel-GlobalDestruction-XS
perl-Devel-Hide
perl-Devel-Leak
perl-Devel-LexAlias
perl-Devel-Size
perl-Devel-StackTrace
perl-Devel-Symdump
perl-Digest-BubbleBabble
perl-Digest-CRC
perl-Digest-HMAC
perl-Digest-SHA1
perl-Dist-CheckConflicts
perl-DynaLoader-Functions
perl-Email-Address
perl-Email-Date-Format
perl-Encode-Detect
perl-Encode-EUCJPASCII
perl-Encode-IMAPUTF7
perl-Encode-Locale
perl-Env-ShellWords
perl-Error
perl-EV
perl-Eval-Closure
perl-Event
perl-Exception-Class
perl-Expect
perl-ExtUtils-Config
perl-ExtUtils-Depends
perl-ExtUtils-Helpers
perl-ExtUtils-InstallPaths
perl-ExtUtils-PkgConfig
perl-FCGI
perl-Fedora-VSP
perl-FFI-CheckLib
perl-File-BaseDir
perl-File-BOM
perl-File-chdir
perl-File-CheckTree
perl-File-Copy-Recursive
perl-File-DesktopEntry
perl-File-Find-Object
perl-File-Find-Object-Rule
perl-File-Find-Rule
perl-File-Find-Rule-Perl
perl-File-Inplace
perl-File-Listing
perl-File-MimeInfo
perl-File-pushd
perl-File-ReadBackwards
perl-File-Remove
perl-File-ShareDir
perl-File-ShareDir-Install
perl-File-Slurp
perl-File-Slurp-Tiny
perl-File-Slurper
perl-File-Type
perl-Font-TTF
perl-FreezeThaw
perl-GD
perl-GD-Barcode
perl-generators
perl-Getopt-ArgvFile
perl-gettext
perl-Graphics-ColorNamesLite-WWW
perl-GSSAPI
perl-Guard
perl-Hook-LexWrap
perl-HTML-Parser
perl-HTML-Tagset
perl-HTML-Tree
perl-HTTP-Cookies
perl-HTTP-Daemon
perl-HTTP-Date
perl-HTTP-Message
perl-HTTP-Negotiate
perl-Image-Base
perl-Image-Info
perl-Image-Xbm
perl-Image-Xpm
perl-Import-Into
perl-Importer
perl-inc-latest
perl-indirect
perl-Inline-Files
perl-IO-AIO
perl-IO-All
perl-IO-CaptureOutput
perl-IO-Compress-Lzma
perl-IO-HTML
perl-IO-Multiplex
perl-IO-SessionData
perl-IO-Socket-INET6
perl-IO-String
perl-IO-stringy
perl-IO-Tty
perl-IPC-Run
perl-IPC-Run3
perl-IPC-System-Simple
perl-JSON
perl-JSON-Color
perl-JSON-MaybeXS
perl-LDAP
perl-libnet
perl-libwww-perl
perl-libxml-perl
perl-Lingua-EN-Inflect
perl-List-MoreUtils-XS
perl-local-lib
perl-Locale-Codes
perl-Locale-Maketext-Gettext
perl-Locale-Msgfmt
perl-Locale-PO
perl-Log-Message
perl-Log-Message-Simple
perl-LWP-MediaTypes
perl-LWP-Protocol-https
perl-Mail-AuthenticationResults
perl-Mail-DKIM
perl-Mail-IMAPTalk
perl-Mail-SPF
perl-MailTools
perl-Math-Int64
perl-Math-Random-ISAAC
perl-MIME-Charset
perl-MIME-Lite
perl-MIME-Types
perl-Mixin-Linewise
perl-MLDBM
perl-Mock-Config
perl-Module-Build-Tiny
perl-Module-CPANfile
perl-Module-Implementation
perl-Module-Install-AuthorRequires
perl-Module-Install-AuthorTests
perl-Module-Install-AutoLicense
perl-Module-Install-GithubMeta
perl-Module-Install-ManifestSkip
perl-Module-Install-ReadmeFromPod
perl-Module-Install-ReadmeMarkdownFromPod
perl-Module-Install-Repository
perl-Module-Install-TestBase
perl-Module-Load-Util
perl-Module-Manifest
perl-Module-Manifest-Skip
perl-Module-Package
perl-Module-Package-Au
perl-Module-Pluggable
perl-Module-Runtime
perl-Module-Signature
perl-Mojolicious
perl-Moo
perl-Mozilla-CA
perl-Mozilla-LDAP
perl-MRO-Compat
perl-multidimensional
perl-namespace-autoclean
perl-namespace-clean
perl-Net-CIDR-Lite
perl-Net-Daemon
perl-Net-DNS
perl-Net-DNS-Resolver-Mock
perl-Net-DNS-Resolver-Programmable
perl-Net-HTTP
perl-Net-IMAP-Simple
perl-Net-IMAP-Simple-SSL
perl-Net-IP
perl-Net-LibIDN2
perl-Net-Patricia
perl-Net-SMTP-SSL
perl-Net-SNMP
perl-Net-Telnet
perl-Newt
perl-NNTPClient
perl-NTLM
perl-Number-Compare
perl-Object-Deadly
perl-Object-HashBase
perl-Package-Anon
perl-Package-Constants
perl-Package-DeprecationManager
perl-Package-Generator
perl-Package-Stash
perl-Package-Stash-XS
perl-PadWalker
perl-Paper-Specs
perl-PAR-Dist
perl-Parallel-Iterator
perl-Params-Classify
perl-Params-Util
perl-Params-Validate
perl-Params-ValidationCompiler
perl-Parse-PMFile
perl-Parse-RecDescent
perl-Parse-Yapp
perl-Path-Tiny
perl-Perl-Critic
perl-Perl-Critic-More
perl-Perl-Destruct-Level
perl-Perl-MinimumVersion
perl-Perl4-CoreLibs
perl-PerlIO-gzip
perl-PerlIO-utf8_strict
perl-PkgConfig-LibPkgConf
perl-Pod-Coverage
perl-Pod-Coverage-TrustPod
perl-Pod-Escapes
perl-Pod-Eventual
perl-Pod-LaTeX
perl-Pod-Markdown
perl-Pod-Parser
perl-Pod-Plainer
perl-Pod-POM
perl-Pod-Spell
perl-PPI
perl-PPI-HTML
perl-PPIx-QuoteLike
perl-PPIx-Regexp
perl-PPIx-Utilities
perl-prefork
perl-Probe-Perl
perl-Razor-Agent
perl-Readonly
perl-Readonly-XS
perl-Ref-Util
perl-Ref-Util-XS
perl-Regexp-Pattern-Perl
perl-Return-MultiLevel
perl-Role-Tiny
perl-Scope-Guard
perl-Scope-Upper
perl-SGMLSpm
perl-SNMP_Session
perl-Socket6
perl-Software-License
perl-Sort-Versions
perl-Specio
perl-Spiffy
perl-strictures
perl-String-CRC32
perl-String-Format
perl-String-ShellQuote
perl-String-Similarity
perl-Sub-Exporter
perl-Sub-Exporter-Progressive
perl-Sub-Identify
perl-Sub-Info
perl-Sub-Install
perl-Sub-Name
perl-Sub-Quote
perl-Sub-Uplevel
perl-SUPER
perl-Switch
perl-Syntax-Highlight-Engine-Kate
perl-Sys-CPU
perl-Sys-MemInfo
perl-Sys-Virt
perl-Taint-Runtime
perl-Task-Weaken
perl-Term-Size-Any
perl-Term-Size-Perl
perl-Term-Table
perl-Term-UI
perl-TermReadKey
perl-Test-Base
perl-Test-ClassAPI
perl-Test-CPAN-Meta
perl-Test-CPAN-Meta-JSON
perl-Test-Deep
perl-Test-Differences
perl-Test-DistManifest
perl-Test-Distribution
perl-Test-EOL
perl-Test-Exception
perl-Test-Exit
perl-Test-FailWarnings
perl-Test-Fatal
perl-Test-File
perl-Test-File-ShareDir
perl-Test-Harness
perl-Test-HasVersion
perl-Test-InDistDir
perl-Test-Inter
perl-Test-LeakTrace
perl-Test-LongString
perl-Test-Manifest
perl-Test-Memory-Cycle
perl-Test-MinimumVersion
perl-Test-MockObject
perl-Test-MockRandom
perl-Test-Needs
perl-Test-NoTabs
perl-Test-NoWarnings
perl-Test-Object
perl-Test-Output
perl-Test-Pod
perl-Test-Pod-Coverage
perl-Test-Portability-Files
perl-Test-Requires
perl-Test-RequiresInternet
perl-Test-Script
perl-Test-Simple
perl-Test-SubCalls
perl-Test-Synopsis
perl-Test-Taint
perl-Test-TrailingSpace
perl-Test-utf8
perl-Test-Vars
perl-Test-Warn
perl-Test-Without-Module
perl-Test2-Plugin-NoWarnings
perl-Test2-Suite
perl-Test2-Tools-Explain
perl-Text-CharWidth
perl-Text-CSV_XS
perl-Text-Diff
perl-Text-Glob
perl-Text-Iconv
perl-Text-Soundex
perl-Text-Unidecode
perl-Text-WrapI18N
perl-Tie-IxHash
perl-TimeDate
perl-Tree-DAG_Node
perl-Unicode-EastAsianWidth
perl-Unicode-LineBreak
perl-Unicode-Map8
perl-Unicode-String
perl-Unicode-UTF8
perl-UNIVERSAL-can
perl-UNIVERSAL-isa
perl-Unix-Syslog
perl-URI
perl-Variable-Magic
perl-Version-Requirements
perl-WWW-RobotRules
perl-XML-Catalog
perl-XML-DOM
perl-XML-Dumper
perl-XML-Filter-BufferText
perl-XML-Generator
perl-XML-Grove
perl-XML-Handler-YAWriter
perl-XML-LibXML
perl-XML-LibXSLT
perl-XML-NamespaceSupport
perl-XML-Parser-Lite
perl-XML-RegExp
perl-XML-SAX
perl-XML-SAX-Base
perl-XML-SAX-Writer
perl-XML-Simple
perl-XML-TokeParser
perl-XML-TreeBuilder
perl-XML-Twig
perl-XML-Writer
perl-XML-XPath
perl-XML-XPathEngine
perl-XString
perl-YAML-LibYAML
perl-YAML-PP
perl-YAML-Syck
perltidy
pesign
phodav
php
php-pear
php-pecl-zip
physfs
picosat
pinfo
pipewire
pixman
pkcs11-helper
pkgconf
plexus-cipher
plexus-containers
plexus-sec-dispatcher
plotutils
pmdk-convert
pmix
pngcrush
pngnq
po4a
podman
poetry
policycoreutils
polkit-pkla-compat
polkit-qt-1
portreserve
postfix
potrace
powertop
ppp
pps-tools
pptp
priv_wrapper
procmail
prometheus
prometheus-node-exporter
ps_mem
psacct
pssh
psutils
ptlib
publicsuffix-list
pugixml
pulseaudio
puppet
pwgen
pyatspi
pybind11
pycairo
pyelftools
pyflakes
pygobject3
PyGreSQL
pykickstart
pylint
pyparted
pyproject-rpm-macros
pyserial
python-absl-py
python-aiodns
python-aiohttp
python-alsa
python-argcomplete
python-argparse-manpage
python-astroid
python-astunparse
python-async-generator
python-augeas
python-azure-sdk
python-beautifulsoup4
python-betamax
python-blinker
python-blivet
python-cached_property
python-charset-normalizer
python-cheetah
python-click
python-cmd2
python-colorama
python-CommonMark
python-conda-package-handling
python-configshell
python-cpuinfo
python-cups
python-curio
python-cytoolz
python-d2to1
python-dbus-client-gen
python-dbus-python-client-gen
python-dbus-signature-pyparsing
python-dbusmock
python-ddt
python-debtcollector
python-decorator
python-distlib
python-dmidecode
python-dns
python-dtopt
python-dulwich
python-editables
python-enchant
python-entrypoints
python-ethtool
python-evdev
python-extras
python-faker
python-fasteners
python-fastjsonschema
python-fields
python-filelock
python-fixtures
python-flake8
python-flask
python-flit
python-flit-core
python-fluidity-sm
python-frozendict
python-funcsigs
python-gast
python-genshi
python-google-auth
python-google-auth-oauthlib
python-greenlet
python-gssapi
python-h5py
python-hatch-fancy-pypi-readme
python-hatch-vcs
python-hatchling
python-hs-dbus-signature
python-html5lib
python-httplib2
python-humanize
python-hwdata
python-importlib-metadata
python-inotify
python-into-dbus-python
python-IPy
python-iso8601
python-isodate
python-isort
python-itsdangerous
python-justbases
python-justbytes
python-jwcrypto
python-jwt
python-kdcproxy
python-kerberos
python-kmod
python-kubernetes
python-lark
python-lazy-object-proxy
python-ldap
python-linux-procfs
python-lit
python-looseversion
python-markdown
python-markdown-it-py
python-mccabe
python-mdurl
python-memcached
python-mimeparse
python-mock
python-monotonic
python-more-itertools
python-mpmath
python-msal
python-msrestazure
python-mutagen
python-networkx
python-nose2
python-ntlm-auth
python-oauth2client
python-openpyxl
python-openstackdocstheme
python-oslo-i18n
python-oslo-sphinx
python-paramiko
python-pathspec
python-pefile
python-pexpect
python-pkgconfig
python-platformdirs
python-pluggy
python-podman-api
python-poetry-core
python-process-tests
python-productmd
python-ptyprocess
python-pycares
python-pycosat
python-pydbus
python-pymongo
python-PyMySQL
python-pyperclip
python-pyroute2
python-pyrsistent
python-pysocks
python-pytest-benchmark
python-pytest-cov
python-pytest-expect
python-pytest-flake8
python-pytest-flakes
python-pytest-forked
python-pytest-mock
python-pytest-relaxed
python-pytest-runner
python-pytest-subtests
python-pytest-timeout
python-pytest-xdist
python-pytoml
python-pyudev
python-pywbem
python-qrcode
python-rdflib
python-recommonmark
python-requests-file
python-requests-ftp
python-requests-kerberos
python-requests-mock
python-requests-oauthlib
python-requests-toolbelt
python-requests_ntlm
python-responses
python-retrying
python-rfc3986
python-rich
python-rpm-generators
python-rpmfluff
python-rtslib
python-ruamel-yaml
python-ruamel-yaml-clib
python-s3transfer
python-schedutils
python-semantic_version
python-should_dsl
python-simpleline
python-slip
python-sniffio
python-sortedcontainers
python-soupsieve
python-sphinx
python-sphinx-epytext
python-sphinx-theme-py3doc-enhanced
python-sphinx_rtd_theme
python-sphinxcontrib-apidoc
python-sphinxcontrib-applehelp
python-sphinxcontrib-devhelp
python-sphinxcontrib-htmlhelp
python-sphinxcontrib-httpdomain
python-sphinxcontrib-jsmath
python-sphinxcontrib-qthelp
python-sphinxcontrib-serializinghtml
python-sqlalchemy
python-suds
python-systemd
python-tempita
python-templated-dictionary
python-termcolor
python-testpath
python-testresources
python-testscenarios
python-testtools
python-tidy
python-toml
python-tomli
python-toolz
python-tornado
python-tox
python-tox-current-env
python-tqdm
python-trio
python-trove-classifiers
python-typing-extensions
python-uamqp
python-unittest2
python-uritemplate
python-urwid
python-varlink
python-versioneer
python-virt-firmware
python-voluptuous
python-waitress
python-webencodings
python-webtest
python-wheel
python-whoosh
python-winrm
python-wrapt
python-xlrd
python-xlsxwriter
python-xmltodict
python-yubico
python-zipp
python-zmq
python-zstd
python3-mallard-ducktype
python3-pytest-asyncio
python3-typed_ast
pyusb
pywbem
pyxattr
qemu
qhull
qpdf
qperf
qr-code-generator
qt-rpm-macros
qt5-qtconnectivity
qt5-qtsensors
qt5-qtserialport
qtbase
qtdeclarative
qtsvg
qttools
quagga
quota
radvd
ragel
raptor2
rarian
rasdaemon
rasqal
rcs
rdist
rdma-core
re2
re2c
realmd
rear
recode
redland
resource-agents
rest
rhash
rlwrap
rp-pppoe
rpm-mpi-hooks
rpmdevtools
rpmlint
rr
rtkit
rtl-sdr
ruby-augeas
rubygem-bson
rubygem-coderay
rubygem-diff-lcs
rubygem-flexmock
rubygem-hpricot
rubygem-introspection
rubygem-liquid
rubygem-maruku
rubygem-metaclass
rubygem-mongo
rubygem-mustache
rubygem-mysql2
rubygem-pkg-config
rubygem-rake
rubygem-rake-compiler
rubygem-ronn
rubygem-rouge
rubygem-rspec
rubygem-rspec-expectations
rubygem-rspec-mocks
rubygem-rspec-support
rubygem-thread_order
rusers
rust-cbindgen
samba
sanlock
sassist
satyr
sbc
sblim-cim-client2
sblim-cmpi-base
sblim-cmpi-devel
sblim-cmpi-fsvol
sblim-cmpi-network
sblim-cmpi-nfsv3
sblim-cmpi-nfsv4
sblim-cmpi-params
sblim-cmpi-sysfs
sblim-cmpi-syslog
sblim-indication_helper
sblim-sfcb
sblim-sfcc
sblim-sfcCommon
sblim-testsuite
sblim-wbemcli
scl-utils
scotch
screen
scrub
SDL
SDL2
SDL_sound
sdparm
seabios
secilc
selinux-policy
sendmail
serd
setools
setserial
setuptool
sgabios
sgml-common
sgpio
shared-mime-info
sharutils
sip
sisu
skkdic
sleuthkit
slirp4netns
smartmontools
smc-tools
socket_wrapper
softhsm
sombok
sord
sos
sound-theme-freedesktop
soundtouch
sox
soxr
sparsehash
spausedd
speex
speexdsp
spice-protocol
spice-vdagent
spirv-headers
spirv-tools
splix
squashfs-tools
squid
sratom
sscg
star
startup-notification
stunnel
subscription-manager
suitesparse
SuperLU
supermin
switcheroo-control
swtpm
symlinks
sympy
sysfsutils
systemd
systemd-bootchart
t1lib
t1utils
taglib
tang
targetcli
tbb
tcl-pgtcl
tclx
teckit
telnet
thrift
tidy
time
tini
tinycdb
tix
tk
tlog
tmpwatch
tn5250
tofrodos
tokyocabinet
trace-cmd
tss2
ttembed
ttmkfdir
tuna
twolame
uchardet
uclibc-ng
ucpp
ucs-miscfixed-fonts
ucx
udftools
udica
udisks2
uglify-js
uid_wrapper
unicode-emoji
unicode-ucd
unique3
units
upower
uriparser
urlview
usb_modeswitch
usb_modeswitch-data
usbguard
usbip
usbmuxd
usbredir
usermode
ustr
uthash
uuid
uw-imap
v4l-utils
vhostmd
vino
virglrenderer
virt-p2v
virt-top
virt-what
virt-who
vitess
vmem
volume_key
vorbis-tools
vte291
vulkan-headers
vulkan-loader
watchdog
wavpack
wayland
wayland-protocols
web-assets
webrtc-audio-processing
websocketpp
wget
whois
wireguard-tools
wireless-regdb
wireshark
woff2
wordnet
words
wpebackend-fdo
wsmancli
wvdial
x3270
xapian-core
Xaw3d
xcb-proto
xcb-util
xcb-util-image
xcb-util-keysyms
xcb-util-renderutil
xcb-util-wm
xdelta
xdg-dbus-proxy
xdg-utils
xdp-tools
xerces-c
xfconf
xfsdump
xhtml1-dtds
xkeyboard-config
xmlstarlet
xmltoman
xmvn
xorg-x11-apps
xorg-x11-drv-libinput
xorg-x11-font-utils
xorg-x11-fonts
xorg-x11-proto-devel
xorg-x11-server
xorg-x11-server-utils
xorg-x11-util-macros
xorg-x11-utils
xorg-x11-xauth
xorg-x11-xbitmaps
xorg-x11-xinit
xorg-x11-xkb-utils
xorg-x11-xtrans-devel
xrestop
xterm
xxhash
yajl
yaml-cpp
yasm
yelp-tools
yelp-xsl
ykclient
yp-tools
ypbind
ypserv
z3
zenity
zerofree
zfs-fuse
zipper
zopfli
zziplib |
| Fedora (Copyright Remi Collet) | [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/legalcode) | libmemcached-awesome
librabbitmq |
| Fedora (ISC) | [ISC License](https://github.com/sarugaku/resolvelib/blob/main/LICENSE) | python-resolvelib |
| Magnus Edenhill Open Source | [Magnus Edenhill Open Source BSD License](https://github.com/jemalloc/jemalloc/blob/dev/COPYING) | librdkafka |
diff --git a/LICENSES-AND-NOTICES/SPECS/data/licenses.json b/LICENSES-AND-NOTICES/SPECS/data/licenses.json
index b4ae96cad2a..54ecaedc612 100644
--- a/LICENSES-AND-NOTICES/SPECS/data/licenses.json
+++ b/LICENSES-AND-NOTICES/SPECS/data/licenses.json
@@ -54,7 +54,6 @@
"annobin",
"ansible-freeipa",
"archivemount",
- "argparse-manpage",
"arptables",
"arpwatch",
"asio",
@@ -99,6 +98,7 @@
"cachefilesd",
"cairomm",
"calamares",
+ "capnproto",
"capstone",
"catatonit",
"catch",
@@ -1629,6 +1629,7 @@
"python-aiohttp",
"python-alsa",
"python-argcomplete",
+ "python-argparse-manpage",
"python-astroid",
"python-astunparse",
"python-async-generator",
@@ -1854,6 +1855,7 @@
"python-winrm",
"python-wrapt",
"python-xlrd",
+ "python-xlsxwriter",
"python-xmltodict",
"python-yubico",
"python-zipp",
@@ -1903,6 +1905,7 @@
"rpm-mpi-hooks",
"rpmdevtools",
"rpmlint",
+ "rr",
"rtkit",
"rtl-sdr",
"ruby-augeas",
diff --git a/SPECS-EXTENDED/buildah/buildah.spec b/SPECS-EXTENDED/buildah/buildah.spec
index 759b23f6cb7..ae8713ec4b7 100644
--- a/SPECS-EXTENDED/buildah/buildah.spec
+++ b/SPECS-EXTENDED/buildah/buildah.spec
@@ -32,7 +32,7 @@ BuildRequires: btrfs-progs-devel
BuildRequires: device-mapper-devel
BuildRequires: git
BuildRequires: glib2-devel
-BuildRequires: glibc-static >= 2.38-5%{?dist}
+BuildRequires: glibc-static >= 2.38-6%{?dist}
BuildRequires: go-md2man
BuildRequires: go-rpm-macros
BuildRequires: golang
diff --git a/SPECS-EXTENDED/capnproto/capnproto.signatures.json b/SPECS-EXTENDED/capnproto/capnproto.signatures.json
new file mode 100644
index 00000000000..2a788b98b07
--- /dev/null
+++ b/SPECS-EXTENDED/capnproto/capnproto.signatures.json
@@ -0,0 +1,5 @@
+{
+ "Signatures": {
+ "capnproto-c++-1.0.1.tar.gz": "0f7f4b8a76a2cdb284fddef20de8306450df6dd031a47a15ac95bc43c3358e09"
+ }
+}
diff --git a/SPECS-EXTENDED/capnproto/capnproto.spec b/SPECS-EXTENDED/capnproto/capnproto.spec
new file mode 100644
index 00000000000..836dd4869b1
--- /dev/null
+++ b/SPECS-EXTENDED/capnproto/capnproto.spec
@@ -0,0 +1,205 @@
+# Force out of source build
+%undefine __cmake_in_source_build
+
+%global modulename %{name}-c++
+
+Name: capnproto
+Version: 1.0.1
+Release: 4%{?dist}
+Summary: A data interchange format and capability-based RPC system
+
+License: MIT
+Vendor: Microsoft Corporation
+Distribution: Azure Linux
+URL: https://capnproto.org
+
+Source0: https://capnproto.org/%{modulename}-%{version}.tar.gz
+
+# We need C++
+BuildRequires: gcc-c++
+BuildRequires: cmake >= 3.1
+
+# Ensure that we use matching version of libraries
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+
+%description
+Cap’n Proto is an insanely fast data interchange format
+and capability-based RPC system. Think JSON, except binary.
+Or think Protocol Buffers, except faster. In fact, in benchmarks,
+Cap’n Proto is INFINITY TIMES faster than Protocol Buffers.
+
+This package contains the schema compiler and command-line
+encoder/decoder tools.
+
+%package libs
+Summary: Libraries for %{name}
+
+%description libs
+The %{name}-libs package contains the libraries for using %{name}
+in applications.
+
+%package devel
+Summary: Development files for %{name}
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+
+%description devel
+The %{name}-devel package contains libraries and header files for
+developing applications that use %{name}.
+
+
+%prep
+%autosetup -n %{modulename}-%{version} -p2
+
+# Disable broken test
+## Cf. https://github.com/capnproto/capnproto/issues/1349
+## Cf. https://github.com/capnproto/capnproto/issues/1398
+sed -e '/TEST(AsyncIo, AncillaryMessageHandler)/,/^}/s/^/\/\//' -i src/kj/async-io-test.c++
+
+
+%build
+# The tests are randomly failing due to poor sparsing support in the build system
+export CFLAGS="%{build_cflags} -DHOLES_NOT_SUPPORTED=1"
+export CXXFLAGS="%{build_cxxflags} -DHOLES_NOT_SUPPORTED=1"
+
+%cmake -DBUILD_TESTING=ON
+%cmake_build
+
+
+%check
+%ctest
+
+
+%install
+%cmake_install
+find %{buildroot} -name '*.la' -delete
+
+
+%files
+%{_bindir}/capnp
+%{_bindir}/capnpc
+%{_bindir}/capnpc-c++
+%{_bindir}/capnpc-capnp
+
+%files libs
+%license LICENSE.txt
+%{_libdir}/*.so.*
+
+%files devel
+%{_includedir}/*
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/cmake/CapnProto/
+
+%changelog
+* Fri Jun 14 2024 Henry Beberman - 1.0.1-4
+- Initial Azure Linux import from Fedora 41 (license: MIT).
+- License verified.
+
+* Tue Jan 23 2024 Fedora Release Engineering - 1.0.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Fri Jan 19 2024 Fedora Release Engineering - 1.0.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Fri Sep 08 2023 Neal Gompa - 1.0.1-1
+- Rebase to 1.0.1
+
+* Wed Jul 19 2023 Fedora Release Engineering - 0.10.3-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Tue Feb 28 2023 Mamoru TASAKA - 0.10.3-3
+- Backport upstream fix for missing headers for g++13
+- Backport upstream fix for operator!= removal for C++20
+
+* Wed Jan 18 2023 Fedora Release Engineering - 0.10.3-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
+
+* Fri Dec 02 2022 Fabio Valentini - 0.10.3-1
+- Update to version 0.10.3
+- Fixes RHBZ#2149787
+- Addresses CVE-2022-46149
+
+* Tue Nov 29 2022 Neal Gompa - 0.10.2-1
+- Rebase to 0.10.2
+- Drop backported patch
+
+* Wed Jul 20 2022 Fedora Release Engineering - 0.9.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Wed Jan 19 2022 Fedora Release Engineering - 0.9.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Tue Dec 21 2021 Neal Gompa - 0.9.1-1
+- Rebase to 0.9.1
+- Add patch to fix running tests
+- Disable flaky/broken test per upstream guidance
+
+* Wed Jul 21 2021 Fedora Release Engineering - 0.8.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Tue Jan 26 2021 Fedora Release Engineering - 0.8.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Mon Jul 27 2020 Fedora Release Engineering - 0.8.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Sat Jul 18 2020 Neal Gompa - 0.8.0-1
+- Update to 0.8.0 (#1827443)
+- Drop backported patches
+
+* Thu Mar 12 2020 Neal Gompa - 0.7.0-6
+- Backport patch to fix aliasing violation breaking builds on GCC 10 on ARM (#1807872)
+- Disable "DiskFile holes" test to stop build failures
+
+* Tue Jan 28 2020 Fedora Release Engineering - 0.7.0-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Wed Jul 24 2019 Fedora Release Engineering - 0.7.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Thu Jan 31 2019 Fedora Release Engineering - 0.7.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Wed Jan 23 2019 Björn Esser - 0.7.0-2
+- Append curdir to CMake invokation. (#1668512)
+
+* Sun Sep 23 2018 Neal Gompa - 0.7.0-1
+- Update to 0.7.0
+- Drop upstreamed patches
+- Drop obsolete ldconfig scriptlets
+
+* Thu Jul 12 2018 Fedora Release Engineering - 0.6.1-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Wed Feb 07 2018 Fedora Release Engineering - 0.6.1-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Sun Aug 06 2017 Björn Esser - 0.6.1-6
+- Rebuilt for AutoReq cmake-filesystem
+
+* Wed Aug 02 2017 Fedora Release Engineering - 0.6.1-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering - 0.6.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Jun 09 2017 Neal Gompa - 0.6.1-3
+- Update patch based on upstream feedback
+
+* Fri Jun 09 2017 Neal Gompa - 0.6.1-2
+- Adjust soversion patch to maintain binary compat across patch versions
+
+* Fri Jun 09 2017 Neal Gompa - 0.6.1-1
+- Update to 0.6.1
+
+* Mon Feb 27 2017 Neal Gompa - 0.5.3-4
+- Add patch to fix FTBFS with GCC 7 (#1423291)
+
+* Fri Feb 10 2017 Fedora Release Engineering - 0.5.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Apr 28 2016 Neal Gompa - 0.5.3-2
+- Add patches to fix ppc builds
+
+* Tue Apr 26 2016 Neal Gompa - 0.5.3-1
+- Initial packaging
diff --git a/SPECS-EXTENDED/catatonit/catatonit.spec b/SPECS-EXTENDED/catatonit/catatonit.spec
index acb4f70a73d..3a766166714 100644
--- a/SPECS-EXTENDED/catatonit/catatonit.spec
+++ b/SPECS-EXTENDED/catatonit/catatonit.spec
@@ -13,7 +13,7 @@ BuildRequires: automake
BuildRequires: file
BuildRequires: gcc
BuildRequires: git
-BuildRequires: glibc-static >= 2.38-5%{?dist}
+BuildRequires: glibc-static >= 2.38-6%{?dist}
BuildRequires: libtool
BuildRequires: make
diff --git a/SPECS/cri-o/cri-o-rpmlintrc b/SPECS-EXTENDED/cri-o/cri-o-rpmlintrc
similarity index 100%
rename from SPECS/cri-o/cri-o-rpmlintrc
rename to SPECS-EXTENDED/cri-o/cri-o-rpmlintrc
diff --git a/SPECS/cri-o/cri-o.signatures.json b/SPECS-EXTENDED/cri-o/cri-o.signatures.json
similarity index 100%
rename from SPECS/cri-o/cri-o.signatures.json
rename to SPECS-EXTENDED/cri-o/cri-o.signatures.json
diff --git a/SPECS/cri-o/cri-o.spec b/SPECS-EXTENDED/cri-o/cri-o.spec
similarity index 100%
rename from SPECS/cri-o/cri-o.spec
rename to SPECS-EXTENDED/cri-o/cri-o.spec
diff --git a/SPECS/cri-o/crio.conf b/SPECS-EXTENDED/cri-o/crio.conf
similarity index 100%
rename from SPECS/cri-o/crio.conf
rename to SPECS-EXTENDED/cri-o/crio.conf
diff --git a/SPECS/cri-o/crio.service b/SPECS-EXTENDED/cri-o/crio.service
similarity index 100%
rename from SPECS/cri-o/crio.service
rename to SPECS-EXTENDED/cri-o/crio.service
diff --git a/SPECS/cri-o/generate_source_tarball.sh b/SPECS-EXTENDED/cri-o/generate_source_tarball.sh
similarity index 100%
rename from SPECS/cri-o/generate_source_tarball.sh
rename to SPECS-EXTENDED/cri-o/generate_source_tarball.sh
diff --git a/SPECS/cri-o/kubelet.env b/SPECS-EXTENDED/cri-o/kubelet.env
similarity index 100%
rename from SPECS/cri-o/kubelet.env
rename to SPECS-EXTENDED/cri-o/kubelet.env
diff --git a/SPECS/cri-o/sysconfig.crio b/SPECS-EXTENDED/cri-o/sysconfig.crio
similarity index 100%
rename from SPECS/cri-o/sysconfig.crio
rename to SPECS-EXTENDED/cri-o/sysconfig.crio
diff --git a/SPECS-EXTENDED/dyninst/dyninst.spec b/SPECS-EXTENDED/dyninst/dyninst.spec
index 511ecf4baaf..2448eecd356 100644
--- a/SPECS-EXTENDED/dyninst/dyninst.spec
+++ b/SPECS-EXTENDED/dyninst/dyninst.spec
@@ -31,7 +31,7 @@ BuildRequires: tbb tbb-devel
# Extra requires just for the testsuite
BuildRequires: gcc-gfortran libstdc++-static libxml2-devel
-BuildRequires: glibc-static >= 2.38-5%{?dist}
+BuildRequires: glibc-static >= 2.38-6%{?dist}
# Testsuite files should not provide/require anything
%{?filter_setup:
diff --git a/SPECS-EXTENDED/podman/podman.spec b/SPECS-EXTENDED/podman/podman.spec
index 525690b6b8f..add84212ce4 100644
--- a/SPECS-EXTENDED/podman/podman.spec
+++ b/SPECS-EXTENDED/podman/podman.spec
@@ -50,7 +50,7 @@ BuildRequires: go-md2man
BuildRequires: golang
BuildRequires: gcc
BuildRequires: glib2-devel
-BuildRequires: glibc-static >= 2.38-5%{?dist}
+BuildRequires: glibc-static >= 2.38-6%{?dist}
BuildRequires: git
BuildRequires: go-rpm-macros
BuildRequires: gpgme-devel
diff --git a/SPECS-EXTENDED/argparse-manpage/argparse-manpage.signatures.json b/SPECS-EXTENDED/python-argparse-manpage/python-argparse-manpage.signatures.json
similarity index 100%
rename from SPECS-EXTENDED/argparse-manpage/argparse-manpage.signatures.json
rename to SPECS-EXTENDED/python-argparse-manpage/python-argparse-manpage.signatures.json
diff --git a/SPECS-EXTENDED/argparse-manpage/argparse-manpage.spec b/SPECS-EXTENDED/python-argparse-manpage/python-argparse-manpage.spec
similarity index 90%
rename from SPECS-EXTENDED/argparse-manpage/argparse-manpage.spec
rename to SPECS-EXTENDED/python-argparse-manpage/python-argparse-manpage.spec
index f849f13fe5f..8c77828b5dd 100644
--- a/SPECS-EXTENDED/argparse-manpage/argparse-manpage.spec
+++ b/SPECS-EXTENDED/python-argparse-manpage/python-argparse-manpage.spec
@@ -1,5 +1,6 @@
Vendor: Microsoft Corporation
Distribution: Azure Linux
+%global modname argparse-manpage
%global sum() Build manual page from %* ArgumentParser object
%global desc \
@@ -11,33 +12,33 @@ specify that by (a) the module name or corresponding python filename and \
There is a limited support for (deprecated) optparse objects, too.
-Name: argparse-manpage
+Name: python-%{modname}
Version: 1.5
Release: 3%{?dist}
Summary: %{sum Python}
BuildArch: noarch
License: ASL 2.0
-URL: https://github.com/praiskup/%{name}
-Source0: %pypi_source
+URL: https://github.com/praiskup/%{modname}
+Source0: %pypi_source argparse-manpage
BuildRequires: python3-setuptools python3-devel
%if 0%{?with_check}
BuildRequires: python3-pip
%endif
-Requires: python3-%{name} = %{version}-%{release}
+Requires: python3-%{modname} = %{version}-%{release}
%description
%desc
-%package -n python3-%name
+%package -n python3-%{modname}
Summary: %{sum Python 3}
-%description -n python3-%name
+%description -n python3-%{modname}
%{desc}
%prep
-%setup -q
+%setup -q -n %{modname}-%{version}
%build
%py3_build
@@ -59,7 +60,7 @@ pip3 install pytest==7.1.2 six==1.16.0
%{_mandir}/man1/argparse-manpage.1.*
%{python3_sitelib}/build_manpages/cli
-%files -n python3-%name
+%files -n python3-%{modname}
%license LICENSE
%{python3_sitelib}/build_manpages
%{python3_sitelib}/argparse_manpage-%{version}*.egg-info
diff --git a/SPECS-EXTENDED/rr/rr.signatures.json b/SPECS-EXTENDED/rr/rr.signatures.json
new file mode 100644
index 00000000000..98b5c7e7f5d
--- /dev/null
+++ b/SPECS-EXTENDED/rr/rr.signatures.json
@@ -0,0 +1,5 @@
+{
+ "Signatures": {
+ "rr-5.8.0.tar.gz": "8b162a3340a6ddb29170b359fe0f2e023f86a9bfea035555b74d38d9fc5e0c00"
+ }
+}
diff --git a/SPECS-EXTENDED/rr/rr.spec b/SPECS-EXTENDED/rr/rr.spec
new file mode 100644
index 00000000000..a6a7742372a
--- /dev/null
+++ b/SPECS-EXTENDED/rr/rr.spec
@@ -0,0 +1,236 @@
+# Force out of source build
+%undefine __cmake_in_source_build
+
+%global commit da33770d22b404d7333e46e26495eaca0c5a6d8a
+%global gittag 5.8.0
+%global shortcommit %(c=%{commit}; echo ${c:0:7})
+
+ExclusiveArch: %{ix86} x86_64 aarch64
+
+# Disable 32-bit builds on architectures with multilibs
+# to avoid attempting pulling in 32-bit in to koji build.
+%ifarch x86_64
+%global disable32bit -Ddisable32bit=ON
+%endif
+Summary: Tool to record and replay execution of applications
+Name: rr
+Version: 5.8.0
+Release: 2%{?dist}
+# The entire source code is MIT with the exceptions of
+# files in following directories:
+# third-party/blake2 CC0
+# third-party/gdb BSD
+# third-party/proc-service BSD
+# third-party/zen-pmu-workaround GPLv2
+License: MIT and CC0 and BSD and GPLv2
+Vendor: Microsoft Corporation
+Distribution: Azure Linux
+URL: http://rr-project.org
+
+Source: https://github.com/rr-debugger/rr/archive/%{gittag}/%{name}-%{version}.tar.gz
+
+%if 0%{?rhel} == 7
+BuildRequires: cmake3
+BuildRequires: python36-pexpect
+%else
+BuildRequires: cmake
+BuildRequires: python3-pexpect
+%endif
+BuildRequires: python3
+BuildRequires: make gcc gcc-c++ gdb
+BuildRequires: libgcc
+BuildRequires: glibc-devel
+BuildRequires: libstdc++-devel
+BuildRequires: man-pages
+BuildRequires: capnproto capnproto-libs capnproto-devel
+BuildRequires: patchelf
+BuildRequires: zlib-devel
+
+%description
+rr is a lightweight tool for recording and replaying execution
+of applications (trees of processes and threads).
+For more information, please visit http://rr-project.org
+
+%package testsuite
+Summary: Testsuite for checking rr functionality
+Requires: rr
+Requires: gdb
+Requires: python3
+%if 0%{?rhel} == 7
+Requires: python36-pexpect
+Requires: cmake3
+%else
+Requires: python3-pexpect
+Requires: cmake
+%endif
+%description testsuite
+rr-testsuite includes compiled test binaries and other files
+which are used to test the functionality of rr.
+
+%prep
+%autosetup -p1 -n rr-%{gittag}
+
+%build
+%if 0%{?rhel} == 7
+%cmake3 -DCMAKE_BUILD_TYPE=Release -DINSTALL_TESTSUITE=ON %{?disable32bit}
+%cmake3_build
+%else
+%cmake -DCMAKE_BUILD_TYPE=Release -DINSTALL_TESTSUITE=ON %{?disable32bit}
+%cmake_build
+%endif
+
+%install
+%if 0%{?rhel} == 7
+%cmake3_install
+%else
+%cmake_install
+%endif
+
+rm -rf %{buildroot}%{_datadir}/rr/src
+
+# Using a small hack from the Dyninst testsuite which changes file permissions
+# to prevent any stripping of debugging information. This is done for libraries
+# and executables used by the testsuite.
+find %{buildroot}%{_libdir}/rr/testsuite/obj/bin \
+ -type f -name '*' -execdir chmod 644 '{}' '+'
+
+find %{buildroot}%{_libdir} \
+ -type f -name '*.so' -execdir chmod 644 '{}' '+'
+
+# Some files contain invalid RPATHS.
+patchelf --set-rpath '%{_libdir}/rr/' %{buildroot}%{_libdir}/rr/testsuite/obj/bin/constructor
+patchelf --set-rpath '%{_libdir}/rr/' %{buildroot}%{_libdir}/rr/testsuite/obj/bin/step_into_lib
+
+%files
+%dir %{_libdir}/rr
+%{_libdir}/rr/*.so
+%exclude %{_libdir}/rr/libtest_lib*.so
+%{_bindir}/rr
+%{_bindir}/rr_exec_stub*
+%{_bindir}/signal-rr-recording.sh
+%{_bindir}/rr-collect-symbols.py
+%{_datadir}/bash-completion/completions/rr
+%dir %{_datadir}/rr
+%{_datadir}/rr/*.xml
+
+%attr(755,root,root) %{_libdir}/rr/*.so
+
+%files testsuite
+%{_libdir}/rr/libtest_lib*.so
+%dir %{_libdir}/rr/testsuite
+%{_libdir}/rr/testsuite/*
+
+%attr(755,root,root) %{_libdir}/rr/libtest_lib*.so
+%attr(755,root,root) %{_libdir}/rr/testsuite/obj/bin/*
+
+%license LICENSE
+
+%changelog
+* Fri Jun 14 2024 Henry Beberman - 5.8.0-2
+- Initial Azure Linux import from Fedora 41 (license: MIT).
+- License verified.
+
+* Mon May 20 2024 William Cohen - 5.8.0-1
+- Rebase to rr-5.8.0.
+
+* Fri Jan 26 2024 Fedora Release Engineering - 5.7.0-11
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Mon Jan 22 2024 Fedora Release Engineering - 5.7.0-10
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Wed Oct 4 2023 William Cohen - 5.7.0-9
+- Rebase to rr-5.7.0.
+
+* Tue Sep 12 2023 William Cohen - 5.6.0-8
+- Rebuild for capnproto 1.0.1
+
+* Fri Sep 08 2023 Neal Gompa - 5.6.0-7
+- Rebuild for capnproto 1.0.1
+
+* Fri Jul 21 2023 Fedora Release Engineering - 5.6.0-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Wed Jan 18 2023 William Cohen - 5.6.0-5
+- Fix FTBFS issue with gcc-13.
+
+* Sat Dec 3 2022 Florian Weimer - 5.6.0-4
+- Avoid implicit function declaration in test (C99 compatibility)
+
+* Fri Dec 02 2022 Fabio Valentini - 5.6.0-3
+- Rebuild for capnproto 0.10.3 / CVE-2022-46149
+
+* Tue Nov 29 2022 Neal Gompa - 5.6.0-2
+- Rebuild for capnproto 0.10.2
+
+* Mon Aug 8 2022 William Cohen - 5.6.0-1
+- Rebase to rr-5.6.0.
+
+* Fri Aug 5 2022 William Cohen - 5.5.0-5.20220805gitda33770
+- Sync with upstream branch master,
+ commit da33770d22b404d7333e46e26495eaca0c5a6d8a.
+
+* Sat Jul 23 2022 Fedora Release Engineering - 5.5.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Fri Jan 21 2022 Fedora Release Engineering - 5.5.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Tue Dec 21 2021 Neal Gompa - 5.5.0-2
+- Rebuild for capnproto 0.9.1
+
+* Mon Sep 20 2021 William Cohen - 5.5.0-1
+- Rebase to rr-5.5.0.
+
+* Thu Jul 29 2021 William Cohen - 5.4.0-4
+- Fix FTBFS (rhbz#1987924)
+
+* Fri Jul 23 2021 Fedora Release Engineering - 5.4.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Wed Jan 27 2021 Fedora Release Engineering - 5.4.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Mon Nov 2 2020 William Cohen - 5.4.0-1
+- Rebase to rr-5.4.0.
+
+* Fri Aug 28 2020 Sagar Patel - 5.3.0-19.20200828gitb53e4d9
+- Sync with upstream branch master,
+ commit b53e4d990b873e1b57284994ad7a65f3626880f5.
+- Fix package requirements for rr-testsuite.
+- Note: There is an issue causing rr to hang on RHEL7 (RHBZ#1873266).
+- Note: There are some pathing issues with rr-testsuite.
+
+* Wed Jul 29 2020 Fedora Release Engineering - 5.3.0-17.20200427gitbab9ca9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Sat Jul 18 2020 Neal Gompa - 5.3.0-16.20200427gitbab9ca9
+- Rebuilt for capnproto 0.8.0 again
+
+* Sat Jul 18 2020 Neal Gompa - 5.3.0-15.20200427gitbab9ca9
+- Rebuilt for capnproto 0.8.0
+
+* Mon Apr 27 2020 Sagar Patel 14.20200427gitbab9ca9
+- Sync with upstream branch master,
+ commit bab9ca94fc03d893cf6b8bf58f7b4522a0113466.
+- Build failures from the previous release are now fixed.
+
+* Fri Apr 24 2020 Sagar Patel 13.20200424gitcf5169b
+- Sync with upstream branch master,
+ commit cf5169bb3e29ce9db4a73e26164bec0e92b083fb.
+- Introduces support for installable testsuite.
+
+* Mon Feb 24 2020 Sagar Patel 11.20200224git4513b23
+- Sync with upstream branch master,
+ commit 4513b23c8092097dc42c73f3cbaf4cfaebd04efe.
+- New patches enable rr to be built on older compilers.
+
+* Thu Feb 13 2020 Sagar Patel 10.20200213gitabd3442
+- Sync with upstream branch master,
+ commit abd344288878c9b4046e0b8664927992947a46eb.
+- New patches enable rr to be built on RHEL7.2 and later.
+
+* Tue Jan 14 2020 William Cohen 5.3.0-8.20200124git7908fea
+- Sync with upstream branch master,
+ commit 70ba28f7ab2923d4e36ffc9d5d2e32357353b25c.
+- SRPM buildable on Fedora koji or other rpm build systems.
diff --git a/SPECS-SIGNED/grub2-efi-binary-signed/grub2-efi-binary-signed.spec b/SPECS-SIGNED/grub2-efi-binary-signed/grub2-efi-binary-signed.spec
index c7f1b7b1acc..3d27aacf30f 100644
--- a/SPECS-SIGNED/grub2-efi-binary-signed/grub2-efi-binary-signed.spec
+++ b/SPECS-SIGNED/grub2-efi-binary-signed/grub2-efi-binary-signed.spec
@@ -11,8 +11,8 @@
%endif
Summary: Signed GRand Unified Bootloader for %{buildarch} systems
Name: grub2-efi-binary-signed-%{buildarch}
-Version: 2.06
-Release: 18%{?dist}
+Version: 2.12
+Release: 1%{?dist}
License: GPLv3+
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -79,6 +79,12 @@ cp %{SOURCE3} %{buildroot}/boot/efi/EFI/BOOT/%{grubpxeefiname}
/boot/efi/EFI/BOOT/%{grubpxeefiname}
%changelog
+* Fri Jun 14 2024 Gary Swalling - 2.12-1
+- Match grub2 version and release numbers
+
+* Wed Jun 12 2024 George Mileka - 2.06-19
+- disable code optimization for ip checksum calculation
+
* Mon Apr 15 2024 Dan Streetman - 2.06-18
- update grub to sbat 4
diff --git a/SPECS-SIGNED/kernel-signed/kernel-signed.spec b/SPECS-SIGNED/kernel-signed/kernel-signed.spec
index 79b62ee9a41..7f6613b5031 100644
--- a/SPECS-SIGNED/kernel-signed/kernel-signed.spec
+++ b/SPECS-SIGNED/kernel-signed/kernel-signed.spec
@@ -10,7 +10,7 @@
Summary: Signed Linux Kernel for %{buildarch} systems
Name: kernel-signed-%{buildarch}
Version: 6.6.29.1
-Release: 4%{?dist}
+Release: 5%{?dist}
License: GPLv2
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -145,6 +145,9 @@ echo "initrd of kernel %{uname_r} removed" >&2
%exclude /module_info.ld
%changelog
+* Tue Jun 11 2024 Juan Camposeco 6.6.29.1-5
+- Add patch to enable mstflint kernel driver
+
* Fri May 31 2024 Thien Trung Vuong - 6.6.29.1-4
- Bump release to match kernel
diff --git a/SPECS/annobin/annobin.spec b/SPECS/annobin/annobin.spec
index 0b5ae36b0db..53fee070300 100644
--- a/SPECS/annobin/annobin.spec
+++ b/SPECS/annobin/annobin.spec
@@ -19,13 +19,14 @@
Summary: Binary annotation plugin for GCC
Name: annobin
Version: 12.49
-Release: 1%{?dist}
+Release: 2%{?dist}
License: GPL-3.0-or-later AND LGPL-2.0-or-later AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND GFDL-1.3-or-later
Vendor: Microsoft Corporation
Distribution: Azure Linux
URL: https://sourceware.org/annobin/
Source: https://nickc.fedorapeople.org/%{annobin_sources}
Requires: %{name}-plugin-clang
+
# Insert patches here, if needed. Eg:
# Patch01: annobin-plugin-default-string-notes.patch
#---------------------------------------------------------------------------------
@@ -236,7 +237,7 @@ touch doc/annobin.info
#---------------------------------------------------------------------------------
%build
-CONFIG_ARGS="$CONFIG_ARGS --quiet --with-debuginfod --with-clang --with-gcc-plugin-dir=%{ANNOBIN_GCC_PLUGIN_DIR} --with-llvm"
+CONFIG_ARGS="$CONFIG_ARGS --quiet --without-debuginfod --with-clang --with-gcc-plugin-dir=%{ANNOBIN_GCC_PLUGIN_DIR} --with-llvm"
export CFLAGS="$CFLAGS -DAARCH64_BRANCH_PROTECTION_SUPPORTED=1"
@@ -352,6 +353,10 @@ make check || ( cat tests/test-suite.log; false )
#---------------------------------------------------------------------------------
%changelog
+* Thu Jun 13 2024 Sam Meluch - 12.40-2
+- build package --without-debuginfod
+- fix package tests
+
* Fri Mar 08 2024 Mykhailo Bykhovtsev - 12.40-1
- Promoted package from extended to core
- Upgraded to 12.49
diff --git a/SPECS/azurelinux-release/azurelinux-release.spec b/SPECS/azurelinux-release/azurelinux-release.spec
index 23a38fbcdd8..70fac2d5bbc 100644
--- a/SPECS/azurelinux-release/azurelinux-release.spec
+++ b/SPECS/azurelinux-release/azurelinux-release.spec
@@ -5,7 +5,7 @@
Summary: Azure Linux release files
Name: azurelinux-release
Version: %{dist_version}.0
-Release: 14%{?dist}
+Release: 15%{?dist}
License: MIT
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -118,6 +118,9 @@ install -Dm0644 %{SOURCE4} -t %{buildroot}%{_sysctldir}/
%{_sysctldir}/*.conf
%changelog
+* Thu Jun 21 2024 Andrew Phelps - 3.0-15
+- Azure Linux 3.0 June Preview Release 2
+
* Wed Jun 12 2024 Sam Meluch - 3.0-14
- Azure Linux 3.0 June Preview Release 1
diff --git a/SPECS/babel/babel.signatures.json b/SPECS/babel/babel.signatures.json
index 7264a5a8829..642ce9cfdc6 100644
--- a/SPECS/babel/babel.signatures.json
+++ b/SPECS/babel/babel.signatures.json
@@ -1,5 +1,5 @@
{
"Signatures": {
- "Babel-2.12.1.tar.gz": "cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"
+ "babel-2.15.0.tar.gz": "8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"
}
}
diff --git a/SPECS/babel/babel.spec b/SPECS/babel/babel.spec
index 0e9072bf358..4cb048c34f3 100644
--- a/SPECS/babel/babel.spec
+++ b/SPECS/babel/babel.spec
@@ -1,13 +1,13 @@
Summary: An integrated collection of utilities that assist in internationalizing and localizing Python applications
Name: babel
-Version: 2.12.1
+Version: 2.15.0
Release: 1%{?dist}
License: BSD
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: Development/Languages/Python
URL: https://babel.pocoo.org
-Source0: https://files.pythonhosted.org/packages/ba/42/54426ba5d7aeebde9f4aaba9884596eb2fe02b413ad77d62ef0b0422e205/Babel-%{version}.tar.gz
+Source0: https://files.pythonhosted.org/packages/15/d2/9671b93d623300f0aef82cde40e25357f11330bdde91743891b22a555bed/%{name}-%{version}.tar.gz
BuildRequires: python3-devel
BuildRequires: python3-pytest
BuildRequires: python3-pytz
@@ -19,6 +19,8 @@ BuildRequires: openssl-devel
BuildRequires: python3-attrs
BuildRequires: python3-pip
BuildRequires: python3-six
+BuildRequires: python3-pytest
+BuildRequires: python3-pluggy
%endif
Requires: python3
Requires: python3-pytz
@@ -34,7 +36,7 @@ The functionality Babel provides for internationalization (I18n) and localizatio
2.A Python interface to the CLDR (Common Locale Data Repository), providing access to various locale display names, localized number and date formatting, etc.
%prep
-%autosetup -n Babel-%{version}
+%autosetup -n babel-%{version}
%build
%py3_build
@@ -44,8 +46,8 @@ The functionality Babel provides for internationalization (I18n) and localizatio
ln -sfv pybabel %{buildroot}/%{_bindir}/pybabel3
%check
-pip3 install pytest freezegun funcsigs pathlib2 pluggy utils
-%{python3} setup.py test
+pip3 install freezegun funcsigs pathlib2 utils iniconfig
+%pytest
%files
%defattr(-,root,root,-)
@@ -55,6 +57,10 @@ pip3 install pytest freezegun funcsigs pathlib2 pluggy utils
%{python3_sitelib}/*
%changelog
+* Fri Jun 14 2024 Sam Meluch - 2.15.0-1
+- fix package tests
+- upgrade to 2.15.0 for python 3.12 support
+
* Thu Nov 02 2023 CBL-Mariner Servicing Account - 2.12.1-1
- Auto-upgrade to 2.12.1 - Azure Linux 3.0 - package upgrades
diff --git a/SPECS/bash/bash-2.03-profile.patch b/SPECS/bash/bash-2.03-profile.patch
new file mode 100644
index 00000000000..ba3344b3cc1
--- /dev/null
+++ b/SPECS/bash/bash-2.03-profile.patch
@@ -0,0 +1,12 @@
+diff -up bash-3.2/config-top.h.profile bash-3.2/config-top.h
+--- bash-3.2/config-top.h.profile 2008-07-17 13:35:39.000000000 +0200
++++ bash-3.2/config-top.h 2008-07-17 13:42:18.000000000 +0200
+@@ -26,6 +26,8 @@
+ what POSIX.2 specifies. */
+ #define CONTINUE_AFTER_KILL_ERROR
+
++#define NON_INTERACTIVE_LOGIN_SHELLS
++
+ /* Define BREAK_COMPLAINS if you want the non-standard, but useful
+ error messages about `break' and `continue' out of context. */
+ #define BREAK_COMPLAINS
diff --git a/SPECS/bash/bash.spec b/SPECS/bash/bash.spec
index c5ee6f5a61c..4b37ec039e0 100644
--- a/SPECS/bash/bash.spec
+++ b/SPECS/bash/bash.spec
@@ -1,7 +1,7 @@
Summary: Bourne-Again SHell
Name: bash
Version: 5.2.15
-Release: 1%{?dist}
+Release: 2%{?dist}
License: GPLv3
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -10,6 +10,8 @@ URL: https://www.gnu.org/software/bash/
Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz
Source1: bash_completion
Patch0: bash-5.1.patch
+# Non-interactive shells beginning with argv[0][0] == '-' should run the startup files when not in posix mode.
+Patch1: bash-2.03-profile.patch
BuildRequires: readline
Requires: readline
Requires(post): /bin/cp
@@ -328,6 +330,10 @@ fi
%defattr(-,root,root)
%changelog
+* Mon Jun 17 2024 Daniel McIlvaney - 5.2.15-2
+- When non-interactive shells are started with '-bash' load startup files. From
+- Fedora upstream: https://src.fedoraproject.org/rpms/bash/blob/f40/f/bash-2.03-profile.patch
+
* Tue Nov 21 2023 Andrew Phelps - 5.2.15-1
- Upgrade to version 5.2.15
diff --git a/SPECS/bluez/CVE-2023-50229-CVE-2023-50230.patch b/SPECS/bluez/CVE-2023-50229-CVE-2023-50230.patch
new file mode 100644
index 00000000000..d6fb603e58d
--- /dev/null
+++ b/SPECS/bluez/CVE-2023-50229-CVE-2023-50230.patch
@@ -0,0 +1,63 @@
+From 5ab5352531a9cc7058cce569607f3a6831464443 Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz
+Date: Tue, 19 Sep 2023 12:14:01 -0700
+Subject: [PATCH] pbap: Fix not checking Primary/Secundary Counter length
+
+Primary/Secundary Counters are supposed to be 16 bytes values, if the
+server has implemented them incorrectly it may lead to the following
+crash:
+
+=================================================================
+==31860==ERROR: AddressSanitizer: heap-buffer-overflow on address
+0x607000001878 at pc 0x7f95a1575638 bp 0x7fff58c6bb80 sp 0x7fff58c6b328
+
+ READ of size 48 at 0x607000001878 thread T0
+ #0 0x7f95a1575637 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:860
+ #1 0x7f95a1575ba6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:892
+ #2 0x7f95a1575ba6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:887
+ #3 0x564df69c77a0 in read_version obexd/client/pbap.c:288
+ #4 0x564df69c77a0 in read_return_apparam obexd/client/pbap.c:352
+ #5 0x564df69c77a0 in phonebook_size_callback obexd/client/pbap.c:374
+ #6 0x564df69bea3c in session_terminate_transfer obexd/client/session.c:921
+ #7 0x564df69d56b0 in get_xfer_progress_first obexd/client/transfer.c:729
+ #8 0x564df698b9ee in handle_response gobex/gobex.c:1140
+ #9 0x564df698cdea in incoming_data gobex/gobex.c:1385
+ #10 0x7f95a12fdc43 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55c43)
+ #11 0x7f95a13526c7 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xaa6c7)
+ #12 0x7f95a12fd2b2 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x552b2)
+ #13 0x564df6977d41 in main obexd/src/main.c:307
+ #14 0x7f95a10a7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
+ #15 0x7f95a10a7e3f in __libc_start_main_impl ../csu/libc-start.c:392
+ #16 0x564df6978704 in _start (/usr/local/libexec/bluetooth/obexd+0x8b704)
+ 0x607000001878 is located 0 bytes to the right of 72-byte region [0x607000001830,0x607000001878)
+
+ allocated by thread T0 here:
+ #0 0x7f95a1595a37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
+ #1 0x564df69c8b6a in pbap_probe obexd/client/pbap.c:1259
+---
+ obexd/client/pbap.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c
+index 1ed8c68ecc..2d2aa95089 100644
+--- a/obexd/client/pbap.c
++++ b/obexd/client/pbap.c
+@@ -285,7 +285,7 @@ static void read_version(struct pbap_data *pbap, GObexApparam *apparam)
+ data = value;
+ }
+
+- if (memcmp(pbap->primary, data, len)) {
++ if (len == sizeof(pbap->primary) && memcmp(pbap->primary, data, len)) {
+ memcpy(pbap->primary, data, len);
+ g_dbus_emit_property_changed(conn,
+ obc_session_get_path(pbap->session),
+@@ -299,7 +299,8 @@ static void read_version(struct pbap_data *pbap, GObexApparam *apparam)
+ data = value;
+ }
+
+- if (memcmp(pbap->secondary, data, len)) {
++ if (len == sizeof(pbap->secondary) &&
++ memcmp(pbap->secondary, data, len)) {
+ memcpy(pbap->secondary, data, len);
+ g_dbus_emit_property_changed(conn,
+ obc_session_get_path(pbap->session),
diff --git a/SPECS/bluez/bluez.spec b/SPECS/bluez/bluez.spec
index 586f2ea35c7..68c5bf759d0 100644
--- a/SPECS/bluez/bluez.spec
+++ b/SPECS/bluez/bluez.spec
@@ -1,7 +1,7 @@
Summary: Bluetooth utilities
Name: bluez
Version: 5.63
-Release: 4%{?dist}
+Release: 5%{?dist}
License: GPLv2+ AND LGPLv2+
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -24,6 +24,7 @@ Patch6: 0002-Use-g_memdup2-everywhere.patch
Patch7: 0001-hog-Fix-read-order-of-attributes-rediffed.patch
Patch8: 0002-hog-Add-input-queue-while-uhid-device-has-not-been-c-rediffed.patch
Patch9: CVE-2022-3563.patch
+Patch10: CVE-2023-50229-CVE-2023-50230.patch
BuildRequires: autoconf
BuildRequires: automake
# For printing
@@ -272,6 +273,9 @@ install emulator/btvirt %{buildroot}/%{_libexecdir}/bluetooth/
%{_userunitdir}/obex.service
%changelog
+* Fri Jun 21 2024 Neha Agarwal - 5.63-5
+- Patch CVE-2023-50229 and CVE-2023-50230
+
* Mon Oct 02 2023 Minghe Ren - 5.63-4
- Add patch for CVE-2022-3563
diff --git a/SPECS/brotli/brotli.spec b/SPECS/brotli/brotli.spec
index 29e6bb78f6d..6cc0f2291c8 100644
--- a/SPECS/brotli/brotli.spec
+++ b/SPECS/brotli/brotli.spec
@@ -1,7 +1,7 @@
Summary: Lossless compression algorithm
Name: brotli
Version: 1.1.0
-Release: 1%{?dist}
+Release: 2%{?dist}
License: MIT
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -78,10 +78,7 @@ done
%postun -p /sbin/ldconfig
%check
-make test
-test_result=$?
-make clean
-[[ $test_result -eq 0 ]]
+%ctest
%files
%{_bindir}/brotli
@@ -113,6 +110,9 @@ make clean
%{_mandir}/man3/constants.h.3brotli*
%changelog
+* Fri Jun 14 2024 Sam Meluch - 1.1.0-2
+- fix package tests
+
* Wed Dec 13 2023 Andrew Phelps - 1.1.0-1
- Upgrade to version 1.1.0
diff --git a/SPECS/busybox/busybox.spec b/SPECS/busybox/busybox.spec
index a45ecb0906b..dc320f6e41b 100644
--- a/SPECS/busybox/busybox.spec
+++ b/SPECS/busybox/busybox.spec
@@ -12,7 +12,7 @@ Source2: busybox-petitboot.config
Patch0: busybox-1.31.1-stime-fix.patch
Patch1: CVE-2022-28391.patch
BuildRequires: gcc
-BuildRequires: glibc-static >= 2.38-5%{?dist}
+BuildRequires: glibc-static >= 2.38-6%{?dist}
BuildRequires: libselinux-devel >= 1.27.7-2
BuildRequires: libsepol-devel
%if 0%{?with_check}
diff --git a/SPECS/cloud-init/cloud-init.spec b/SPECS/cloud-init/cloud-init.spec
index f06201068b4..feb1c5eeb26 100644
--- a/SPECS/cloud-init/cloud-init.spec
+++ b/SPECS/cloud-init/cloud-init.spec
@@ -1,7 +1,7 @@
Summary: Cloud instance init scripts
Name: cloud-init
Version: 23.4.3
-Release: 2%{?dist}
+Release: 3%{?dist}
License: GPLv3
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -11,6 +11,8 @@ Source0: https://github.com/canonical/%{name}/archive/refs/tags/%{version
Source1: 10-azure-kvp.cfg
Patch0: 0001-Add-new-distro-azurelinux-for-Microsoft-Azure-Linux.patch
Patch1: Add-Network-Interface-Renaming-Support-for-CAPM3-Met.patch
+# Patch no longer needed for cloud-init >= 24.1
+Patch2: dhcp_support_dhclient_unknown_121.patch
%define cl_services cloud-config.service cloud-config.target cloud-final.service cloud-init.service cloud-init.target cloud-init-local.service
BuildRequires: automake
BuildRequires: dbus
@@ -144,7 +146,10 @@ make check %{?_smp_mflags}
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/10-azure-kvp.cfg
%changelog
-* Thu May 9 2024 Sharath Srikanth Chellappa - 23.4.3-2
+* Wed June 06 2024 Minghe Ren - 23.4.3-3
+- Add patch for cloud-init to support dhclient's unknown-121 option
+
+* Thu May 09 2024 Sharath Srikanth Chellappa - 23.4.3-2
- Add patch to add network interface renaming support for CAPM3 Met.
* Mon Feb 26 2024 Dan Streetman - 23.4.3-1
diff --git a/SPECS/cloud-init/dhcp_support_dhclient_unknown_121.patch b/SPECS/cloud-init/dhcp_support_dhclient_unknown_121.patch
new file mode 100644
index 00000000000..f0f493ee07b
--- /dev/null
+++ b/SPECS/cloud-init/dhcp_support_dhclient_unknown_121.patch
@@ -0,0 +1,130 @@
+From 5cf6f3aee2a8af335b36cf573abf48642b94aa65 Mon Sep 17 00:00:00 2001
+From: Chris Patterson
+Date: Thu, 4 Apr 2024 12:16:06 -0400
+Subject: [PATCH] dhcp: support configuring static routes for dhclient's
+ unknown-121 option
+
+Cloud-init does not configure rfc3442-classless-static-routes if dhclient isn't
+patched to support them or it is not configured with:
+
+```
+option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
+```
+
+Example lease with option configured (typical):
+
+lease {
+ interface "eth0";
+ <...cut...>
+ option rfc3442-classless-static-routes 0,10,0,0,1,32,168,63,129,16,10,0,0,1,32,169,254,169,254,10,0,0,1;
+ <...cut...>
+}
+
+Example lease without option, where it is presented as "unknown-121":
+
+lease {
+ interface "eth0";
+ <...cut...>
+ option unknown-121 0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1;
+ <...cut...>
+}
+
+The primary difference is that dhclient outputs the bytes in a
+hex-encoded format and with `:` delimiter. Extend existing
+parsing to support this format.
+
+With a couple added INFO logs, here is a sample DHCP on Azure with
+static routes being parsed from unknown-121 option with this patch:
+
+```
+2024-04-04 16:12:01,677 - ephemeral.py[DEBUG]: Received dhcp lease on eth0 for 10.0.0.11/255.255.255.0
+2024-04-04 16:12:01,677 - dhcp.py[INFO]: Parsing: '0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1'
+2024-04-04 16:12:01,677 - dhcp.py[INFO]: Tokens: ['0', '10', '0', '0', '1', '32', '168', '63', '129', '16', '10', '0', '0', '1', '32', '169', '254', '169', '254', '10', '0', '0', '1']
+2024-04-04 16:12:01,677 - ephemeral.py[DEBUG]: Attempting setup of ephemeral network on eth0 with 10.0.0.11/24 brd 10.0.0.255
+2024-04-04 16:12:01,677 - subp.py[DEBUG]: Running command ['ip', '-family', 'inet', 'addr', 'add', '10.0.0.11/24', 'broadcast', '10.0.0.255', 'dev', 'eth0'] with allowed return codes [0] (shell=False, capture=True)
+2024-04-04 16:12:01,679 - subp.py[DEBUG]: Running command ['ip', '-family', 'inet', 'link', 'set', 'dev', 'eth0', 'up'] with allowed return codes [0] (shell=False, capture=True)
+2024-04-04 16:12:01,681 - subp.py[DEBUG]: Running command ['ip', '-4', 'route', 'append', '0.0.0.0/0', 'via', '10.0.0.1', 'dev', 'eth0'] with allowed return codes [0] (shell=False, capture=True)
+2024-04-04 16:12:01,683 - subp.py[DEBUG]: Running command ['ip', '-4', 'route', 'append', '168.63.129.16/32', 'via', '10.0.0.1', 'dev', 'eth0'] with allowed return codes [0] (shell=False, capture=True)
+2024-04-04 16:12:01,684 - subp.py[DEBUG]: Running command ['ip', '-4', 'route', 'append', '169.254.169.254/32', 'via', '10.0.0.1', 'dev', 'eth0'] with allowed return codes [0] (shell=False, capture=True)
+2024-04-04 16:12:01,686 - handlers.py[DEBUG]: start: azure-ds/_check_if_primary: _check_if_primary
+2024-04-04 16:12:01,686 - handlers.py[DEBUG]: finish: azure-ds/_check_if_primary: SUCCESS: _check_if_primary
+2024-04-04 16:12:01,687 - azure.py[DEBUG]: Obtained DHCP lease on interface 'eth0' (primary=True driver='hv_netvsc' router='10.0.0.1' routes=[('0.0.0.0/0', '10.0.0.1'), ('168.63.129.16/32', '10.0.0.1'), ('169.254.169.254/32', '10.0.0.1')] lease={'inter
+face': 'eth0', 'fixed-address': '10.0.0.11', 'server-name': 'BL24A1071918060SOC', 'subnet-mask': '255.255.255.0', 'dhcp-lease-time': '4294967295', 'routers': '10.0.0.1', 'dhcp-message-type': '5', 'domain-name-servers': '168.63.129.16', 'dhcp-server-ide
+ntifier': '168.63.129.16', 'dhcp-renewal-time': '4294967295', 'unknown-121': '0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1', 'dhcp-rebinding-time': '4294967295', 'unknown-245': 'a8:3f:81:10', 'domain-name': 'fyoqc4gghleevjxtq4h4pjbded.bx.int
+ernal.cloudapp.net', 'renew': '0 2160/05/11 22:40:16', 'rebind': '0 2160/05/11 22:40:16', 'expire': '0 2160/05/11 22:40:16'} imds_routed=True wireserver_routed=True)
+```
+
+Signed-off-by: Chris Patterson
+---
+ cloudinit/net/dhcp.py | 15 ++++++++++++++-
+ cloudinit/net/ephemeral.py | 1 +
+ tests/unittests/net/test_dhcp.py | 11 +++++++++++
+ 3 files changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
+index 07c1339..ce1402a 100644
+--- a/cloudinit/net/dhcp.py
++++ b/cloudinit/net/dhcp.py
+@@ -388,14 +388,27 @@ class IscDhclient(DhcpClient):
+ ("0.0.0.0/0", "192.168.128.1")
+ ]
+
++ # unknown-121 option format
++ sr3 = parse_static_routes(\
++ "0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1")
++ sr3 = [
++ ("0.0.0.0/0", "10.0.0.1"),
++ ("168.63.129.16/32", "10.0.0.1"),
++ ("169.254.169.254/32", "10.0.0.1"),
++ ]
++
+ Python version of isc-dhclient's hooks:
+ /etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes
+ """
+ # raw strings from dhcp lease may end in semi-colon
+ rfc3442 = rfc3442.rstrip(";")
+- tokens = [tok for tok in re.split(r"[, .]", rfc3442) if tok]
++ tokens = [tok for tok in re.split(r"[, . :]", rfc3442) if tok]
+ static_routes = []
+
++ # Handle unknown-121 format by converting hex to base 10.
++ if ":" in rfc3442:
++ tokens = [str(int(tok, 16)) for tok in tokens]
++
+ def _trunc_error(cidr, required, remain):
+ msg = (
+ "RFC3442 string malformed. Current route has CIDR of %s "
+diff --git a/cloudinit/net/ephemeral.py b/cloudinit/net/ephemeral.py
+index 28c851c..d4a1095 100644
+--- a/cloudinit/net/ephemeral.py
++++ b/cloudinit/net/ephemeral.py
+@@ -305,6 +305,7 @@ class EphemeralDHCPv4:
+ "static_routes": [
+ "rfc3442-classless-static-routes",
+ "classless-static-routes",
++ "unknown-121",
+ ],
+ "router": "routers",
+ }
+diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py
+index a7b6231..b75bb40 100644
+--- a/tests/unittests/net/test_dhcp.py
++++ b/tests/unittests/net/test_dhcp.py
+@@ -262,6 +262,17 @@ class TestDHCPParseStaticRoutes(CiTestCase):
+ IscDhclient.parse_static_routes(rfc3442),
+ )
+
++ def test_unknown_121(self):
++ for unknown121 in [
++ "0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1",
++ "0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1;",
++ ]:
++ assert IscDhclient.parse_static_routes(unknown121) == [
++ ("0.0.0.0/0", "10.0.0.1"),
++ ("168.63.129.16/32", "10.0.0.1"),
++ ("169.254.169.254/32", "10.0.0.1"),
++ ]
++
+ def test_parse_static_routes_default_route(self):
+ rfc3442 = "0,130,56,240,1"
+ self.assertEqual(
diff --git a/SPECS/containerized-data-importer/CVE-2024-3727.patch b/SPECS/containerized-data-importer/CVE-2024-3727.patch
new file mode 100644
index 00000000000..92f882851e9
--- /dev/null
+++ b/SPECS/containerized-data-importer/CVE-2024-3727.patch
@@ -0,0 +1,165 @@
+From ea14d57b98cc37decad0c39ccbafb27994274b47 Mon Sep 17 00:00:00 2001
+From: Brian Fjeldstad
+Date: Thu, 6 Jun 2024 21:13:36 +0000
+Subject: [PATCH] apply CVE-2024-3727 fix to v5.19.1
+
+---
+ vendor/github.com/containers/image/v5/docker/docker_client.go | 3 +++
+ vendor/github.com/containers/image/v5/docker/docker_image.go | 8 ++++++--
+ vendor/github.com/containers/image/v5/docker/docker_image_dest.go | 15 ++++++++++++---
+ vendor/github.com/containers/image/v5/docker/docker_image_src.go | 19 +++++++++++++++++--
+ vendor/github.com/containers/image/v5/docker/lookaside.go | 7 +++++--
+ 5 files changed, 43 insertions(+), 9 deletions(-)
+
+diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go
+index 833323b4..99bde923 100644
+--- a/vendor/github.com/containers/image/v5/docker/docker_client.go
++++ b/vendor/github.com/containers/image/v5/docker/docker_client.go
+@@ -796,6 +796,9 @@ func (c *dockerClient) detectProperties(ctx context.Context) error {
+ // getExtensionsSignatures returns signatures from the X-Registry-Supports-Signatures API extension,
+ // using the original data structures.
+ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) {
++ if err := manifestDigest.Validate(); err != nil { // Make sure manifestDigest.String() does not contain any unexpected characters
++ return nil, err
++ }
+ path := fmt.Sprintf(extensionsSignaturePath, reference.Path(ref.ref), manifestDigest)
+ res, err := c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil)
+ if err != nil {
+diff --git a/vendor/github.com/containers/image/v5/docker/docker_image.go b/vendor/github.com/containers/image/v5/docker/docker_image.go
+index c84bb37d..0076d229 100644
+--- a/vendor/github.com/containers/image/v5/docker/docker_image.go
++++ b/vendor/github.com/containers/image/v5/docker/docker_image.go
+@@ -83,8 +83,12 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types.
+ if err = json.NewDecoder(res.Body).Decode(&tagsHolder); err != nil {
+ return nil, err
+ }
+- tags = append(tags, tagsHolder.Tags...)
+-
++ for _, tag := range tagsHolder.Tags {
++ if _, err := reference.WithTag(dr.ref, tag); err != nil { // Ensure the tag does not contain unexpected values
++ return nil, fmt.Errorf("registry returned invalid tag %q: %w", tag, err)
++ }
++ tags = append(tags, tag)
++ }
+ link := res.Header.Get("Link")
+ if link == "" {
+ break
+diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
+index e7af8f93..1096c56f 100644
+--- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
++++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
+@@ -226,6 +226,9 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader,
+ // If the destination does not contain the blob, or it is unknown, blobExists ordinarily returns (false, -1, nil);
+ // it returns a non-nil error only on an unexpected failure.
+ func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference.Named, digest digest.Digest, extraScope *authScope) (bool, int64, error) {
++ if err := digest.Validate(); err != nil { // Make sure digest.String() does not contain any unexpected characters
++ return false, -1, err
++ }
+ checkPath := fmt.Sprintf(blobsPath, reference.Path(repo), digest.String())
+ logrus.Debugf("Checking %s", checkPath)
+ res, err := d.c.makeRequest(ctx, http.MethodHead, checkPath, nil, nil, v2Auth, extraScope)
+@@ -558,8 +561,11 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, m
+
+ // NOTE: Keep this in sync with docs/signature-protocols.md!
+ for i, signature := range signatures {
+- url := signatureStorageURL(d.c.signatureBase, manifestDigest, i)
+- err := d.putOneSignature(url, signature)
++ url, err := signatureStorageURL(d.c.signatureBase, manifestDigest, i)
++ if err != nil {
++ return err
++ }
++ err = d.putOneSignature(url, signature)
+ if err != nil {
+ return err
+ }
+@@ -570,7 +576,10 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, m
+ // is enough for dockerImageSource to stop looking for other signatures, so that
+ // is sufficient.
+ for i := len(signatures); ; i++ {
+- url := signatureStorageURL(d.c.signatureBase, manifestDigest, i)
++ url, err := signatureStorageURL(d.c.signatureBase, manifestDigest, i)
++ if err != nil {
++ return err
++ }
+ missing, err := d.c.deleteOneSignature(url)
+ if err != nil {
+ return err
+diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go
+index 314e9b39..43ca0c4f 100644
+--- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go
++++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go
+@@ -178,6 +178,9 @@ func simplifyContentType(contentType string) string {
+ // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists).
+ func (s *dockerImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) {
+ if instanceDigest != nil {
++ if err := instanceDigest.Validate(); err != nil { // Make sure instanceDigest.String() does not contain any unexpected characters
++ return nil, "", err
++ }
+ return s.fetchManifest(ctx, instanceDigest.String())
+ }
+ err := s.ensureManifestIsLoaded(ctx)
+@@ -373,6 +376,9 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo,
+ return nil, nil, fmt.Errorf("external URLs not supported with GetBlobAt")
+ }
+
++ if err := info.Digest.Validate(); err != nil { // Make sure info.Digest.String() does not contain any unexpected characters
++ return nil, nil, err
++ }
+ path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String())
+ logrus.Debugf("Downloading %s", path)
+ res, err := s.c.makeRequest(ctx, http.MethodGet, path, headers, nil, v2Auth, nil)
+@@ -425,6 +431,9 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca
+ }
+ }
+
++ if err := info.Digest.Validate(); err != nil { // Make sure info.Digest.String() does not contain any unexpected characters
++ return nil, 0, err
++ }
+ path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String())
+ logrus.Debugf("Downloading %s", path)
+ res, err := s.c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil)
+@@ -486,7 +495,10 @@ func (s *dockerImageSource) getSignaturesFromLookaside(ctx context.Context, inst
+ // NOTE: Keep this in sync with docs/signature-protocols.md!
+ signatures := [][]byte{}
+ for i := 0; ; i++ {
+- url := signatureStorageURL(s.c.signatureBase, manifestDigest, i)
++ url, err := signatureStorageURL(s.c.signatureBase, manifestDigest, i)
++ if err != nil {
++ return nil, err
++ }
+ signature, missing, err := s.getOneSignature(ctx, url)
+ if err != nil {
+ return nil, err
+@@ -627,7 +639,10 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere
+ }
+
+ for i := 0; ; i++ {
+- url := signatureStorageURL(c.signatureBase, manifestDigest, i)
++ url, err := signatureStorageURL(c.signatureBase, manifestDigest, i)
++ if err != nil {
++ return err
++ }
+ missing, err := c.deleteOneSignature(url)
+ if err != nil {
+ return err
+diff --git a/vendor/github.com/containers/image/v5/docker/lookaside.go b/vendor/github.com/containers/image/v5/docker/lookaside.go
+index 515e5932..2e400c09 100644
+--- a/vendor/github.com/containers/image/v5/docker/lookaside.go
++++ b/vendor/github.com/containers/image/v5/docker/lookaside.go
+@@ -229,8 +229,11 @@ func (ns registryNamespace) signatureTopLevel(write bool) string {
+ // signatureStorageURL returns an URL usable for accessing signature index in base with known manifestDigest.
+ // base is not nil from the caller
+ // NOTE: Keep this in sync with docs/signature-protocols.md!
+-func signatureStorageURL(base signatureStorageBase, manifestDigest digest.Digest, index int) *url.URL {
++func signatureStorageURL(base signatureStorageBase, manifestDigest digest.Digest, index int) (*url.URL, error) {
++ if err := manifestDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in a path with ../, so validate explicitly.
++ return nil, err
++ }
+ url := *base
+ url.Path = fmt.Sprintf("%s@%s=%s/signature-%d", url.Path, manifestDigest.Algorithm(), manifestDigest.Hex(), index+1)
+- return &url
++ return &url, nil
+ }
+--
+2.34.1
+
diff --git a/SPECS/containerized-data-importer/containerized-data-importer.spec b/SPECS/containerized-data-importer/containerized-data-importer.spec
index a5c94512633..7eabf50fbf1 100644
--- a/SPECS/containerized-data-importer/containerized-data-importer.spec
+++ b/SPECS/containerized-data-importer/containerized-data-importer.spec
@@ -18,13 +18,14 @@
Summary: Container native virtualization
Name: containerized-data-importer
Version: 1.57.0
-Release: 1%{?dist}
+Release: 2%{?dist}
License: ASL 2.0
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: System/Packages
URL: https://github.com/kubevirt/containerized-data-importer
Source0: https://github.com/kubevirt/containerized-data-importer/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
+Patch0: CVE-2024-3727.patch
BuildRequires: golang
BuildRequires: golang-packaging
BuildRequires: libnbd-devel
@@ -108,6 +109,7 @@ kubernetes installation with kubectl apply.
# to be 'physically' placed into the proper location.
%setup -q -n go/src/kubevirt.io/%{name} -c -T
tar --strip-components=1 -xf %{SOURCE0}
+%autopatch -p1
%build
@@ -198,6 +200,9 @@ install -m 0644 _out/manifests/release/cdi-cr.yaml %{buildroot}%{_datadir}/cdi/m
%{_datadir}/cdi/manifests
%changelog
+* Thu Jun 06 2024 Brian Fjeldstad - 1.57.0-2
+- Address CVE-2024-3727 by patching vendored github.com/containers/image
+
* Fri Oct 27 2023 CBL-Mariner Servicing Account - 1.57.0-1
- Auto-upgrade to 1.57.0 - Azure Linux 3.0 - package upgrades
diff --git a/SPECS/coreutils/coreutils-9.4-uname-1.patch b/SPECS/coreutils/coreutils-9.4-uname-1.patch
new file mode 100644
index 00000000000..15f01b19bdd
--- /dev/null
+++ b/SPECS/coreutils/coreutils-9.4-uname-1.patch
@@ -0,0 +1,69 @@
+From e92876a5257bc762eb61c2f12f0338be493ab939 Mon Sep 17 00:00:00 2001
+From: Rachel Menge
+Date: Wed, 29 May 2024 22:27:32 +0000
+Subject: [PATCH] coreutils-9.4 uname patch for -i and -p
+
+Original commit info:
+
+Submitted by: William Immendorf
+Date: 2010-05-08
+Inital Package Version: 8.5
+Origin: http://cvs.fedoraproject.org/viewvc/devel/coreutils/coreutils-8.2-uname-processortype.patch
+Upstream Status: Rejected
+Description: Fixes the output of uname's -i and -p parameters
+---
+ src/uname.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/src/uname.c b/src/uname.c
+index 883b9a4..78641bf 100644
+--- a/src/uname.c
++++ b/src/uname.c
+@@ -313,7 +313,7 @@ main (int argc, char **argv)
+
+ if (toprint & PRINT_PROCESSOR)
+ {
+- char const *element = unknown;
++ char *element = unknown;
+ #ifdef __APPLE__
+ # if defined __arm__ || defined __arm64__
+ element = "arm";
+@@ -330,6 +330,12 @@ main (int argc, char **argv)
+ if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
+ element = processor;
+ }
++#else
++ {
++ struct utsname u;
++ uname(&u);
++ element = u.machine;
++ }
+ #endif
+ #ifdef UNAME_PROCESSOR
+ if (element == unknown)
+@@ -347,7 +353,7 @@ main (int argc, char **argv)
+
+ if (toprint & PRINT_HARDWARE_PLATFORM)
+ {
+- char const *element = unknown;
++ char *element = unknown;
+ #if HAVE_SYSINFO && defined SI_PLATFORM
+ {
+ static char hardware_platform[257];
+@@ -355,6 +361,14 @@ main (int argc, char **argv)
+ hardware_platform, sizeof hardware_platform))
+ element = hardware_platform;
+ }
++#else
++ {
++ struct utsname u;
++ uname(&u);
++ element = u.machine;
++ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6')
++ element[1]='3';
++ }
+ #endif
+ #ifdef UNAME_HARDWARE_PLATFORM
+ if (element == unknown)
+--
+2.34.1
diff --git a/SPECS/coreutils/coreutils.spec b/SPECS/coreutils/coreutils.spec
index ef32e5c6c75..8a2ee7b6745 100644
--- a/SPECS/coreutils/coreutils.spec
+++ b/SPECS/coreutils/coreutils.spec
@@ -1,7 +1,7 @@
Summary: Basic system utilities
Name: coreutils
Version: 9.4
-Release: 2%{?dist}
+Release: 3%{?dist}
License: GPLv3
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -11,6 +11,7 @@ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz
# make this package to own serial console profile since it utilizes stty tool
Source1: serial-console.sh
Patch0: coreutils-9.4-i18n-1.patch
+Patch1: coreutils-9.4-uname-1.patch
BuildRequires: libselinux-devel
BuildRequires: libselinux-utils
Requires: gmp
@@ -91,6 +92,9 @@ LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8 make -k check
%defattr(-,root,root)
%changelog
+* Mon Jun 17 2024 Andrew Phelps - 9.4-3
+- add coreutils-9.4-uname-1.patch
+
* Wed Mar 20 2024 Dan Streetman - 9.4-2
- fix serial-console.sh
diff --git a/SPECS/crash/crash.spec b/SPECS/crash/crash.spec
index ca4cf709f35..4ce251310f1 100644
--- a/SPECS/crash/crash.spec
+++ b/SPECS/crash/crash.spec
@@ -1,11 +1,11 @@
%global gdb_version 10.2
Name: crash
Version: 8.0.4
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: kernel crash analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Group: Development/Tools
Vendor: Microsoft Corporation
-Distribution: Azure Linux
+Distribution: Azure Linux
URL: https://github.com/crash-utility/crash
Source0: https://github.com/crash-utility/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
# crash requires gdb tarball for the build. There is no option to use the host gdb. For crash 8.0.1 the newest supported gdb version is 10.2.
@@ -36,17 +36,41 @@ The core analysis suite is a self-contained tool that can be used to investigate
This package contains libraries and header files need for development.
+%ifarch x86_64
+%package target-arm64
+Summary: Crash executable for analyzing arm64 crash dumps on x86_64 host machines
+Group: Development/Libraries
+
+%description target-arm64
+This package contains the "crash-target-arm64" binary for analyzing arm64 crash dumps on x86_64 host machines.
+%endif
+
%prep
%autosetup -n %{name}-%{version}
# make expect the gdb tarball to be named with its version only, gdb-[version].tar.gz, e.g.: gdb-10.2.tar.gz
cp %{SOURCE1} ./gdb-%{gdb_version}.tar.gz
%build
+%ifarch x86_64
+# For x86_64 only, build a separate crash binary for target=ARM64
+# After creating the "crash-target-arm64" binary, clean everything and rebuild for native target
+make RPMPKG=%{version}-%{release} target=ARM64
+cp -v crash crash-target-arm64
+rm -rf ./gdb-%{gdb_version}
+make clean
+# Need to specify target=X86_64 here, since this parameter is "sticky" from the previous build
+make RPMPKG=%{version}-%{release} target=X86_64
+%else
make RPMPKG=%{version}-%{release}
+%endif
%install
mkdir -p %{buildroot}%{_bindir}
%make_install
+%ifarch x86_64
+cp -v crash-target-arm64 %{buildroot}%{_bindir}/crash-target-arm64
+%endif
+
mkdir -p %{buildroot}%{_mandir}/man8
install -pm 644 crash.8 %{buildroot}%{_mandir}/man8/crash.8
mkdir -p %{buildroot}%{_includedir}/crash
@@ -65,7 +89,16 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%dir %{_includedir}/crash
%{_includedir}/crash/*.h
+%ifarch x86_64
+%files target-arm64
+%defattr(-,root,root)
+%{_bindir}/crash-target-arm64
+%endif
+
%changelog
+* Tue Jun 18 2024 Andrew Phelps - 8.0.4-3
+- Add crash-target-arm64 binary to analyze aarch64 dumps on x86_64 machine
+
* Mon Jun 03 2024 Nicolas Guibourge - 8.0.4-2
- Update gdb-10.2-2.tar.gz to address CVE-2022-37434
diff --git a/SPECS/flannel/flannel.spec b/SPECS/flannel/flannel.spec
index b6886979760..46c1119df8d 100644
--- a/SPECS/flannel/flannel.spec
+++ b/SPECS/flannel/flannel.spec
@@ -13,7 +13,7 @@ Source0: https://github.com/flannel-io/%{name}/archive/refs/tags/v%{versi
Source1: %{name}-%{version}-vendor.tar.gz
BuildRequires: gcc
BuildRequires: glibc-devel
-BuildRequires: glibc-static >= 2.38-5%{?dist}
+BuildRequires: glibc-static >= 2.38-6%{?dist}
BuildRequires: golang >= 1.20
BuildRequires: kernel-headers
diff --git a/SPECS/gcc/CVE-2023-4039.patch b/SPECS/gcc/CVE-2023-4039.patch
index b9de29d9abe..7a7a399c0bd 100644
--- a/SPECS/gcc/CVE-2023-4039.patch
+++ b/SPECS/gcc/CVE-2023-4039.patch
@@ -1,6 +1,6 @@
-From 12f648c158fb9f3be7aa2b6ab377d128a0c1bf1c Mon Sep 17 00:00:00 2001
+From 71a2aa2127283f450c623d3604dbcabe0e14a8d4 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:43 +0100
+Date: Tue, 12 Sep 2023 16:07:12 +0100
Subject: [PATCH 01/19] aarch64: Use local frame vars in shrink-wrapping code
aarch64_layout_frame uses a shorthand for referring to
@@ -12,7 +12,7 @@ This patch does the same for some other heavy users of the structure.
No functional change intended.
gcc/
- * config/aarch64/aarch64.c (aarch64_save_callee_saves): Use
+ * config/aarch64/aarch64.cc (aarch64_save_callee_saves): Use
a local shorthand for cfun->machine->frame.
(aarch64_restore_callee_saves, aarch64_get_separate_components):
(aarch64_process_components): Likewise.
@@ -20,14 +20,23 @@ gcc/
(aarch64_expand_prologue, aarch64_expand_epilogue): Likewise.
(aarch64_layout_frame): Use existing shorthand for one more case.
---
- gcc/config/aarch64/aarch64.c | 115 ++++++++++++++++++-----------------
- 1 file changed, 60 insertions(+), 55 deletions(-)
-
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index c2f4b27f6..2ddd01b34 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7733,6 +7733,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+ gcc/config/aarch64/aarch64.cc | 123 ++++++++++++++++++----------------
+ 1 file changed, 64 insertions(+), 59 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 822a2b49a46..5d473d161d9 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8612,7 +8612,7 @@ aarch64_layout_frame (void)
+ frame.is_scs_enabled
+ = (!crtl->calls_eh_return
+ && sanitize_flags_p (SANITIZE_SHADOW_CALL_STACK)
+- && known_ge (cfun->machine->frame.reg_offset[LR_REGNUM], 0));
++ && known_ge (frame.reg_offset[LR_REGNUM], 0));
+
+ /* When shadow call stack is enabled, the scs_pop in the epilogue will
+ restore x30, and we don't need to pop x30 again in the traditional
+@@ -9078,6 +9078,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
unsigned start, unsigned limit, bool skip_wb,
bool hard_fp_valid_p)
{
@@ -35,18 +44,18 @@ index c2f4b27f6..2ddd01b34 100644
rtx_insn *insn;
unsigned regno;
unsigned regno2;
-@@ -7747,8 +7748,8 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9092,8 +9093,8 @@ aarch64_save_callee_saves (poly_int64 start_offset,
bool frame_related_p = aarch64_emit_cfi_for_reg_p (regno);
if (skip_wb
-- && (regno == cfun->machine->frame.wb_candidate1
-- || regno == cfun->machine->frame.wb_candidate2))
-+ && (regno == frame.wb_candidate1
-+ || regno == frame.wb_candidate2))
+- && (regno == cfun->machine->frame.wb_push_candidate1
+- || regno == cfun->machine->frame.wb_push_candidate2))
++ && (regno == frame.wb_push_candidate1
++ || regno == frame.wb_push_candidate2))
continue;
if (cfun->machine->reg_is_wrapped_separately[regno])
-@@ -7756,7 +7757,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9101,7 +9102,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
machine_mode mode = aarch64_reg_save_mode (regno);
reg = gen_rtx_REG (mode, regno);
@@ -55,7 +64,7 @@ index c2f4b27f6..2ddd01b34 100644
rtx base_rtx = stack_pointer_rtx;
poly_int64 sp_offset = offset;
-@@ -7769,7 +7770,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9114,7 +9115,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
{
gcc_assert (known_eq (start_offset, 0));
poly_int64 fp_offset
@@ -64,7 +73,7 @@ index c2f4b27f6..2ddd01b34 100644
if (hard_fp_valid_p)
base_rtx = hard_frame_pointer_rtx;
else
-@@ -7791,8 +7792,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9136,8 +9137,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
&& (regno2 = aarch64_next_callee_save (regno + 1, limit)) <= limit
&& !cfun->machine->reg_is_wrapped_separately[regno2]
&& known_eq (GET_MODE_SIZE (mode),
@@ -74,7 +83,7 @@ index c2f4b27f6..2ddd01b34 100644
{
rtx reg2 = gen_rtx_REG (mode, regno2);
rtx mem2;
-@@ -7842,6 +7842,7 @@ static void
+@@ -9187,6 +9187,7 @@ static void
aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
unsigned limit, bool skip_wb, rtx *cfi_ops)
{
@@ -82,14 +91,14 @@ index c2f4b27f6..2ddd01b34 100644
unsigned regno;
unsigned regno2;
poly_int64 offset;
-@@ -7858,13 +7859,13 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
+@@ -9203,13 +9204,13 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
rtx reg, mem;
if (skip_wb
-- && (regno == cfun->machine->frame.wb_candidate1
-- || regno == cfun->machine->frame.wb_candidate2))
-+ && (regno == frame.wb_candidate1
-+ || regno == frame.wb_candidate2))
+- && (regno == cfun->machine->frame.wb_pop_candidate1
+- || regno == cfun->machine->frame.wb_pop_candidate2))
++ && (regno == frame.wb_pop_candidate1
++ || regno == frame.wb_pop_candidate2))
continue;
machine_mode mode = aarch64_reg_save_mode (regno);
@@ -99,7 +108,7 @@ index c2f4b27f6..2ddd01b34 100644
rtx base_rtx = stack_pointer_rtx;
if (mode == VNx2DImode && BYTES_BIG_ENDIAN)
aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg,
-@@ -7875,8 +7876,7 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
+@@ -9220,8 +9221,7 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
&& (regno2 = aarch64_next_callee_save (regno + 1, limit)) <= limit
&& !cfun->machine->reg_is_wrapped_separately[regno2]
&& known_eq (GET_MODE_SIZE (mode),
@@ -109,7 +118,7 @@ index c2f4b27f6..2ddd01b34 100644
{
rtx reg2 = gen_rtx_REG (mode, regno2);
rtx mem2;
-@@ -7981,6 +7981,7 @@ offset_12bit_unsigned_scaled_p (machine_mode mode, poly_int64 offset)
+@@ -9326,6 +9326,7 @@ offset_12bit_unsigned_scaled_p (machine_mode mode, poly_int64 offset)
static sbitmap
aarch64_get_separate_components (void)
{
@@ -117,7 +126,7 @@ index c2f4b27f6..2ddd01b34 100644
sbitmap components = sbitmap_alloc (LAST_SAVED_REGNUM + 1);
bitmap_clear (components);
-@@ -7997,18 +7998,18 @@ aarch64_get_separate_components (void)
+@@ -9342,18 +9343,18 @@ aarch64_get_separate_components (void)
if (mode == VNx2DImode && BYTES_BIG_ENDIAN)
continue;
@@ -139,7 +148,7 @@ index c2f4b27f6..2ddd01b34 100644
else
offset += crtl->outgoing_args_size;
-@@ -8027,11 +8028,11 @@ aarch64_get_separate_components (void)
+@@ -9372,11 +9373,11 @@ aarch64_get_separate_components (void)
/* If the spare predicate register used by big-endian SVE code
is call-preserved, it must be saved in the main prologue
before any saves that use it. */
@@ -148,14 +157,14 @@ index c2f4b27f6..2ddd01b34 100644
+ if (frame.spare_pred_reg != INVALID_REGNUM)
+ bitmap_clear_bit (components, frame.spare_pred_reg);
-- unsigned reg1 = cfun->machine->frame.wb_candidate1;
-- unsigned reg2 = cfun->machine->frame.wb_candidate2;
-+ unsigned reg1 = frame.wb_candidate1;
-+ unsigned reg2 = frame.wb_candidate2;
+- unsigned reg1 = cfun->machine->frame.wb_push_candidate1;
+- unsigned reg2 = cfun->machine->frame.wb_push_candidate2;
++ unsigned reg1 = frame.wb_push_candidate1;
++ unsigned reg2 = frame.wb_push_candidate2;
/* If registers have been chosen to be stored/restored with
writeback don't interfere with them to avoid having to output explicit
stack adjustment instructions. */
-@@ -8140,6 +8141,7 @@ aarch64_get_next_set_bit (sbitmap bmp, unsigned int start)
+@@ -9485,6 +9486,7 @@ aarch64_get_next_set_bit (sbitmap bmp, unsigned int start)
static void
aarch64_process_components (sbitmap components, bool prologue_p)
{
@@ -163,7 +172,7 @@ index c2f4b27f6..2ddd01b34 100644
rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed
? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM);
-@@ -8154,9 +8156,9 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9499,9 +9501,9 @@ aarch64_process_components (sbitmap components, bool prologue_p)
machine_mode mode = aarch64_reg_save_mode (regno);
rtx reg = gen_rtx_REG (mode, regno);
@@ -175,7 +184,7 @@ index c2f4b27f6..2ddd01b34 100644
else
offset += crtl->outgoing_args_size;
-@@ -8181,14 +8183,14 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9526,14 +9528,14 @@ aarch64_process_components (sbitmap components, bool prologue_p)
break;
}
@@ -192,7 +201,7 @@ index c2f4b27f6..2ddd01b34 100644
GET_MODE_SIZE (mode)))
{
insn = emit_insn (set);
-@@ -8210,7 +8212,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9555,7 +9557,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
/* REGNO2 can be saved/restored in a pair with REGNO. */
rtx reg2 = gen_rtx_REG (mode, regno2);
if (frame_pointer_needed)
@@ -201,7 +210,7 @@ index c2f4b27f6..2ddd01b34 100644
else
offset2 += crtl->outgoing_args_size;
rtx addr2 = plus_constant (Pmode, ptr_reg, offset2);
-@@ -8305,6 +8307,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -9650,6 +9652,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
bool frame_related_p,
bool final_adjustment_p)
{
@@ -209,7 +218,7 @@ index c2f4b27f6..2ddd01b34 100644
HOST_WIDE_INT guard_size
= 1 << param_stack_clash_protection_guard_size;
HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD;
-@@ -8325,25 +8328,25 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -9670,25 +9673,25 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
register as a probe. We can't assume that LR was saved at position 0
though, so treat any space below it as unprobed. */
if (final_adjustment_p
@@ -241,7 +250,7 @@ index c2f4b27f6..2ddd01b34 100644
if (known_eq (frame_size, 0))
{
-@@ -8632,17 +8635,18 @@ aarch64_epilogue_uses (int regno)
+@@ -9977,17 +9980,18 @@ aarch64_epilogue_uses (int regno)
void
aarch64_expand_prologue (void)
{
@@ -260,17 +269,26 @@ index c2f4b27f6..2ddd01b34 100644
+ poly_int64 sve_callee_adjust = frame.sve_callee_adjust;
poly_int64 below_hard_fp_saved_regs_size
- = cfun->machine->frame.below_hard_fp_saved_regs_size;
-- unsigned reg1 = cfun->machine->frame.wb_candidate1;
-- unsigned reg2 = cfun->machine->frame.wb_candidate2;
+- unsigned reg1 = cfun->machine->frame.wb_push_candidate1;
+- unsigned reg2 = cfun->machine->frame.wb_push_candidate2;
- bool emit_frame_chain = cfun->machine->frame.emit_frame_chain;
+ = frame.below_hard_fp_saved_regs_size;
-+ unsigned reg1 = frame.wb_candidate1;
-+ unsigned reg2 = frame.wb_candidate2;
++ unsigned reg1 = frame.wb_push_candidate1;
++ unsigned reg2 = frame.wb_push_candidate2;
+ bool emit_frame_chain = frame.emit_frame_chain;
rtx_insn *insn;
if (flag_stack_clash_protection && known_eq (callee_adjust, 0))
-@@ -8708,7 +8712,7 @@ aarch64_expand_prologue (void)
+@@ -10018,7 +10022,7 @@ aarch64_expand_prologue (void)
+ }
+
+ /* Push return address to shadow call stack. */
+- if (cfun->machine->frame.is_scs_enabled)
++ if (frame.is_scs_enabled)
+ emit_insn (gen_scs_push ());
+
+ if (flag_stack_usage_info)
+@@ -10057,7 +10061,7 @@ aarch64_expand_prologue (void)
/* The offset of the frame chain record (if any) from the current SP. */
poly_int64 chain_offset = (initial_adjust + callee_adjust
@@ -279,7 +297,7 @@ index c2f4b27f6..2ddd01b34 100644
gcc_assert (known_ge (chain_offset, 0));
/* The offset of the bottom of the save area from the current SP. */
-@@ -8811,15 +8815,16 @@ aarch64_use_return_insn_p (void)
+@@ -10160,16 +10164,17 @@ aarch64_use_return_insn_p (void)
void
aarch64_expand_epilogue (bool for_sibcall)
{
@@ -296,15 +314,17 @@ index c2f4b27f6..2ddd01b34 100644
+ poly_int64 sve_callee_adjust = frame.sve_callee_adjust;
poly_int64 below_hard_fp_saved_regs_size
- = cfun->machine->frame.below_hard_fp_saved_regs_size;
-- unsigned reg1 = cfun->machine->frame.wb_candidate1;
-- unsigned reg2 = cfun->machine->frame.wb_candidate2;
+- unsigned reg1 = cfun->machine->frame.wb_pop_candidate1;
+- unsigned reg2 = cfun->machine->frame.wb_pop_candidate2;
+- unsigned int last_gpr = (cfun->machine->frame.is_scs_enabled
+ = frame.below_hard_fp_saved_regs_size;
-+ unsigned reg1 = frame.wb_candidate1;
-+ unsigned reg2 = frame.wb_candidate2;
++ unsigned reg1 = frame.wb_pop_candidate1;
++ unsigned reg2 = frame.wb_pop_candidate2;
++ unsigned int last_gpr = (frame.is_scs_enabled
+ ? R29_REGNUM : R30_REGNUM);
rtx cfi_ops = NULL;
rtx_insn *insn;
- /* A stack clash protection prologue may not have left EP0_REGNUM or
-@@ -8852,7 +8857,7 @@ aarch64_expand_epilogue (bool for_sibcall)
+@@ -10203,7 +10208,7 @@ aarch64_expand_epilogue (bool for_sibcall)
/* We need to add memory barrier to prevent read from deallocated stack. */
bool need_barrier_p
= maybe_ne (get_frame_size ()
@@ -313,7 +333,16 @@ index c2f4b27f6..2ddd01b34 100644
/* Emit a barrier to prevent loads from a deallocated stack. */
if (maybe_gt (final_adjust, crtl->outgoing_args_size)
-@@ -11483,24 +11488,24 @@ aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
+@@ -10284,7 +10289,7 @@ aarch64_expand_epilogue (bool for_sibcall)
+ }
+
+ /* Pop return address from shadow call stack. */
+- if (cfun->machine->frame.is_scs_enabled)
++ if (frame.is_scs_enabled)
+ {
+ machine_mode mode = aarch64_reg_save_mode (R30_REGNUM);
+ rtx reg = gen_rtx_REG (mode, R30_REGNUM);
+@@ -12740,24 +12745,24 @@ aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
poly_int64
aarch64_initial_elimination_offset (unsigned from, unsigned to)
{
@@ -345,12 +374,12 @@ index c2f4b27f6..2ddd01b34 100644
--
-2.17.1
+2.39.4
-From e6f4ab027ccd405ad6b1a293fa7bd304f6995e83 Mon Sep 17 00:00:00 2001
+From 89a9fa287706c5011f61926eaf65e7b996b963a3 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:44 +0100
+Date: Tue, 12 Sep 2023 16:07:12 +0100
Subject: [PATCH 02/19] aarch64: Avoid a use of callee_offset
When we emit the frame chain, i.e. when we reach Here in this statement
@@ -390,17 +419,17 @@ CFA note to be in sync, and it's more convenient for later patches
if it uses chain_offset.
gcc/
- * config/aarch64/aarch64.c (aarch64_expand_prologue): Use
+ * config/aarch64/aarch64.cc (aarch64_expand_prologue): Use
chain_offset rather than callee_offset.
---
- gcc/config/aarch64/aarch64.c | 4 +---
+ gcc/config/aarch64/aarch64.cc | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 2ddd01b34..e67d44edd 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -8640,7 +8640,6 @@ aarch64_expand_prologue (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 5d473d161d9..4f233c95140 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -9985,7 +9985,6 @@ aarch64_expand_prologue (void)
poly_int64 initial_adjust = frame.initial_adjust;
HOST_WIDE_INT callee_adjust = frame.callee_adjust;
poly_int64 final_adjust = frame.final_adjust;
@@ -408,7 +437,7 @@ index 2ddd01b34..e67d44edd 100644
poly_int64 sve_callee_adjust = frame.sve_callee_adjust;
poly_int64 below_hard_fp_saved_regs_size
= frame.below_hard_fp_saved_regs_size;
-@@ -8749,8 +8748,7 @@ aarch64_expand_prologue (void)
+@@ -10098,8 +10097,7 @@ aarch64_expand_prologue (void)
implicit. */
if (!find_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX))
{
@@ -419,12 +448,12 @@ index 2ddd01b34..e67d44edd 100644
gen_rtx_SET (hard_frame_pointer_rtx, src));
}
--
-2.17.1
+2.39.4
-From dd53b165c9c18c8b9459ea9472f6e01aaf9403d5 Mon Sep 17 00:00:00 2001
+From b36a2a78040722dab6124366c5d6baf8eaf80aef Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:44 +0100
+Date: Tue, 12 Sep 2023 16:07:13 +0100
Subject: [PATCH 03/19] aarch64: Explicitly handle frames with no saved
registers
@@ -443,17 +472,17 @@ no outgoing arguments, and so all the frame will be above where
the saved registers normally go.
gcc/
- * config/aarch64/aarch64.c (aarch64_layout_frame): Explicitly
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Explicitly
allocate the frame in one go if there are no saved registers.
---
- gcc/config/aarch64/aarch64.c | 8 +++++---
+ gcc/config/aarch64/aarch64.cc | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index e67d44edd..1667593a1 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7348,9 +7348,11 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 4f233c95140..37643041ffb 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8639,9 +8639,11 @@ aarch64_layout_frame (void)
HOST_WIDE_INT const_size, const_outgoing_args_size, const_fp_offset;
HOST_WIDE_INT const_saved_regs_size;
@@ -469,12 +498,12 @@ index e67d44edd..1667593a1 100644
/* Simple, small frame with no outgoing arguments:
--
-2.17.1
+2.39.4
-From 2e30d93703ccc3d3bedda1402540b3a665c01136 Mon Sep 17 00:00:00 2001
+From ada2ab0093596be707f23a3466ac82cff59fcffe Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:45 +0100
+Date: Tue, 12 Sep 2023 16:07:13 +0100
Subject: [PATCH 04/19] aarch64: Add bytes_below_saved_regs to frame info
The frame layout code currently hard-codes the assumption that
@@ -485,21 +514,21 @@ value into a new field of aarch64_frame.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::bytes_below_saved_regs): New
field.
- * config/aarch64/aarch64.c (aarch64_layout_frame): Initialize it,
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Initialize it,
and use it instead of crtl->outgoing_args_size.
(aarch64_get_separate_components): Use bytes_below_saved_regs instead
of outgoing_args_size.
(aarch64_process_components): Likewise.
---
- gcc/config/aarch64/aarch64.c | 71 ++++++++++++++++++------------------
- gcc/config/aarch64/aarch64.h | 5 +++
+ gcc/config/aarch64/aarch64.cc | 71 ++++++++++++++++++-----------------
+ gcc/config/aarch64/aarch64.h | 5 +++
2 files changed, 41 insertions(+), 35 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 1667593a1..d77c13b70 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7215,6 +7215,8 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 37643041ffb..dacc2b0e4dd 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8478,6 +8478,8 @@ aarch64_layout_frame (void)
gcc_assert (crtl->is_leaf
|| maybe_ne (frame.reg_offset[R30_REGNUM], SLOT_NOT_REQUIRED));
@@ -508,7 +537,7 @@ index 1667593a1..d77c13b70 100644
/* Now assign stack slots for the registers. Start with the predicate
registers, since predicate LDR and STR have a relatively small
offset range. These saves happen below the hard frame pointer. */
-@@ -7319,18 +7321,18 @@ aarch64_layout_frame (void)
+@@ -8582,18 +8584,18 @@ aarch64_layout_frame (void)
poly_int64 varargs_and_saved_regs_size = offset + frame.saved_varargs_size;
@@ -531,8 +560,8 @@ index 1667593a1..d77c13b70 100644
frame.locals_offset = frame.saved_varargs_size;
-@@ -7346,7 +7348,7 @@ aarch64_layout_frame (void)
- else if (frame.wb_candidate1 != INVALID_REGNUM)
+@@ -8637,7 +8639,7 @@ aarch64_layout_frame (void)
+ else if (frame.wb_pop_candidate1 != INVALID_REGNUM)
max_push_offset = 256;
- HOST_WIDE_INT const_size, const_outgoing_args_size, const_fp_offset;
@@ -540,7 +569,7 @@ index 1667593a1..d77c13b70 100644
HOST_WIDE_INT const_saved_regs_size;
if (known_eq (frame.saved_regs_size, 0))
frame.initial_adjust = frame.frame_size;
-@@ -7354,31 +7356,31 @@ aarch64_layout_frame (void)
+@@ -8645,31 +8647,31 @@ aarch64_layout_frame (void)
&& const_size < max_push_offset
&& known_eq (frame.hard_fp_offset, const_size))
{
@@ -584,7 +613,7 @@ index 1667593a1..d77c13b70 100644
}
else if (saves_below_hard_fp_p
&& known_eq (frame.saved_regs_size,
-@@ -7388,30 +7390,29 @@ aarch64_layout_frame (void)
+@@ -8679,30 +8681,29 @@ aarch64_layout_frame (void)
sub sp, sp, hard_fp_offset + below_hard_fp_saved_regs_size
save SVE registers relative to SP
@@ -622,7 +651,7 @@ index 1667593a1..d77c13b70 100644
sub sp, sp, hard_fp_offset
stp x29, x30, [sp, 0]
-@@ -7419,10 +7420,10 @@ aarch64_layout_frame (void)
+@@ -8710,10 +8711,10 @@ aarch64_layout_frame (void)
stp reg3, reg4, [sp, 16]
[sub sp, sp, below_hard_fp_saved_regs_size]
[save SVE registers relative to SP]
@@ -635,7 +664,7 @@ index 1667593a1..d77c13b70 100644
}
/* Make sure the individual adjustments add up to the full frame size. */
-@@ -8013,7 +8014,7 @@ aarch64_get_separate_components (void)
+@@ -9358,7 +9359,7 @@ aarch64_get_separate_components (void)
if (frame_pointer_needed)
offset -= frame.below_hard_fp_saved_regs_size;
else
@@ -644,7 +673,7 @@ index 1667593a1..d77c13b70 100644
/* Check that we can access the stack slot of the register with one
direct load with no adjustments needed. */
-@@ -8162,7 +8163,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9507,7 +9508,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
if (frame_pointer_needed)
offset -= frame.below_hard_fp_saved_regs_size;
else
@@ -653,7 +682,7 @@ index 1667593a1..d77c13b70 100644
rtx addr = plus_constant (Pmode, ptr_reg, offset);
rtx mem = gen_frame_mem (mode, addr);
-@@ -8216,7 +8217,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9561,7 +9562,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
if (frame_pointer_needed)
offset2 -= frame.below_hard_fp_saved_regs_size;
else
@@ -662,7 +691,7 @@ index 1667593a1..d77c13b70 100644
rtx addr2 = plus_constant (Pmode, ptr_reg, offset2);
rtx mem2 = gen_frame_mem (mode, addr2);
rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2)
-@@ -8290,10 +8291,10 @@ aarch64_stack_clash_protection_alloca_probe_range (void)
+@@ -9635,10 +9636,10 @@ aarch64_stack_clash_protection_alloca_probe_range (void)
registers. If POLY_SIZE is not large enough to require a probe this function
will only adjust the stack. When allocating the stack space
FRAME_RELATED_P is then used to indicate if the allocation is frame related.
@@ -677,7 +706,7 @@ index 1667593a1..d77c13b70 100644
We emit barriers after each stack adjustment to prevent optimizations from
breaking the invariant that we never drop the stack more than a page. This
-@@ -8502,7 +8503,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -9847,7 +9848,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
/* Handle any residuals. Residuals of at least MIN_PROBE_THRESHOLD have to
be probed. This maintains the requirement that each page is probed at
least once. For initial probing we probe only if the allocation is
@@ -687,10 +716,10 @@ index 1667593a1..d77c13b70 100644
GUARD_SIZE. This works that for any allocation that is large enough to
trigger a probe here, we'll have at least one, and if they're not large
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index bfffbcd6a..3bb2f29af 100644
+index 73b09e20508..0b6faa3ddf1 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -835,6 +835,11 @@ struct GTY (()) aarch64_frame
+@@ -777,6 +777,11 @@ struct GTY (()) aarch64_frame
/* The size of the callee-save registers with a slot in REG_OFFSET. */
poly_int64 saved_regs_size;
@@ -703,12 +732,12 @@ index bfffbcd6a..3bb2f29af 100644
are saved below the hard frame pointer. */
poly_int64 below_hard_fp_saved_regs_size;
--
-2.17.1
+2.39.4
-From 3e826e897e104db564a4f6292fa4bf0a69f18c7e Mon Sep 17 00:00:00 2001
+From 82f6b3e1b596ef0f4e3ac3bb9c6e88fb4458f402 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:45 +0100
+Date: Tue, 12 Sep 2023 16:07:14 +0100
Subject: [PATCH 05/19] aarch64: Add bytes_below_hard_fp to frame info
Following on from the previous bytes_below_saved_regs patch, this one
@@ -732,19 +761,19 @@ from the outset.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::bytes_below_hard_fp): New
field.
- * config/aarch64/aarch64.c (aarch64_layout_frame): Initialize it.
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Initialize it.
(aarch64_expand_epilogue): Use it instead of
below_hard_fp_saved_regs_size.
---
- gcc/config/aarch64/aarch64.c | 6 +++---
- gcc/config/aarch64/aarch64.h | 5 +++++
+ gcc/config/aarch64/aarch64.cc | 6 +++---
+ gcc/config/aarch64/aarch64.h | 5 +++++
2 files changed, 8 insertions(+), 3 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index d77c13b70..ef3903757 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7267,6 +7267,7 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index dacc2b0e4dd..a3f7aabcc59 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8530,6 +8530,7 @@ aarch64_layout_frame (void)
of the callee save area. */
bool saves_below_hard_fp_p = maybe_ne (offset, 0);
frame.below_hard_fp_saved_regs_size = offset;
@@ -752,17 +781,17 @@ index d77c13b70..ef3903757 100644
if (frame.emit_frame_chain)
{
/* FP and LR are placed in the linkage record. */
-@@ -8822,8 +8823,7 @@ aarch64_expand_epilogue (bool for_sibcall)
+@@ -10171,8 +10172,7 @@ aarch64_expand_epilogue (bool for_sibcall)
poly_int64 final_adjust = frame.final_adjust;
poly_int64 callee_offset = frame.callee_offset;
poly_int64 sve_callee_adjust = frame.sve_callee_adjust;
- poly_int64 below_hard_fp_saved_regs_size
- = frame.below_hard_fp_saved_regs_size;
+ poly_int64 bytes_below_hard_fp = frame.bytes_below_hard_fp;
- unsigned reg1 = frame.wb_candidate1;
- unsigned reg2 = frame.wb_candidate2;
- rtx cfi_ops = NULL;
-@@ -8879,7 +8879,7 @@ aarch64_expand_epilogue (bool for_sibcall)
+ unsigned reg1 = frame.wb_pop_candidate1;
+ unsigned reg2 = frame.wb_pop_candidate2;
+ unsigned int last_gpr = (frame.is_scs_enabled
+@@ -10230,7 +10230,7 @@ aarch64_expand_epilogue (bool for_sibcall)
is restored on the instruction doing the writeback. */
aarch64_add_offset (Pmode, stack_pointer_rtx,
hard_frame_pointer_rtx,
@@ -772,10 +801,10 @@ index d77c13b70..ef3903757 100644
else
/* The case where we need to re-use the register here is very rare, so
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index 3bb2f29af..5c5f5b738 100644
+index 0b6faa3ddf1..4263d29d29d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -844,6 +844,11 @@ struct GTY (()) aarch64_frame
+@@ -786,6 +786,11 @@ struct GTY (()) aarch64_frame
are saved below the hard frame pointer. */
poly_int64 below_hard_fp_saved_regs_size;
@@ -788,12 +817,12 @@ index 3bb2f29af..5c5f5b738 100644
top of the locals area. This value is always a multiple of
STACK_BOUNDARY. */
--
-2.17.1
+2.39.4
-From c77beb190156920fab3418047f6729badcfd8c7b Mon Sep 17 00:00:00 2001
+From 86fa43e9fe4a8bf954f2919f07cbe3646d1d1df3 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:46 +0100
+Date: Tue, 12 Sep 2023 16:07:14 +0100
Subject: [PATCH 06/19] aarch64: Tweak aarch64_save/restore_callee_saves
aarch64_save_callee_saves and aarch64_restore_callee_saves took
@@ -809,7 +838,7 @@ makes sense in combination with the follow-on patches.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::callee_offset): Delete.
- * config/aarch64/aarch64.c (aarch64_layout_frame): Remove
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Remove
callee_offset handling.
(aarch64_save_callee_saves): Replace the start_offset parameter
with a bytes_below_sp parameter.
@@ -817,23 +846,23 @@ gcc/
(aarch64_expand_prologue): Update accordingly.
(aarch64_expand_epilogue): Likewise.
---
- gcc/config/aarch64/aarch64.c | 56 ++++++++++++++++++------------------
- gcc/config/aarch64/aarch64.h | 4 ---
+ gcc/config/aarch64/aarch64.cc | 56 +++++++++++++++++------------------
+ gcc/config/aarch64/aarch64.h | 4 ---
2 files changed, 28 insertions(+), 32 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index ef3903757..1923d751f 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7341,7 +7341,6 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index a3f7aabcc59..46ae5cf7673 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8604,7 +8604,6 @@ aarch64_layout_frame (void)
frame.final_adjust = 0;
frame.callee_adjust = 0;
frame.sve_callee_adjust = 0;
- frame.callee_offset = 0;
- HOST_WIDE_INT max_push_offset = 0;
- if (frame.wb_candidate2 != INVALID_REGNUM)
-@@ -7381,7 +7380,6 @@ aarch64_layout_frame (void)
+ frame.wb_pop_candidate1 = frame.wb_push_candidate1;
+ frame.wb_pop_candidate2 = frame.wb_push_candidate2;
+@@ -8672,7 +8671,6 @@ aarch64_layout_frame (void)
stp reg1, reg2, [sp, bytes_below_saved_regs]
stp reg3, reg4, [sp, bytes_below_saved_regs + 16] */
frame.initial_adjust = frame.frame_size;
@@ -841,7 +870,7 @@ index ef3903757..1923d751f 100644
}
else if (saves_below_hard_fp_p
&& known_eq (frame.saved_regs_size,
-@@ -7728,12 +7726,13 @@ aarch64_add_cfa_expression (rtx_insn *insn, rtx reg,
+@@ -9073,12 +9071,13 @@ aarch64_add_cfa_expression (rtx_insn *insn, rtx reg,
}
/* Emit code to save the callee-saved registers from register number START
@@ -859,7 +888,7 @@ index ef3903757..1923d751f 100644
unsigned start, unsigned limit, bool skip_wb,
bool hard_fp_valid_p)
{
-@@ -7761,7 +7760,9 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9106,7 +9105,9 @@ aarch64_save_callee_saves (poly_int64 start_offset,
machine_mode mode = aarch64_reg_save_mode (regno);
reg = gen_rtx_REG (mode, regno);
@@ -870,7 +899,7 @@ index ef3903757..1923d751f 100644
rtx base_rtx = stack_pointer_rtx;
poly_int64 sp_offset = offset;
-@@ -7772,9 +7773,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9117,9 +9118,7 @@ aarch64_save_callee_saves (poly_int64 start_offset,
else if (GP_REGNUM_P (regno)
&& (!offset.is_constant (&const_offset) || const_offset >= 512))
{
@@ -881,7 +910,7 @@ index ef3903757..1923d751f 100644
if (hard_fp_valid_p)
base_rtx = hard_frame_pointer_rtx;
else
-@@ -7838,12 +7837,13 @@ aarch64_save_callee_saves (poly_int64 start_offset,
+@@ -9183,12 +9182,13 @@ aarch64_save_callee_saves (poly_int64 start_offset,
}
/* Emit code to restore the callee registers from register number START
@@ -899,7 +928,7 @@ index ef3903757..1923d751f 100644
unsigned limit, bool skip_wb, rtx *cfi_ops)
{
aarch64_frame &frame = cfun->machine->frame;
-@@ -7869,7 +7869,9 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
+@@ -9214,7 +9214,9 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start,
machine_mode mode = aarch64_reg_save_mode (regno);
reg = gen_rtx_REG (mode, regno);
@@ -910,16 +939,16 @@ index ef3903757..1923d751f 100644
rtx base_rtx = stack_pointer_rtx;
if (mode == VNx2DImode && BYTES_BIG_ENDIAN)
aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg,
-@@ -8645,8 +8647,6 @@ aarch64_expand_prologue (void)
+@@ -9990,8 +9992,6 @@ aarch64_expand_prologue (void)
HOST_WIDE_INT callee_adjust = frame.callee_adjust;
poly_int64 final_adjust = frame.final_adjust;
poly_int64 sve_callee_adjust = frame.sve_callee_adjust;
- poly_int64 below_hard_fp_saved_regs_size
- = frame.below_hard_fp_saved_regs_size;
- unsigned reg1 = frame.wb_candidate1;
- unsigned reg2 = frame.wb_candidate2;
+ unsigned reg1 = frame.wb_push_candidate1;
+ unsigned reg2 = frame.wb_push_candidate2;
bool emit_frame_chain = frame.emit_frame_chain;
-@@ -8718,8 +8718,8 @@ aarch64_expand_prologue (void)
+@@ -10067,8 +10067,8 @@ aarch64_expand_prologue (void)
- frame.hard_fp_offset);
gcc_assert (known_ge (chain_offset, 0));
@@ -930,7 +959,7 @@ index ef3903757..1923d751f 100644
if (emit_frame_chain)
{
-@@ -8727,7 +8727,7 @@ aarch64_expand_prologue (void)
+@@ -10076,7 +10076,7 @@ aarch64_expand_prologue (void)
{
reg1 = R29_REGNUM;
reg2 = R30_REGNUM;
@@ -939,7 +968,7 @@ index ef3903757..1923d751f 100644
false, false);
}
else
-@@ -8767,7 +8767,7 @@ aarch64_expand_prologue (void)
+@@ -10116,7 +10116,7 @@ aarch64_expand_prologue (void)
emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx));
}
@@ -948,7 +977,7 @@ index ef3903757..1923d751f 100644
callee_adjust != 0 || emit_frame_chain,
emit_frame_chain);
if (maybe_ne (sve_callee_adjust, 0))
-@@ -8777,16 +8777,17 @@ aarch64_expand_prologue (void)
+@@ -10126,16 +10126,17 @@ aarch64_expand_prologue (void)
aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx,
sve_callee_adjust,
!frame_pointer_needed, false);
@@ -969,15 +998,15 @@ index ef3903757..1923d751f 100644
aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, final_adjust,
!frame_pointer_needed, true);
}
-@@ -8821,7 +8822,6 @@ aarch64_expand_epilogue (bool for_sibcall)
+@@ -10170,7 +10171,6 @@ aarch64_expand_epilogue (bool for_sibcall)
poly_int64 initial_adjust = frame.initial_adjust;
HOST_WIDE_INT callee_adjust = frame.callee_adjust;
poly_int64 final_adjust = frame.final_adjust;
- poly_int64 callee_offset = frame.callee_offset;
poly_int64 sve_callee_adjust = frame.sve_callee_adjust;
poly_int64 bytes_below_hard_fp = frame.bytes_below_hard_fp;
- unsigned reg1 = frame.wb_candidate1;
-@@ -8889,13 +8889,13 @@ aarch64_expand_epilogue (bool for_sibcall)
+ unsigned reg1 = frame.wb_pop_candidate1;
+@@ -10240,9 +10240,9 @@ aarch64_expand_epilogue (bool for_sibcall)
/* Restore the vector registers before the predicate registers,
so that we can use P4 as a temporary for big-endian SVE frames. */
@@ -989,16 +1018,20 @@ index ef3903757..1923d751f 100644
false, &cfi_ops);
if (maybe_ne (sve_callee_adjust, 0))
aarch64_add_sp (NULL_RTX, NULL_RTX, sve_callee_adjust, true);
+@@ -10250,7 +10250,7 @@ aarch64_expand_epilogue (bool for_sibcall)
+ /* When shadow call stack is enabled, the scs_pop in the epilogue will
+ restore x30, we don't need to restore x30 again in the traditional
+ way. */
- aarch64_restore_callee_saves (callee_offset - sve_callee_adjust,
+ aarch64_restore_callee_saves (final_adjust + sve_callee_adjust,
- R0_REGNUM, R30_REGNUM,
+ R0_REGNUM, last_gpr,
callee_adjust != 0, &cfi_ops);
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index 5c5f5b738..10d6a2de5 100644
+index 4263d29d29d..fd820b1be4e 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -871,10 +871,6 @@ struct GTY (()) aarch64_frame
+@@ -813,10 +813,6 @@ struct GTY (()) aarch64_frame
It is zero when no push is used. */
HOST_WIDE_INT callee_adjust;
@@ -1010,12 +1043,12 @@ index 5c5f5b738..10d6a2de5 100644
SVE registers. */
poly_int64 sve_callee_adjust;
--
-2.17.1
+2.39.4
-From 7cf697ed1ecca280ccc5f357c855a692796ee329 Mon Sep 17 00:00:00 2001
+From 8ae9181426f2700c2e5a2909487fa630e6fa406b Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:46 +0100
+Date: Tue, 12 Sep 2023 16:07:15 +0100
Subject: [PATCH 07/19] aarch64: Only calculate chain_offset if there is a
chain
@@ -1023,17 +1056,17 @@ After previous patches, it is no longer necessary to calculate
a chain_offset in cases where there is no chain record.
gcc/
- * config/aarch64/aarch64.c (aarch64_expand_prologue): Move the
+ * config/aarch64/aarch64.cc (aarch64_expand_prologue): Move the
calculation of chain_offset into the emit_frame_chain block.
---
- gcc/config/aarch64/aarch64.c | 10 +++++-----
+ gcc/config/aarch64/aarch64.cc | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 1923d751f..94403152e 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -8713,16 +8713,16 @@ aarch64_expand_prologue (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 46ae5cf7673..0e9b9717c08 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -10062,16 +10062,16 @@ aarch64_expand_prologue (void)
if (callee_adjust != 0)
aarch64_push_regs (reg1, reg2, callee_adjust);
@@ -1056,12 +1089,12 @@ index 1923d751f..94403152e 100644
{
reg1 = R29_REGNUM;
--
-2.17.1
+2.39.4
-From 8fdb29e28738ee2ca3aaa329352cf1e2f2fe8b24 Mon Sep 17 00:00:00 2001
+From 375794feb614cee1f41b710b9cc1b6f25da6c1cb Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:46 +0100
+Date: Tue, 12 Sep 2023 16:07:15 +0100
Subject: [PATCH 08/19] aarch64: Rename locals_offset to bytes_above_locals
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@@ -1093,18 +1126,18 @@ that by renaming locals_offset to bytes_above_locals.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::locals_offset): Rename to...
(aarch64_frame::bytes_above_locals): ...this.
- * config/aarch64/aarch64.c (aarch64_layout_frame)
+ * config/aarch64/aarch64.cc (aarch64_layout_frame)
(aarch64_initial_elimination_offset): Update accordingly.
---
- gcc/config/aarch64/aarch64.c | 6 +++---
- gcc/config/aarch64/aarch64.h | 6 +++---
+ gcc/config/aarch64/aarch64.cc | 6 +++---
+ gcc/config/aarch64/aarch64.h | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 94403152e..c41cf5682 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7335,7 +7335,7 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 0e9b9717c08..0a22f91520e 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8598,7 +8598,7 @@ aarch64_layout_frame (void)
STACK_BOUNDARY / BITS_PER_UNIT));
frame.frame_size = saved_regs_and_above + frame.bytes_below_saved_regs;
@@ -1113,7 +1146,7 @@ index 94403152e..c41cf5682 100644
frame.initial_adjust = 0;
frame.final_adjust = 0;
-@@ -11497,13 +11497,13 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
+@@ -12754,13 +12754,13 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
return frame.hard_fp_offset;
if (from == FRAME_POINTER_REGNUM)
@@ -1130,10 +1163,10 @@ index 94403152e..c41cf5682 100644
return frame.frame_size;
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index 10d6a2de5..7615e95e2 100644
+index fd820b1be4e..7ae12d13e2b 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -849,10 +849,10 @@ struct GTY (()) aarch64_frame
+@@ -791,10 +791,10 @@ struct GTY (()) aarch64_frame
always a multiple of STACK_BOUNDARY. */
poly_int64 bytes_below_hard_fp;
@@ -1148,12 +1181,12 @@ index 10d6a2de5..7615e95e2 100644
/* Offset from the base of the frame (incomming SP) to the
hard_frame_pointer. This value is always a multiple of
--
-2.17.1
+2.39.4
-From bc36b36ed615bc2671e7239cd61e4aa37fd38976 Mon Sep 17 00:00:00 2001
+From 1a9ea1c45c75615ffbfabe652b3598a1d7be2168 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:47 +0100
+Date: Tue, 12 Sep 2023 16:07:16 +0100
Subject: [PATCH 09/19] aarch64: Rename hard_fp_offset to bytes_above_hard_fp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@@ -1174,19 +1207,19 @@ gcc/
* config/aarch64/aarch64.h (aarch64_frame::hard_fp_offset): Rename
to...
(aarch64_frame::bytes_above_hard_fp): ...this.
- * config/aarch64/aarch64.c (aarch64_layout_frame)
+ * config/aarch64/aarch64.cc (aarch64_layout_frame)
(aarch64_expand_prologue): Update accordingly.
(aarch64_initial_elimination_offset): Likewise.
---
- gcc/config/aarch64/aarch64.c | 26 +++++++++++++-------------
- gcc/config/aarch64/aarch64.h | 6 +++---
+ gcc/config/aarch64/aarch64.cc | 26 +++++++++++++-------------
+ gcc/config/aarch64/aarch64.h | 6 +++---
2 files changed, 16 insertions(+), 16 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index c41cf5682..04c5f417d 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7327,7 +7327,7 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 0a22f91520e..95499ae49ba 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8590,7 +8590,7 @@ aarch64_layout_frame (void)
+ get_frame_size (),
STACK_BOUNDARY / BITS_PER_UNIT);
@@ -1195,8 +1228,8 @@ index c41cf5682..04c5f417d 100644
= saved_regs_and_above - frame.below_hard_fp_saved_regs_size;
/* Both these values are already aligned. */
-@@ -7348,13 +7348,13 @@ aarch64_layout_frame (void)
- else if (frame.wb_candidate1 != INVALID_REGNUM)
+@@ -8639,13 +8639,13 @@ aarch64_layout_frame (void)
+ else if (frame.wb_pop_candidate1 != INVALID_REGNUM)
max_push_offset = 256;
- HOST_WIDE_INT const_size, const_below_saved_regs, const_fp_offset;
@@ -1211,7 +1244,7 @@ index c41cf5682..04c5f417d 100644
{
/* Simple, small frame with no data below the saved registers.
-@@ -7371,8 +7371,8 @@ aarch64_layout_frame (void)
+@@ -8662,8 +8662,8 @@ aarch64_layout_frame (void)
case that it hardly seems worth the effort though. */
&& (!saves_below_hard_fp_p || const_below_saved_regs == 0)
&& !(cfun->calls_alloca
@@ -1222,7 +1255,7 @@ index c41cf5682..04c5f417d 100644
{
/* Frame with small area below the saved registers:
-@@ -7390,12 +7390,12 @@ aarch64_layout_frame (void)
+@@ -8681,12 +8681,12 @@ aarch64_layout_frame (void)
sub sp, sp, hard_fp_offset + below_hard_fp_saved_regs_size
save SVE registers relative to SP
sub sp, sp, bytes_below_saved_regs */
@@ -1238,7 +1271,7 @@ index c41cf5682..04c5f417d 100644
{
/* Frame with large area below the saved registers, or with SVE saves,
but with a small area above:
-@@ -7405,7 +7405,7 @@ aarch64_layout_frame (void)
+@@ -8696,7 +8696,7 @@ aarch64_layout_frame (void)
[sub sp, sp, below_hard_fp_saved_regs_size]
[save SVE registers relative to SP]
sub sp, sp, bytes_below_saved_regs */
@@ -1247,7 +1280,7 @@ index c41cf5682..04c5f417d 100644
frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size;
frame.final_adjust = frame.bytes_below_saved_regs;
}
-@@ -7420,7 +7420,7 @@ aarch64_layout_frame (void)
+@@ -8711,7 +8711,7 @@ aarch64_layout_frame (void)
[sub sp, sp, below_hard_fp_saved_regs_size]
[save SVE registers relative to SP]
sub sp, sp, bytes_below_saved_regs */
@@ -1256,7 +1289,7 @@ index c41cf5682..04c5f417d 100644
frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size;
frame.final_adjust = frame.bytes_below_saved_regs;
}
-@@ -8720,7 +8720,7 @@ aarch64_expand_prologue (void)
+@@ -10069,7 +10069,7 @@ aarch64_expand_prologue (void)
{
/* The offset of the frame chain record (if any) from the current SP. */
poly_int64 chain_offset = (initial_adjust + callee_adjust
@@ -1265,7 +1298,7 @@ index c41cf5682..04c5f417d 100644
gcc_assert (known_ge (chain_offset, 0));
if (callee_adjust == 0)
-@@ -11494,10 +11494,10 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
+@@ -12751,10 +12751,10 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
if (to == HARD_FRAME_POINTER_REGNUM)
{
if (from == ARG_POINTER_REGNUM)
@@ -1279,10 +1312,10 @@ index c41cf5682..04c5f417d 100644
if (to == STACK_POINTER_REGNUM)
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index 7615e95e2..f1157c391 100644
+index 7ae12d13e2b..3808f49e9ca 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -854,10 +854,10 @@ struct GTY (()) aarch64_frame
+@@ -796,10 +796,10 @@ struct GTY (()) aarch64_frame
STACK_BOUNDARY. */
poly_int64 bytes_above_locals;
@@ -1297,12 +1330,12 @@ index 7615e95e2..f1157c391 100644
/* The size of the frame. This value is the offset from base of the
frame (incomming SP) to the stack_pointer. This value is always
--
-2.17.1
+2.39.4
-From 04f77be1650925ac080e283cb1a1051ecfc1a54c Mon Sep 17 00:00:00 2001
+From d202ce1ecf60a36a3e1009917dd76109248ce9be Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:47 +0100
+Date: Tue, 12 Sep 2023 16:07:16 +0100
Subject: [PATCH 10/19] aarch64: Tweak frame_size comment
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@@ -1318,10 +1351,10 @@ gcc/
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index f1157c391..8f84f66ad 100644
+index 3808f49e9ca..108a5731b0d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -859,8 +859,8 @@ struct GTY (()) aarch64_frame
+@@ -801,8 +801,8 @@ struct GTY (()) aarch64_frame
STACK_BOUNDARY. */
poly_int64 bytes_above_hard_fp;
@@ -1333,12 +1366,12 @@ index f1157c391..8f84f66ad 100644
poly_int64 frame_size;
--
-2.17.1
+2.39.4
-From 908f0d4682e6d0cbf8c3e090885e13b41bb1484b Mon Sep 17 00:00:00 2001
+From f2b585375205b0a1802d79c682ba33766ecd1f0f Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:48 +0100
+Date: Tue, 12 Sep 2023 16:07:17 +0100
Subject: [PATCH 11/19] aarch64: Measure reg_offset from the bottom of the
frame
@@ -1356,7 +1389,7 @@ in its own right.
gcc/
* config/aarch64/aarch64.h (aarch64_frame): Add comment above
reg_offset.
- * config/aarch64/aarch64.c (aarch64_layout_frame): Walk offsets
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Walk offsets
from the bottom of the frame, rather than the bottom of the saved
register area. Measure reg_offset from the bottom of the frame
rather than the bottom of the saved register area.
@@ -1365,15 +1398,15 @@ gcc/
(aarch64_get_separate_components): Likewise.
(aarch64_process_components): Likewise.
---
- gcc/config/aarch64/aarch64.c | 53 ++++++++++++++++--------------------
- gcc/config/aarch64/aarch64.h | 3 ++
+ gcc/config/aarch64/aarch64.cc | 53 ++++++++++++++++-------------------
+ gcc/config/aarch64/aarch64.h | 3 ++
2 files changed, 27 insertions(+), 29 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 04c5f417d..6322f5873 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7137,7 +7137,6 @@ aarch64_needs_frame_chain (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 95499ae49ba..af99807ef8a 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8400,7 +8400,6 @@ aarch64_needs_frame_chain (void)
static void
aarch64_layout_frame (void)
{
@@ -1381,7 +1414,7 @@ index 04c5f417d..6322f5873 100644
int regno, last_fp_reg = INVALID_REGNUM;
machine_mode vector_save_mode = aarch64_reg_save_mode (V8_REGNUM);
poly_int64 vector_save_size = GET_MODE_SIZE (vector_save_mode);
-@@ -7215,7 +7214,9 @@ aarch64_layout_frame (void)
+@@ -8478,7 +8477,9 @@ aarch64_layout_frame (void)
gcc_assert (crtl->is_leaf
|| maybe_ne (frame.reg_offset[R30_REGNUM], SLOT_NOT_REQUIRED));
@@ -1392,7 +1425,7 @@ index 04c5f417d..6322f5873 100644
/* Now assign stack slots for the registers. Start with the predicate
registers, since predicate LDR and STR have a relatively small
-@@ -7227,7 +7228,8 @@ aarch64_layout_frame (void)
+@@ -8490,7 +8491,8 @@ aarch64_layout_frame (void)
offset += BYTES_PER_SVE_PRED;
}
@@ -1402,7 +1435,7 @@ index 04c5f417d..6322f5873 100644
{
/* If we have any vector registers to save above the predicate registers,
the offset of the vector register save slots need to be a multiple
-@@ -7245,10 +7247,10 @@ aarch64_layout_frame (void)
+@@ -8508,10 +8510,10 @@ aarch64_layout_frame (void)
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
else
{
@@ -1417,7 +1450,7 @@ index 04c5f417d..6322f5873 100644
else
gcc_unreachable ();
}
-@@ -7265,9 +7267,10 @@ aarch64_layout_frame (void)
+@@ -8528,9 +8530,10 @@ aarch64_layout_frame (void)
/* OFFSET is now the offset of the hard frame pointer from the bottom
of the callee save area. */
@@ -1431,7 +1464,7 @@ index 04c5f417d..6322f5873 100644
if (frame.emit_frame_chain)
{
/* FP and LR are placed in the linkage record. */
-@@ -7318,9 +7321,10 @@ aarch64_layout_frame (void)
+@@ -8581,9 +8584,10 @@ aarch64_layout_frame (void)
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
@@ -1444,7 +1477,7 @@ index 04c5f417d..6322f5873 100644
poly_int64 saved_regs_and_above
= aligned_upper_bound (varargs_and_saved_regs_size
-@@ -7760,9 +7764,7 @@ aarch64_save_callee_saves (poly_int64 bytes_below_sp,
+@@ -9105,9 +9109,7 @@ aarch64_save_callee_saves (poly_int64 bytes_below_sp,
machine_mode mode = aarch64_reg_save_mode (regno);
reg = gen_rtx_REG (mode, regno);
@@ -1455,7 +1488,7 @@ index 04c5f417d..6322f5873 100644
rtx base_rtx = stack_pointer_rtx;
poly_int64 sp_offset = offset;
-@@ -7869,9 +7871,7 @@ aarch64_restore_callee_saves (poly_int64 bytes_below_sp, unsigned start,
+@@ -9214,9 +9216,7 @@ aarch64_restore_callee_saves (poly_int64 bytes_below_sp, unsigned start,
machine_mode mode = aarch64_reg_save_mode (regno);
reg = gen_rtx_REG (mode, regno);
@@ -1466,7 +1499,7 @@ index 04c5f417d..6322f5873 100644
rtx base_rtx = stack_pointer_rtx;
if (mode == VNx2DImode && BYTES_BIG_ENDIAN)
aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg,
-@@ -8010,14 +8010,12 @@ aarch64_get_separate_components (void)
+@@ -9355,14 +9355,12 @@ aarch64_get_separate_components (void)
it as a stack probe for -fstack-clash-protection. */
if (flag_stack_clash_protection
&& maybe_ne (frame.below_hard_fp_saved_regs_size, 0)
@@ -1483,7 +1516,7 @@ index 04c5f417d..6322f5873 100644
/* Check that we can access the stack slot of the register with one
direct load with no adjustments needed. */
-@@ -8164,9 +8162,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9509,9 +9507,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
rtx reg = gen_rtx_REG (mode, regno);
poly_int64 offset = frame.reg_offset[regno];
if (frame_pointer_needed)
@@ -1494,7 +1527,7 @@ index 04c5f417d..6322f5873 100644
rtx addr = plus_constant (Pmode, ptr_reg, offset);
rtx mem = gen_frame_mem (mode, addr);
-@@ -8218,9 +8214,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+@@ -9563,9 +9559,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
/* REGNO2 can be saved/restored in a pair with REGNO. */
rtx reg2 = gen_rtx_REG (mode, regno2);
if (frame_pointer_needed)
@@ -1505,7 +1538,7 @@ index 04c5f417d..6322f5873 100644
rtx addr2 = plus_constant (Pmode, ptr_reg, offset2);
rtx mem2 = gen_frame_mem (mode, addr2);
rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2)
-@@ -8336,7 +8330,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -9681,7 +9675,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
if (final_adjustment_p
&& known_eq (frame.below_hard_fp_saved_regs_size, 0))
{
@@ -1516,10 +1549,10 @@ index 04c5f417d..6322f5873 100644
min_probe_threshold -= lr_offset.to_constant ();
else
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index 8f84f66ad..beef542d7 100644
+index 108a5731b0d..c8becb098c8 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -824,6 +824,9 @@ extern enum aarch64_processor aarch64_tune;
+@@ -766,6 +766,9 @@ extern enum aarch64_processor aarch64_tune;
#ifdef HAVE_POLY_INT_H
struct GTY (()) aarch64_frame
{
@@ -1530,12 +1563,12 @@ index 8f84f66ad..beef542d7 100644
/* The number of extra stack bytes taken up by register varargs.
--
-2.17.1
+2.39.4
-From 6b1fdbe7f3771e7e2c9a37332e1a2146a113b539 Mon Sep 17 00:00:00 2001
+From 79faabda181d0d9fd29a3cf5726ba65bdee945b5 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:48 +0100
+Date: Tue, 12 Sep 2023 16:07:17 +0100
Subject: [PATCH 12/19] aarch64: Simplify top of frame allocation
After previous patches, it no longer really makes sense to allocate
@@ -1543,17 +1576,17 @@ the top of the frame in terms of varargs_and_saved_regs_size and
saved_regs_and_above.
gcc/
- * config/aarch64/aarch64.c (aarch64_layout_frame): Simplify
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Simplify
the allocation of the top of the frame.
---
- gcc/config/aarch64/aarch64.c | 23 ++++++++---------------
+ gcc/config/aarch64/aarch64.cc | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 6322f5873..b4c1006e6 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7323,23 +7323,16 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index af99807ef8a..31b00094c2a 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8586,23 +8586,16 @@ aarch64_layout_frame (void)
frame.saved_regs_size = offset - frame.bytes_below_saved_regs;
@@ -1586,12 +1619,12 @@ index 6322f5873..b4c1006e6 100644
frame.initial_adjust = 0;
frame.final_adjust = 0;
--
-2.17.1
+2.39.4
-From 9ddd52ddd2427a2a69309bde19d175b4362e26da Mon Sep 17 00:00:00 2001
+From 4e62049e403b141e6f916176160dac8cbd65fe47 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:49 +0100
+Date: Tue, 12 Sep 2023 16:07:18 +0100
Subject: [PATCH 13/19] aarch64: Minor initial adjustment tweak
This patch just changes a calculation of initial_adjust
@@ -1599,18 +1632,18 @@ to one that makes it slightly more obvious that the total
adjustment is frame.frame_size.
gcc/
- * config/aarch64/aarch64.c (aarch64_layout_frame): Tweak
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Tweak
calculation of initial_adjust for frames in which all saves
are SVE saves.
---
- gcc/config/aarch64/aarch64.c | 5 ++---
+ gcc/config/aarch64/aarch64.cc | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index b4c1006e6..3f4716897 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7384,11 +7384,10 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 31b00094c2a..1aa79da0673 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8675,11 +8675,10 @@ aarch64_layout_frame (void)
{
/* Frame in which all saves are SVE saves:
@@ -1625,12 +1658,12 @@ index b4c1006e6..3f4716897 100644
}
else if (frame.bytes_above_hard_fp.is_constant (&const_above_fp)
--
-2.17.1
+2.39.4
-From 0d013411f079b578e45e7ef466ea4e3ad7287015 Mon Sep 17 00:00:00 2001
+From aaa1a0a5912d9e5d571e5f1c6f09ceac99544ab5 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:49 +0100
+Date: Tue, 12 Sep 2023 16:07:18 +0100
Subject: [PATCH 14/19] aarch64: Tweak stack clash boundary condition
The AArch64 ABI says that, when stack clash protection is used,
@@ -1660,23 +1693,23 @@ as required. Continuing to probe allocations of exactly 1KiB
would complicate later patches.
gcc/
- * config/aarch64/aarch64.c (aarch64_allocate_and_probe_stack_space):
+ * config/aarch64/aarch64.cc (aarch64_allocate_and_probe_stack_space):
Don't probe final allocations that are exactly 1KiB in size (after
unprobed space above the final allocation has been deducted).
gcc/testsuite/
* gcc.target/aarch64/stack-check-prologue-17.c: New test.
---
- gcc/config/aarch64/aarch64.c | 4 +-
+ gcc/config/aarch64/aarch64.cc | 4 +-
.../aarch64/stack-check-prologue-17.c | 55 +++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 3f4716897..d9cf978b0 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -8303,9 +8303,11 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 1aa79da0673..5cad847977a 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -9648,9 +9648,11 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
HOST_WIDE_INT guard_size
= 1 << param_stack_clash_protection_guard_size;
HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD;
@@ -1691,7 +1724,7 @@ index 3f4716897..d9cf978b0 100644
account any unprobed space there is above the current SP. There are
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
new file mode 100644
-index 000000000..0d8a25d73
+index 00000000000..0d8a25d73a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
@@ -0,0 +1,55 @@
@@ -1751,12 +1784,12 @@ index 000000000..0d8a25d73
+ return 1;
+}
--
-2.17.1
+2.39.4
-From 5fc70b2d3b0425076ef69ff18afc9556ae1dd8d0 Mon Sep 17 00:00:00 2001
+From 8433953434a7b58c0923140d39eb3c5988c1d097 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:49 +0100
+Date: Tue, 12 Sep 2023 16:07:19 +0100
Subject: [PATCH 15/19] aarch64: Put LR save probe in first 16 bytes
-fstack-clash-protection uses the save of LR as a probe for the next
@@ -1795,31 +1828,41 @@ which allocates guard page size + 64 consecutive unprobed bytes.
This patch requires the LR probe to be in the first 16 bytes of the
save area when stack clash protection is active. Doing it
-unconditionally would cause code-quality regressions, but a later
-patch deals with that.
+unconditionally would cause code-quality regressions.
+
+Putting LR before other registers prevents push/pop allocation
+when shadow call stacks are enabled, since LR is restored
+separately from the other callee-saved registers.
The new comment doesn't say that the probe register is required
to be LR, since a later patch removes that restriction.
gcc/
- * config/aarch64/aarch64.c (aarch64_layout_frame): Ensure that
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Ensure that
the LR save slot is in the first 16 bytes of the register save area.
+ Only form STP/LDP push/pop candidates if both registers are valid.
(aarch64_allocate_and_probe_stack_space): Remove workaround for
when LR was not in the first 16 bytes.
gcc/testsuite/
* gcc.target/aarch64/stack-check-prologue-18.c: New test.
+ * gcc.target/aarch64/stack-check-prologue-19.c: Likewise.
+ * gcc.target/aarch64/stack-check-prologue-20.c: Likewise.
---
- gcc/config/aarch64/aarch64.c | 61 ++++-------
+ gcc/config/aarch64/aarch64.cc | 72 ++++++-------
.../aarch64/stack-check-prologue-18.c | 100 ++++++++++++++++++
- 2 files changed, 123 insertions(+), 38 deletions(-)
+ .../aarch64/stack-check-prologue-19.c | 100 ++++++++++++++++++
+ .../aarch64/stack-check-prologue-20.c | 3 +
+ 4 files changed, 233 insertions(+), 42 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
-
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index d9cf978b0..aa8763662 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7271,26 +7271,34 @@ aarch64_layout_frame (void)
+ create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
+ create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
+
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 5cad847977a..a765f92329d 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8534,26 +8534,34 @@ aarch64_layout_frame (void)
bool saves_below_hard_fp_p
= maybe_ne (frame.below_hard_fp_saved_regs_size, 0);
frame.bytes_below_hard_fp = offset;
@@ -1827,10 +1870,10 @@ index d9cf978b0..aa8763662 100644
+ auto allocate_gpr_slot = [&](unsigned int regno)
+ {
+ frame.reg_offset[regno] = offset;
-+ if (frame.wb_candidate1 == INVALID_REGNUM)
-+ frame.wb_candidate1 = regno;
-+ else if (frame.wb_candidate2 == INVALID_REGNUM)
-+ frame.wb_candidate2 = regno;
++ if (frame.wb_push_candidate1 == INVALID_REGNUM)
++ frame.wb_push_candidate1 = regno;
++ else if (frame.wb_push_candidate2 == INVALID_REGNUM)
++ frame.wb_push_candidate2 = regno;
+ offset += UNITS_PER_WORD;
+ };
+
@@ -1838,9 +1881,9 @@ index d9cf978b0..aa8763662 100644
{
/* FP and LR are placed in the linkage record. */
- frame.reg_offset[R29_REGNUM] = offset;
-- frame.wb_candidate1 = R29_REGNUM;
+- frame.wb_push_candidate1 = R29_REGNUM;
- frame.reg_offset[R30_REGNUM] = offset + UNITS_PER_WORD;
-- frame.wb_candidate2 = R30_REGNUM;
+- frame.wb_push_candidate2 = R30_REGNUM;
- offset += 2 * UNITS_PER_WORD;
+ allocate_gpr_slot (R29_REGNUM);
+ allocate_gpr_slot (R30_REGNUM);
@@ -1857,17 +1900,35 @@ index d9cf978b0..aa8763662 100644
if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED))
- {
- frame.reg_offset[regno] = offset;
-- if (frame.wb_candidate1 == INVALID_REGNUM)
-- frame.wb_candidate1 = regno;
-- else if (frame.wb_candidate2 == INVALID_REGNUM)
-- frame.wb_candidate2 = regno;
+- if (frame.wb_push_candidate1 == INVALID_REGNUM)
+- frame.wb_push_candidate1 = regno;
+- else if (frame.wb_push_candidate2 == INVALID_REGNUM)
+- frame.wb_push_candidate2 = regno;
- offset += UNITS_PER_WORD;
- }
+ allocate_gpr_slot (regno);
poly_int64 max_int_offset = offset;
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
-@@ -8309,29 +8317,6 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -8631,10 +8639,13 @@ aarch64_layout_frame (void)
+ max_push_offset to 0, because no registers are popped at this time,
+ so callee_adjust cannot be adjusted. */
+ HOST_WIDE_INT max_push_offset = 0;
+- if (frame.wb_pop_candidate2 != INVALID_REGNUM)
+- max_push_offset = 512;
+- else if (frame.wb_pop_candidate1 != INVALID_REGNUM)
+- max_push_offset = 256;
++ if (frame.wb_pop_candidate1 != INVALID_REGNUM)
++ {
++ if (frame.wb_pop_candidate2 != INVALID_REGNUM)
++ max_push_offset = 512;
++ else
++ max_push_offset = 256;
++ }
+
+ HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp;
+ HOST_WIDE_INT const_saved_regs_size;
+@@ -9654,29 +9665,6 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
= (final_adjustment_p
? guard_used_by_caller + byte_sp_alignment
: guard_size - guard_used_by_caller);
@@ -1897,7 +1958,7 @@ index d9cf978b0..aa8763662 100644
poly_int64 frame_size = frame.frame_size;
/* We should always have a positive probe threshold. */
-@@ -8511,8 +8496,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -9856,8 +9844,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
if (final_adjustment_p && rounded_size != 0)
min_probe_threshold = 0;
/* If doing a small final adjustment, we always probe at offset 0.
@@ -1910,7 +1971,7 @@ index d9cf978b0..aa8763662 100644
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
new file mode 100644
-index 000000000..82447d20f
+index 00000000000..82447d20fff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
@@ -0,0 +1,100 @@
@@ -2014,13 +2075,128 @@ index 000000000..82447d20f
+ g();
+ return 1;
+}
+diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
+new file mode 100644
+index 00000000000..73ac3e4e4eb
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
+@@ -0,0 +1,100 @@
++/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18" } */
++/* { dg-final { check-function-bodies "**" "" } } */
++
++void f(int, ...);
++void g();
++
++/*
++** test1:
++** ...
++** str x30, \[sp\]
++** sub sp, sp, #4064
++** str xzr, \[sp\]
++** cbnz w0, .*
++** bl g
++** ...
++** str x26, \[sp, #?4128\]
++** ...
++*/
++int test1(int z) {
++ __uint128_t x = 0;
++ int y[0x400];
++ if (z)
++ {
++ asm volatile ("" :::
++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26");
++ f(0, 0, 0, 0, 0, 0, 0, &y,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x);
++ }
++ g();
++ return 1;
++}
++
++/*
++** test2:
++** ...
++** str x30, \[sp\]
++** sub sp, sp, #1040
++** str xzr, \[sp\]
++** cbnz w0, .*
++** bl g
++** ...
++*/
++int test2(int z) {
++ __uint128_t x = 0;
++ int y[0x400];
++ if (z)
++ {
++ asm volatile ("" :::
++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26");
++ f(0, 0, 0, 0, 0, 0, 0, &y,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x);
++ }
++ g();
++ return 1;
++}
++
++/*
++** test3:
++** ...
++** str x30, \[sp\]
++** sub sp, sp, #1024
++** cbnz w0, .*
++** bl g
++** ...
++*/
++int test3(int z) {
++ __uint128_t x = 0;
++ int y[0x400];
++ if (z)
++ {
++ asm volatile ("" :::
++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26");
++ f(0, 0, 0, 0, 0, 0, 0, &y,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x);
++ }
++ g();
++ return 1;
++}
+diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
+new file mode 100644
+index 00000000000..690aae8dfd5
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
+@@ -0,0 +1,3 @@
++/* { dg-options "-O2 -fstack-protector-all -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18" } */
++
++#include "stack-check-prologue-19.c"
--
-2.17.1
+2.39.4
-From 24c1410b55c15966311ab39039f5b0aab0a658f7 Mon Sep 17 00:00:00 2001
+From eea1759073e09dd1aefbc9a881601ab1eebfdd18 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:51 +0100
+Date: Tue, 12 Sep 2023 16:07:19 +0100
Subject: [PATCH 16/19] aarch64: Simplify probe of final frame allocation
Previous patches ensured that the final frame allocation only needs
@@ -2031,7 +2207,7 @@ The main motivation for doing this is to simplify the code and
remove the number of special cases.
gcc/
- * config/aarch64/aarch64.c (aarch64_allocate_and_probe_stack_space):
+ * config/aarch64/aarch64.cc (aarch64_allocate_and_probe_stack_space):
Always probe the residual allocation at offset 1024, asserting
that that is in range.
@@ -2039,17 +2215,19 @@ gcc/testsuite/
* gcc.target/aarch64/stack-check-prologue-17.c: Expect the probe
to be at offset 1024 rather than offset 0.
* gcc.target/aarch64/stack-check-prologue-18.c: Likewise.
+ * gcc.target/aarch64/stack-check-prologue-19.c: Likewise.
---
- gcc/config/aarch64/aarch64.c | 12 ++++--------
+ gcc/config/aarch64/aarch64.cc | 12 ++++--------
.../gcc.target/aarch64/stack-check-prologue-17.c | 2 +-
.../gcc.target/aarch64/stack-check-prologue-18.c | 4 ++--
- 3 files changed, 7 insertions(+), 11 deletions(-)
-
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index aa8763662..2a6fddb69 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -8490,16 +8490,12 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+ .../gcc.target/aarch64/stack-check-prologue-19.c | 4 ++--
+ 4 files changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index a765f92329d..37809a306f7 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -9838,16 +9838,12 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
are still safe. */
if (residual)
{
@@ -2068,7 +2246,7 @@ index aa8763662..2a6fddb69 100644
aarch64_sub_sp (temp1, temp2, residual, frame_related_p);
if (residual >= min_probe_threshold)
-@@ -8510,8 +8506,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
+@@ -9858,8 +9854,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
HOST_WIDE_INT_PRINT_DEC " bytes, probing will be required."
"\n", residual);
@@ -2080,7 +2258,7 @@ index aa8763662..2a6fddb69 100644
}
}
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
-index 0d8a25d73..f0ec13897 100644
+index 0d8a25d73a2..f0ec1389771 100644
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
@@ -33,7 +33,7 @@ int test1(int z) {
@@ -2093,7 +2271,7 @@ index 0d8a25d73..f0ec13897 100644
** bl g
** ...
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
-index 82447d20f..6383bec5e 100644
+index 82447d20fff..6383bec5ebc 100644
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
@@ -9,7 +9,7 @@ void g();
@@ -2110,17 +2288,39 @@ index 82447d20f..6383bec5e 100644
** str x30, \[sp\]
** sub sp, sp, #1040
-** str xzr, \[sp\]
++** str xzr, \[sp, #?1024\]
+ ** cbnz w0, .*
+ ** bl g
+ ** ...
+diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
+index 73ac3e4e4eb..562039b5e9b 100644
+--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
+@@ -9,7 +9,7 @@ void g();
+ ** ...
+ ** str x30, \[sp\]
+ ** sub sp, sp, #4064
+-** str xzr, \[sp\]
++** str xzr, \[sp, #?1024\]
+ ** cbnz w0, .*
+ ** bl g
+ ** ...
+@@ -50,7 +50,7 @@ int test1(int z) {
+ ** ...
+ ** str x30, \[sp\]
+ ** sub sp, sp, #1040
+-** str xzr, \[sp\]
+** str xzr, \[sp, #?1024\]
** cbnz w0, .*
** bl g
** ...
--
-2.17.1
+2.39.4
-From d9ea75050b701dd9258822f0de5efb7bfa197ed1 Mon Sep 17 00:00:00 2001
+From 96d85187c3b9c9a7efc2fd698c3d452e80d8aa47 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:52 +0100
+Date: Tue, 12 Sep 2023 16:07:20 +0100
Subject: [PATCH 17/19] aarch64: Explicitly record probe registers in frame
info
@@ -2176,7 +2376,7 @@ The patch also avoids unnecessary probes in sve/pcs/stack_clash_3.c.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::sve_save_and_probe)
(aarch64_frame::hard_fp_save_and_probe): New fields.
- * config/aarch64/aarch64.c (aarch64_layout_frame): Initialize them.
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Initialize them.
Rather than asserting that a leaf function saves LR, instead assert
that a leaf function saves something.
(aarch64_get_separate_components): Prevent the chosen probe
@@ -2187,16 +2387,16 @@ gcc/
gcc/testsuite/
* gcc.target/aarch64/sve/pcs/stack_clash_3.c: Avoid redundant probes.
---
- gcc/config/aarch64/aarch64.c | 68 +++++++++++++++----
+ gcc/config/aarch64/aarch64.cc | 68 +++++++++++++++----
gcc/config/aarch64/aarch64.h | 8 +++
.../aarch64/sve/pcs/stack_clash_3.c | 6 +-
3 files changed, 64 insertions(+), 18 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 2a6fddb69..5fb4ef251 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7208,15 +7208,11 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 37809a306f7..6c59c39a639 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8471,15 +8471,11 @@ aarch64_layout_frame (void)
&& !crtl->abi->clobbers_full_reg_p (regno))
frame.reg_offset[regno] = SLOT_REQUIRED;
@@ -2213,7 +2413,7 @@ index 2a6fddb69..5fb4ef251 100644
/* Now assign stack slots for the registers. Start with the predicate
registers, since predicate LDR and STR have a relatively small
-@@ -7224,6 +7220,8 @@ aarch64_layout_frame (void)
+@@ -8487,6 +8483,8 @@ aarch64_layout_frame (void)
for (regno = P0_REGNUM; regno <= P15_REGNUM; regno++)
if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED))
{
@@ -2222,7 +2422,7 @@ index 2a6fddb69..5fb4ef251 100644
frame.reg_offset[regno] = offset;
offset += BYTES_PER_SVE_PRED;
}
-@@ -7261,6 +7259,8 @@ aarch64_layout_frame (void)
+@@ -8524,6 +8522,8 @@ aarch64_layout_frame (void)
for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED))
{
@@ -2231,7 +2431,7 @@ index 2a6fddb69..5fb4ef251 100644
frame.reg_offset[regno] = offset;
offset += vector_save_size;
}
-@@ -7270,10 +7270,18 @@ aarch64_layout_frame (void)
+@@ -8533,10 +8533,18 @@ aarch64_layout_frame (void)
frame.below_hard_fp_saved_regs_size = offset - frame.bytes_below_saved_regs;
bool saves_below_hard_fp_p
= maybe_ne (frame.below_hard_fp_saved_regs_size, 0);
@@ -2248,9 +2448,9 @@ index 2a6fddb69..5fb4ef251 100644
+ if (frame.hard_fp_save_and_probe == INVALID_REGNUM)
+ frame.hard_fp_save_and_probe = regno;
frame.reg_offset[regno] = offset;
- if (frame.wb_candidate1 == INVALID_REGNUM)
- frame.wb_candidate1 = regno;
-@@ -7307,6 +7315,8 @@ aarch64_layout_frame (void)
+ if (frame.wb_push_candidate1 == INVALID_REGNUM)
+ frame.wb_push_candidate1 = regno;
+@@ -8570,6 +8578,8 @@ aarch64_layout_frame (void)
for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED))
{
@@ -2259,7 +2459,7 @@ index 2a6fddb69..5fb4ef251 100644
/* If there is an alignment gap between integer and fp callee-saves,
allocate the last fp register to it if possible. */
if (regno == last_fp_reg
-@@ -7330,6 +7340,17 @@ aarch64_layout_frame (void)
+@@ -8593,6 +8603,17 @@ aarch64_layout_frame (void)
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
frame.saved_regs_size = offset - frame.bytes_below_saved_regs;
@@ -2277,7 +2477,7 @@ index 2a6fddb69..5fb4ef251 100644
offset += get_frame_size ();
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
-@@ -7429,6 +7450,25 @@ aarch64_layout_frame (void)
+@@ -8723,6 +8744,25 @@ aarch64_layout_frame (void)
frame.final_adjust = frame.bytes_below_saved_regs;
}
@@ -2303,7 +2503,7 @@ index 2a6fddb69..5fb4ef251 100644
/* Make sure the individual adjustments add up to the full frame size. */
gcc_assert (known_eq (frame.initial_adjust
+ frame.callee_adjust
-@@ -8006,13 +8046,6 @@ aarch64_get_separate_components (void)
+@@ -9354,13 +9394,6 @@ aarch64_get_separate_components (void)
poly_int64 offset = frame.reg_offset[regno];
@@ -2317,7 +2517,7 @@ index 2a6fddb69..5fb4ef251 100644
/* Get the offset relative to the register we'll use. */
if (frame_pointer_needed)
offset -= frame.bytes_below_hard_fp;
-@@ -8047,6 +8080,13 @@ aarch64_get_separate_components (void)
+@@ -9395,6 +9428,13 @@ aarch64_get_separate_components (void)
bitmap_clear_bit (components, LR_REGNUM);
bitmap_clear_bit (components, SP_REGNUM);
@@ -2331,7 +2531,7 @@ index 2a6fddb69..5fb4ef251 100644
return components;
}
-@@ -8583,8 +8623,8 @@ aarch64_epilogue_uses (int regno)
+@@ -9931,8 +9971,8 @@ aarch64_epilogue_uses (int regno)
When probing is needed, we emit a probe at the start of the prologue
and every PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE bytes thereafter.
@@ -2343,10 +2543,10 @@ index 2a6fddb69..5fb4ef251 100644
For outgoing arguments we probe if the size is larger than 1KB, such that
the ABI specified buffer is maintained for the next callee.
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index beef542d7..8f6f44992 100644
+index c8becb098c8..fbfb73545ba 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -909,6 +909,14 @@ struct GTY (()) aarch64_frame
+@@ -863,6 +863,14 @@ struct GTY (()) aarch64_frame
This is the register they should use. */
unsigned spare_pred_reg;
@@ -2359,10 +2559,10 @@ index beef542d7..8f6f44992 100644
+ unsigned hard_fp_save_and_probe;
+
bool laid_out;
- };
+ /* True if shadow call stack should be enabled for the current function. */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c b/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c
-index 3e01ec36c..3530a0d50 100644
+index 3e01ec36c3a..3530a0d504b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c
@@ -11,11 +11,10 @@
@@ -2394,12 +2594,12 @@ index 3e01ec36c..3530a0d50 100644
** ldr x24, \[sp\], 32
** ret
--
-2.17.1
+2.39.4
-From a302261309a560c4dfd43d1bc0550901df66ad32 Mon Sep 17 00:00:00 2001
+From 56df065080950bb30dda9c260f71be54269bdda5 Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:52 +0100
+Date: Tue, 12 Sep 2023 16:07:20 +0100
Subject: [PATCH 18/19] aarch64: Remove below_hard_fp_saved_regs_size
After previous patches, it's no longer necessary to store
@@ -2410,17 +2610,17 @@ reference points.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::saved_regs_size)
(aarch64_frame::below_hard_fp_saved_regs_size): Delete.
- * config/aarch64/aarch64.c (aarch64_layout_frame): Update accordingly.
+ * config/aarch64/aarch64.cc (aarch64_layout_frame): Update accordingly.
---
- gcc/config/aarch64/aarch64.c | 45 +++++++++++++++++-------------------
- gcc/config/aarch64/aarch64.h | 7 ------
+ gcc/config/aarch64/aarch64.cc | 45 ++++++++++++++++-------------------
+ gcc/config/aarch64/aarch64.h | 7 ------
2 files changed, 21 insertions(+), 31 deletions(-)
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index 5fb4ef251..dd1d894f4 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7267,9 +7267,8 @@ aarch64_layout_frame (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index 6c59c39a639..b95e805a8cc 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8530,9 +8530,8 @@ aarch64_layout_frame (void)
/* OFFSET is now the offset of the hard frame pointer from the bottom
of the callee save area. */
@@ -2432,7 +2632,7 @@ index 5fb4ef251..dd1d894f4 100644
gcc_assert (!saves_below_hard_fp_p
|| (frame.sve_save_and_probe != INVALID_REGNUM
&& known_eq (frame.reg_offset[frame.sve_save_and_probe],
-@@ -7339,9 +7338,8 @@ aarch64_layout_frame (void)
+@@ -8602,9 +8601,8 @@ aarch64_layout_frame (void)
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
@@ -2444,7 +2644,7 @@ index 5fb4ef251..dd1d894f4 100644
|| (frame.hard_fp_save_and_probe != INVALID_REGNUM
&& known_eq (frame.reg_offset[frame.hard_fp_save_and_probe],
frame.bytes_below_hard_fp)));
-@@ -7350,7 +7348,7 @@ aarch64_layout_frame (void)
+@@ -8613,7 +8611,7 @@ aarch64_layout_frame (void)
The saving of the bottommost register counts as an implicit probe,
which allows us to maintain the invariant described in the comment
at expand_prologue. */
@@ -2453,7 +2653,7 @@ index 5fb4ef251..dd1d894f4 100644
offset += get_frame_size ();
offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT);
-@@ -7376,7 +7374,7 @@ aarch64_layout_frame (void)
+@@ -8670,7 +8668,7 @@ aarch64_layout_frame (void)
HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp;
HOST_WIDE_INT const_saved_regs_size;
@@ -2462,7 +2662,7 @@ index 5fb4ef251..dd1d894f4 100644
frame.initial_adjust = frame.frame_size;
else if (frame.frame_size.is_constant (&const_size)
&& const_size < max_push_offset
-@@ -7389,7 +7387,7 @@ aarch64_layout_frame (void)
+@@ -8683,7 +8681,7 @@ aarch64_layout_frame (void)
frame.callee_adjust = const_size;
}
else if (frame.bytes_below_saved_regs.is_constant (&const_below_saved_regs)
@@ -2471,7 +2671,7 @@ index 5fb4ef251..dd1d894f4 100644
&& const_below_saved_regs + const_saved_regs_size < 512
/* We could handle this case even with data below the saved
registers, provided that that data left us with valid offsets
-@@ -7408,8 +7406,7 @@ aarch64_layout_frame (void)
+@@ -8702,8 +8700,7 @@ aarch64_layout_frame (void)
frame.initial_adjust = frame.frame_size;
}
else if (saves_below_hard_fp_p
@@ -2481,7 +2681,7 @@ index 5fb4ef251..dd1d894f4 100644
{
/* Frame in which all saves are SVE saves:
-@@ -7431,7 +7428,7 @@ aarch64_layout_frame (void)
+@@ -8725,7 +8722,7 @@ aarch64_layout_frame (void)
[save SVE registers relative to SP]
sub sp, sp, bytes_below_saved_regs */
frame.callee_adjust = const_above_fp;
@@ -2490,7 +2690,7 @@ index 5fb4ef251..dd1d894f4 100644
frame.final_adjust = frame.bytes_below_saved_regs;
}
else
-@@ -7446,7 +7443,7 @@ aarch64_layout_frame (void)
+@@ -8740,7 +8737,7 @@ aarch64_layout_frame (void)
[save SVE registers relative to SP]
sub sp, sp, bytes_below_saved_regs */
frame.initial_adjust = frame.bytes_above_hard_fp;
@@ -2499,7 +2699,7 @@ index 5fb4ef251..dd1d894f4 100644
frame.final_adjust = frame.bytes_below_saved_regs;
}
-@@ -8588,17 +8585,17 @@ aarch64_epilogue_uses (int regno)
+@@ -9936,17 +9933,17 @@ aarch64_epilogue_uses (int regno)
| local variables | <-- frame_pointer_rtx
| |
+-------------------------------+
@@ -2529,10 +2729,10 @@ index 5fb4ef251..dd1d894f4 100644
| dynamic allocation |
+-------------------------------+
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
-index 8f6f44992..e408af22e 100644
+index fbfb73545ba..cfeaf4657ab 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
-@@ -835,18 +835,11 @@ struct GTY (()) aarch64_frame
+@@ -777,18 +777,11 @@ struct GTY (()) aarch64_frame
STACK_BOUNDARY. */
HOST_WIDE_INT saved_varargs_size;
@@ -2552,12 +2752,12 @@ index 8f6f44992..e408af22e 100644
of the outgoing arguments) and the hard frame pointer. This value is
always a multiple of STACK_BOUNDARY. */
--
-2.17.1
+2.39.4
-From 8a28201f0697927351c00bd5bc7e7775f074c2a3 Mon Sep 17 00:00:00 2001
+From b96e66fd4ef3e36983969fb8cdd1956f551a074b Mon Sep 17 00:00:00 2001
From: Richard Sandiford
-Date: Tue, 12 Sep 2023 16:19:52 +0100
+Date: Tue, 12 Sep 2023 16:07:21 +0100
Subject: [PATCH 19/19] aarch64: Make stack smash canary protect saved
registers
@@ -2577,7 +2777,7 @@ the saved registers when stack smash protection is active.
The patch fixes CVE-2023-4039.
gcc/
- * config/aarch64/aarch64.c (aarch64_save_regs_above_locals_p):
+ * config/aarch64/aarch64.cc (aarch64_save_regs_above_locals_p):
New function.
(aarch64_layout_frame): Use it to decide whether locals should
go above or below the saved registers.
@@ -2588,18 +2788,18 @@ gcc/testsuite/
* gcc.target/aarch64/stack-protector-8.c: New test.
* gcc.target/aarch64/stack-protector-9.c: Likewise.
---
- gcc/config/aarch64/aarch64.c | 46 +++++++--
+ gcc/config/aarch64/aarch64.cc | 46 +++++++--
.../gcc.target/aarch64/stack-protector-8.c | 95 +++++++++++++++++++
.../gcc.target/aarch64/stack-protector-9.c | 33 +++++++
3 files changed, 168 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-8.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-9.c
-diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
-index dd1d894f4..a97b39421 100644
---- a/gcc/config/aarch64/aarch64.c
-+++ b/gcc/config/aarch64/aarch64.c
-@@ -7131,6 +7131,20 @@ aarch64_needs_frame_chain (void)
+diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
+index b95e805a8cc..389c0e29353 100644
+--- a/gcc/config/aarch64/aarch64.cc
++++ b/gcc/config/aarch64/aarch64.cc
+@@ -8394,6 +8394,20 @@ aarch64_needs_frame_chain (void)
return aarch64_use_frame_pointer;
}
@@ -2620,7 +2820,7 @@ index dd1d894f4..a97b39421 100644
/* Mark the registers that need to be saved by the callee and calculate
the size of the callee-saved registers area and frame record (both FP
and LR may be omitted). */
-@@ -7142,6 +7156,7 @@ aarch64_layout_frame (void)
+@@ -8405,6 +8419,7 @@ aarch64_layout_frame (void)
poly_int64 vector_save_size = GET_MODE_SIZE (vector_save_mode);
bool frame_related_fp_reg_p = false;
aarch64_frame &frame = cfun->machine->frame;
@@ -2628,7 +2828,7 @@ index dd1d894f4..a97b39421 100644
frame.emit_frame_chain = aarch64_needs_frame_chain ();
-@@ -7208,9 +7223,16 @@ aarch64_layout_frame (void)
+@@ -8471,9 +8486,16 @@ aarch64_layout_frame (void)
&& !crtl->abi->clobbers_full_reg_p (regno))
frame.reg_offset[regno] = SLOT_REQUIRED;
@@ -2645,7 +2845,7 @@ index dd1d894f4..a97b39421 100644
frame.bytes_below_saved_regs = offset;
frame.sve_save_and_probe = INVALID_REGNUM;
-@@ -7350,15 +7372,18 @@ aarch64_layout_frame (void)
+@@ -8613,15 +8635,18 @@ aarch64_layout_frame (void)
at expand_prologue. */
gcc_assert (crtl->is_leaf || maybe_ne (saved_regs_size, 0));
@@ -2668,7 +2868,7 @@ index dd1d894f4..a97b39421 100644
frame.bytes_above_locals = frame.frame_size - top_of_locals;
frame.initial_adjust = 0;
-@@ -8582,10 +8607,10 @@ aarch64_epilogue_uses (int regno)
+@@ -9930,10 +9955,10 @@ aarch64_epilogue_uses (int regno)
| for register varargs |
| |
+-------------------------------+
@@ -2681,7 +2881,7 @@ index dd1d894f4..a97b39421 100644
+-------------------------------+
| callee-saved registers |
+-------------------------------+
-@@ -8597,6 +8622,10 @@ aarch64_epilogue_uses (int regno)
+@@ -9945,6 +9970,10 @@ aarch64_epilogue_uses (int regno)
+-------------------------------+
| SVE predicate registers |
+-------------------------------+
@@ -2692,7 +2892,7 @@ index dd1d894f4..a97b39421 100644
| dynamic allocation |
+-------------------------------+
| padding |
-@@ -8606,6 +8635,9 @@ aarch64_epilogue_uses (int regno)
+@@ -9954,6 +9983,9 @@ aarch64_epilogue_uses (int regno)
+-------------------------------+
| | <-- stack_pointer_rtx (aligned)
@@ -2702,7 +2902,7 @@ index dd1d894f4..a97b39421 100644
Dynamic stack allocations via alloca() decrease stack_pointer_rtx
but leave frame_pointer_rtx and hard_frame_pointer_rtx
unchanged.
-@@ -8797,6 +8829,8 @@ aarch64_expand_prologue (void)
+@@ -10149,6 +10181,8 @@ aarch64_expand_prologue (void)
gcc_assert (known_eq (bytes_below_sp, final_adjust));
aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, final_adjust,
!frame_pointer_needed, true);
@@ -2713,7 +2913,7 @@ index dd1d894f4..a97b39421 100644
/* Return TRUE if we can use a simple_return insn.
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c
new file mode 100644
-index 000000000..e71d820e3
+index 00000000000..e71d820e365
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c
@@ -0,0 +1,95 @@
@@ -2814,7 +3014,7 @@ index 000000000..e71d820e3
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c
new file mode 100644
-index 000000000..58f322aa4
+index 00000000000..58f322aa480
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c
@@ -0,0 +1,33 @@
@@ -2852,5 +3052,5 @@ index 000000000..58f322aa4
+ return 0;
+}
--
-2.17.1
+2.39.4
diff --git a/SPECS/gcc/gcc.spec b/SPECS/gcc/gcc.spec
index b050745feec..fd22dbf7877 100644
--- a/SPECS/gcc/gcc.spec
+++ b/SPECS/gcc/gcc.spec
@@ -56,14 +56,14 @@
Summary: Contains the GNU compiler collection
Name: gcc
Version: 13.2.0
-Release: 6%{?dist}
+Release: 7%{?dist}
License: GPLv2+
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: Development/Tools
URL: https://gcc.gnu.org/
Source0: https://ftp.gnu.org/gnu/gcc/%{name}-%{version}/%{name}-%{version}.tar.xz
-#Patch0: CVE-2023-4039.patch
+Patch0: CVE-2023-4039.patch
Patch1: 0011-libsanitizer-Remove-crypt-and-crypt_r-interceptors.patch
BuildRequires: gmp-devel
@@ -523,6 +523,9 @@ $tests_ok
%do_files aarch64-linux-gnu %{build_cross}
%changelog
+* Fri Jun 21 2024 Andrew Phelps - 13.2.0-7
+- Re-enable CVE-2023-4039.patch and refresh against 13.2.0 source
+
* Tue Apr 09 2024 Andrew Phelps - 13.2.0-6
- Revert change to baseline architecture for x86-64-v3
diff --git a/SPECS/glibc/CVE-2023-4806.patch b/SPECS/glibc/CVE-2023-4806.patch
deleted file mode 100644
index 276e7275f4c..00000000000
--- a/SPECS/glibc/CVE-2023-4806.patch
+++ /dev/null
@@ -1,1995 +0,0 @@
-From e3ccb230a961b4797510e6a1f5f21fd9021853e7 Mon Sep 17 00:00:00 2001
-From: Siddhesh Poyarekar
-Date: Fri, 15 Sep 2023 13:51:12 -0400
-Subject: [PATCH] getaddrinfo: Fix use after free in getcanonname
- (CVE-2023-4806)
-
-When an NSS plugin only implements the _gethostbyname2_r and
-_getcanonname_r callbacks, getaddrinfo could use memory that was freed
-during tmpbuf resizing, through h_name in a previous query response.
-
-The backing store for res->at->name when doing a query with
-gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in
-gethosts during the query. For AF_INET6 lookup with AI_ALL |
-AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second
-for a v4 lookup. In this case, if the first call reallocates tmpbuf
-enough number of times, resulting in a malloc, th->h_name (that
-res->at->name refers to) ends up on a heap allocated storage in tmpbuf.
-Now if the second call to gethosts also causes the plugin callback to
-return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF
-reference in res->at->name. This then gets dereferenced in the
-getcanonname_r plugin call, resulting in the use after free.
-
-Fix this by copying h_name over and freeing it at the end. This
-resolves BZ #30843, which is assigned CVE-2023-4806.
-
-Signed-off-by: Siddhesh Poyarekar
-(cherry picked from commit 973fe93a5675c42798b2161c6f29c01b0e243994)
----
- nss/Makefile | 15 ++++-
- nss/nss_test_gai_hv2_canonname.c | 56 +++++++++++++++++
- nss/tst-nss-gai-hv2-canonname.c | 63 +++++++++++++++++++
- nss/tst-nss-gai-hv2-canonname.h | 1 +
- .../postclean.req | 0
- .../tst-nss-gai-hv2-canonname.script | 2 +
- sysdeps/posix/getaddrinfo.c | 25 +++++---
- 7 files changed, 152 insertions(+), 10 deletions(-)
- create mode 100644 nss/nss_test_gai_hv2_canonname.c
- create mode 100644 nss/tst-nss-gai-hv2-canonname.c
- create mode 100644 nss/tst-nss-gai-hv2-canonname.h
- create mode 100644 nss/tst-nss-gai-hv2-canonname.root/postclean.req
- create mode 100644 nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
-
-diff -ruN a/nss/Makefile b/nss/Makefile
---- a/nss/Makefile 2022-02-02 21:27:54.000000000 -0800
-+++ b/nss/Makefile 2023-10-03 16:02:01.212592232 -0700
-@@ -69,7 +69,8 @@
- tst-nss-files-hosts-long \
- tst-nss-db-endpwent \
- tst-nss-db-endgrent \
-- tst-reload1 tst-reload2
-+ tst-reload1 tst-reload2 \
-+ tst-nss-gai-hv2-canonname
-
- # Tests which need libdl
- ifeq (yes,$(build-shared))
-@@ -132,7 +133,8 @@
- ifeq ($(build-static-nss),yes)
- tests-static += tst-nss-static
- endif
--extra-test-objs += nss_test1.os nss_test2.os
-+extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
-+ nss_test_gai_hv2_canonname.os
-
- include ../Rules
-
-@@ -166,10 +168,13 @@
-
- libof-nss_test1 = extramodules
- libof-nss_test2 = extramodules
-+libof-nss_test_gai_hv2_canonname = extramodules
- $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
- $(build-module)
- $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
- $(build-module)
-+$(objpfx)/libnss_test_gai_hv2_canonname.so: $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps)
-+ $(build-module)
- $(objpfx)nss_test2.os : nss_test1.c
- ifdef libnss_test1.so-version
- $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
-@@ -179,10 +184,13 @@
- $(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so
- $(make-link)
- endif
-+$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): $(objpfx)/libnss_test_gai_hv2_canonname.so
-+ $(make-link)
- $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \
- $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \
-- $(objpfx)/libnss_test2.so$(libnss_test2.so-version)
--
-+ $(objpfx)/libnss_test2.so$(libnss_test2.so-version) \
-+ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \
-+ $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version)
- ifeq (yes,$(have-thread-library))
- $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
- endif
-@@ -197,3 +205,4 @@
- LDFLAGS-tst-nss-test3 = -Wl,--disable-new-dtags
- LDFLAGS-tst-nss-test4 = -Wl,--disable-new-dtags
- LDFLAGS-tst-nss-test5 = -Wl,--disable-new-dtags
-+LDFLAGS-tst-nss-test_gai_hv2_canonname = -Wl,--disable-new-dtags
-diff --git a/nss/nss_test_gai_hv2_canonname.c b/nss/nss_test_gai_hv2_canonname.c
-new file mode 100644
-index 0000000000..4439c83c9f
---- /dev/null
-+++ b/nss/nss_test_gai_hv2_canonname.c
-@@ -0,0 +1,56 @@
-+/* NSS service provider that only provides gethostbyname2_r.
-+ Copyright The GNU Toolchain Authors.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ . */
-+
-+#include
-+#include
-+#include
-+#include "nss/tst-nss-gai-hv2-canonname.h"
-+
-+/* Catch misnamed and functions. */
-+#pragma GCC diagnostic error "-Wmissing-prototypes"
-+NSS_DECLARE_MODULE_FUNCTIONS (test_gai_hv2_canonname)
-+
-+extern enum nss_status _nss_files_gethostbyname2_r (const char *, int,
-+ struct hostent *, char *,
-+ size_t, int *, int *);
-+
-+enum nss_status
-+_nss_test_gai_hv2_canonname_gethostbyname2_r (const char *name, int af,
-+ struct hostent *result,
-+ char *buffer, size_t buflen,
-+ int *errnop, int *herrnop)
-+{
-+ return _nss_files_gethostbyname2_r (name, af, result, buffer, buflen, errnop,
-+ herrnop);
-+}
-+
-+enum nss_status
-+_nss_test_gai_hv2_canonname_getcanonname_r (const char *name, char *buffer,
-+ size_t buflen, char **result,
-+ int *errnop, int *h_errnop)
-+{
-+ /* We expect QUERYNAME, which is a small enough string that it shouldn't fail
-+ the test. */
-+ if (memcmp (QUERYNAME, name, sizeof (QUERYNAME))
-+ || buflen < sizeof (QUERYNAME))
-+ abort ();
-+
-+ strncpy (buffer, name, buflen);
-+ *result = buffer;
-+ return NSS_STATUS_SUCCESS;
-+}
-diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c
-new file mode 100644
-index 0000000000..d5f10c07d6
---- /dev/null
-+++ b/nss/tst-nss-gai-hv2-canonname.c
-@@ -0,0 +1,63 @@
-+/* Test NSS query path for plugins that only implement gethostbyname2
-+ (#30843).
-+ Copyright The GNU Toolchain Authors.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ . */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include "nss/tst-nss-gai-hv2-canonname.h"
-+
-+#define PREPARE do_prepare
-+
-+static void do_prepare (int a, char **av)
-+{
-+ FILE *hosts = xfopen ("/etc/hosts", "w");
-+ for (unsigned i = 2; i < 255; i++)
-+ {
-+ fprintf (hosts, "ff01::ff02:ff03:%u:2\ttest.example.com\n", i);
-+ fprintf (hosts, "192.168.0.%u\ttest.example.com\n", i);
-+ }
-+ xfclose (hosts);
-+}
-+
-+static int
-+do_test (void)
-+{
-+ __nss_configure_lookup ("hosts", "test_gai_hv2_canonname");
-+
-+ struct addrinfo hints = {};
-+ struct addrinfo *result = NULL;
-+
-+ hints.ai_family = AF_INET6;
-+ hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_CANONNAME;
-+
-+ int ret = getaddrinfo (QUERYNAME, NULL, &hints, &result);
-+
-+ if (ret != 0)
-+ FAIL_EXIT1 ("getaddrinfo failed: %s\n", gai_strerror (ret));
-+
-+ TEST_COMPARE_STRING (result->ai_canonname, QUERYNAME);
-+
-+ freeaddrinfo(result);
-+ return 0;
-+}
-+
-+#include
-diff --git a/nss/tst-nss-gai-hv2-canonname.h b/nss/tst-nss-gai-hv2-canonname.h
-new file mode 100644
-index 0000000000..14f2a9cb08
---- /dev/null
-+++ b/nss/tst-nss-gai-hv2-canonname.h
-@@ -0,0 +1 @@
-+#define QUERYNAME "test.example.com"
-diff --git a/nss/tst-nss-gai-hv2-canonname.root/postclean.req b/nss/tst-nss-gai-hv2-canonname.root/postclean.req
-new file mode 100644
-index 0000000000..e69de29bb2
-diff --git a/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
-new file mode 100644
-index 0000000000..31848b4a28
---- /dev/null
-+++ b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script
-@@ -0,0 +1,2 @@
-+cp $B/nss/libnss_test_gai_hv2_canonname.so $L/libnss_test_gai_hv2_canonname.so.2
-+su
-diff -ruN a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
---- a/sysdeps/posix/getaddrinfo.c 2022-02-02 21:27:54.000000000 -0800
-+++ b/sysdeps/posix/getaddrinfo.c 2023-10-03 16:30:25.792764226 -0700
-@@ -100,14 +100,12 @@
-
- struct gaih_servtuple
- {
-- struct gaih_servtuple *next;
- int socktype;
- int protocol;
- int port;
-+ bool set;
- };
-
--static const struct gaih_servtuple nullserv;
--
-
- struct gaih_typeproto
- {
-@@ -118,6 +116,15 @@
- char name[8];
- };
-
-+struct gaih_result
-+{
-+ struct gaih_addrtuple *at;
-+ char *canon;
-+ char *h_name;
-+ bool free_at;
-+ bool got_ipv6;
-+};
-+
- /* Values for `protoflag'. */
- #define GAI_PROTO_NOSERVICE 1
- #define GAI_PROTO_PROTOANY 2
-@@ -153,6 +160,15 @@
- .ai_next = NULL
- };
-
-+static void
-+gaih_result_reset (struct gaih_result *res)
-+{
-+ if (res->free_at)
-+ free (res->at);
-+ free (res->canon);
-+ free (res->h_name);
-+ memset (res, 0, sizeof (*res));
-+}
-
- static int
- gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
-@@ -180,28 +196,21 @@
- }
- while (r);
-
-- st->next = NULL;
- st->socktype = tp->socktype;
- st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
- ? req->ai_protocol : tp->protocol);
- st->port = s->s_port;
-+ st->set = true;
-
- return 0;
- }
-
--/* Convert struct hostent to a list of struct gaih_addrtuple objects.
-- h_name is not copied, and the struct hostent object must not be
-- deallocated prematurely. *RESULT must be NULL or a pointer to a
-- linked-list. The new addresses are appended at the end. */
-+/* Convert struct hostent to a list of struct gaih_addrtuple objects. The new
-+ addresses are appended to the tuple array in RES. */
- static bool
--convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
-- int family,
-- struct hostent *h,
-- struct gaih_addrtuple **result)
-+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
-+ struct hostent *h, struct gaih_result *res)
- {
-- while (*result)
-- result = &(*result)->next;
--
- /* Count the number of addresses in h->h_addr_list. */
- size_t count = 0;
- for (char **p = h->h_addr_list; *p != NULL; ++p)
-@@ -212,10 +221,41 @@
- if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
- return true;
-
-- struct gaih_addrtuple *array = calloc (count, sizeof (*array));
-+ struct gaih_addrtuple *array = res->at;
-+ size_t old = 0;
-+
-+ while (array != NULL)
-+ {
-+ old++;
-+ array = array->next;
-+ }
-+
-+ array = realloc (res->at, (old + count) * sizeof (*array));
-+
- if (array == NULL)
- return false;
-
-+ res->got_ipv6 = family == AF_INET6;
-+ res->at = array;
-+ res->free_at = true;
-+
-+ /* Duplicate h_name because it may get reclaimed when the underlying storage
-+ is freed. */
-+ if (res->h_name == NULL)
-+ {
-+ res->h_name = __strdup (h->h_name);
-+ if (res->h_name == NULL)
-+ return false;
-+ }
-+
-+ /* Update the next pointers on reallocation. */
-+ for (size_t i = 0; i < old; i++)
-+ array[i].next = array + i + 1;
-+
-+ array += old;
-+
-+ memset (array, 0, count * sizeof (*array));
-+
- for (size_t i = 0; i < count; ++i)
- {
- if (family == AF_INET && req->ai_family == AF_INET6)
-@@ -232,73 +272,59 @@
- }
- array[i].next = array + i + 1;
- }
-- array[0].name = h->h_name;
- array[count - 1].next = NULL;
-
-- *result = array;
- return true;
- }
-
--#define gethosts(_family) \
-- { \
-- struct hostent th; \
-- char *localcanon = NULL; \
-- no_data = 0; \
-- while (1) \
-- { \
-- status = DL_CALL_FCT (fct, (name, _family, &th, \
-- tmpbuf->data, tmpbuf->length, \
-- &errno, &h_errno, NULL, &localcanon)); \
-- if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
-- || errno != ERANGE) \
-- break; \
-- if (!scratch_buffer_grow (tmpbuf)) \
-- { \
-- __resolv_context_put (res_ctx); \
-- result = -EAI_MEMORY; \
-- goto free_and_return; \
-- } \
-- } \
-- if (status == NSS_STATUS_NOTFOUND \
-- || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
-- { \
-- if (h_errno == NETDB_INTERNAL) \
-- { \
-- __resolv_context_put (res_ctx); \
-- result = -EAI_SYSTEM; \
-- goto free_and_return; \
-- } \
-- if (h_errno == TRY_AGAIN) \
-- no_data = EAI_AGAIN; \
-- else \
-- no_data = h_errno == NO_DATA; \
-- } \
-- else if (status == NSS_STATUS_SUCCESS) \
-- { \
-- if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
-- { \
-- __resolv_context_put (res_ctx); \
-- result = -EAI_SYSTEM; \
-- goto free_and_return; \
-- } \
-- *pat = addrmem; \
-- \
-- if (localcanon != NULL && canon == NULL) \
-- { \
-- canonbuf = __strdup (localcanon); \
-- if (canonbuf == NULL) \
-- { \
-- __resolv_context_put (res_ctx); \
-- result = -EAI_SYSTEM; \
-- goto free_and_return; \
-- } \
-- canon = canonbuf; \
-- } \
-- if (_family == AF_INET6 && *pat != NULL) \
-- got_ipv6 = true; \
-- } \
-- }
-+static int
-+gethosts (nss_gethostbyname3_r fct, int family, const char *name,
-+ const struct addrinfo *req, struct scratch_buffer *tmpbuf,
-+ struct gaih_result *res, enum nss_status *statusp, int *no_datap)
-+{
-+ struct hostent th;
-+ char *localcanon = NULL;
-+ enum nss_status status;
-
-+ *no_datap = 0;
-+ while (1)
-+ {
-+ *statusp = status = DL_CALL_FCT (fct, (name, family, &th,
-+ tmpbuf->data, tmpbuf->length,
-+ &errno, &h_errno, NULL,
-+ &localcanon));
-+ if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL
-+ || errno != ERANGE)
-+ break;
-+ if (!scratch_buffer_grow (tmpbuf))
-+ return -EAI_MEMORY;
-+ }
-+ if (status == NSS_STATUS_NOTFOUND
-+ || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
-+ {
-+ if (h_errno == NETDB_INTERNAL)
-+ return -EAI_SYSTEM;
-+ if (h_errno == TRY_AGAIN)
-+ *no_datap = EAI_AGAIN;
-+ else
-+ *no_datap = h_errno == NO_DATA;
-+ }
-+ else if (status == NSS_STATUS_SUCCESS)
-+ {
-+ if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
-+ return -EAI_MEMORY;
-+
-+ if (localcanon != NULL && res->canon == NULL)
-+ {
-+ char *canonbuf = __strdup (localcanon);
-+ if (canonbuf == NULL)
-+ return -EAI_MEMORY;
-+ res->canon = canonbuf;
-+ }
-+ }
-+
-+ return 0;
-+}
-
- /* This function is called if a canonical name is requested, but if
- the service function did not provide it. It tries to obtain the
-@@ -307,15 +333,15 @@
- memory allocation failure. The returned string is allocated on the
- heap; the caller has to free it. */
- static char *
--getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
-+getcanonname (nss_action_list nip, const char *hname, const char *name)
- {
- nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
- char *s = (char *) name;
- if (cfct != NULL)
- {
- char buf[256];
-- if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
-- &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
-+ if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno,
-+ &h_errno)) != NSS_STATUS_SUCCESS)
- /* If the canonical name cannot be determined, use the passed
- string. */
- s = (char *) name;
-@@ -323,21 +349,47 @@
- return __strdup (name);
- }
-
-+/* Process looked up canonical name and if necessary, decode to IDNA. Result
-+ is a new string written to CANONP and the earlier string is freed. */
-+
- static int
--gaih_inet (const char *name, const struct gaih_service *service,
-- const struct addrinfo *req, struct addrinfo **pai,
-- unsigned int *naddrs, struct scratch_buffer *tmpbuf)
-+process_canonname (const struct addrinfo *req, const char *orig_name,
-+ struct gaih_result *res)
- {
-- const struct gaih_typeproto *tp = gaih_inet_typeproto;
-- struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
-- struct gaih_addrtuple *at = NULL;
-- bool got_ipv6 = false;
-- const char *canon = NULL;
-- const char *orig_name = name;
-+ char *canon = res->canon;
-
-- /* Reserve stack memory for the scratch buffer in the getaddrinfo
-- function. */
-- size_t alloca_used = sizeof (struct scratch_buffer);
-+ if ((req->ai_flags & AI_CANONNAME) != 0)
-+ {
-+ bool do_idn = req->ai_flags & AI_CANONIDN;
-+ if (do_idn)
-+ {
-+ char *out;
-+ int rc = __idna_from_dns_encoding (canon ?: orig_name, &out);
-+ if (rc == 0)
-+ {
-+ free (canon);
-+ canon = out;
-+ }
-+ else if (rc == EAI_IDN_ENCODE)
-+ /* Use the punycode name as a fallback. */
-+ do_idn = false;
-+ else
-+ return -rc;
-+ }
-+ if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL)
-+ return -EAI_MEMORY;
-+ }
-+
-+ res->canon = canon;
-+ return 0;
-+}
-+
-+static int
-+get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
-+ struct gaih_servtuple *st, struct scratch_buffer *tmpbuf)
-+{
-+ int i;
-+ const struct gaih_typeproto *tp = gaih_inet_typeproto;
-
- if (req->ai_protocol || req->ai_socktype)
- {
-@@ -359,747 +411,792 @@
- }
- }
-
-- int port = 0;
-- if (service != NULL)
-+ if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
-+ return -EAI_SERVICE;
-+
-+ if (service == NULL || service->num >= 0)
- {
-- if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
-- return -EAI_SERVICE;
-+ int port = service != NULL ? htons (service->num) : 0;
-
-- if (service->num < 0)
-+ if (req->ai_socktype || req->ai_protocol)
- {
-- if (tp->name[0])
-- {
-- st = (struct gaih_servtuple *)
-- alloca_account (sizeof (struct gaih_servtuple), alloca_used);
-+ st[0].socktype = tp->socktype;
-+ st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
-+ ? req->ai_protocol : tp->protocol);
-+ st[0].port = port;
-+ st[0].set = true;
-
-- int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
-- if (__glibc_unlikely (rc != 0))
-- return rc;
-- }
-- else
-- {
-- struct gaih_servtuple **pst = &st;
-- for (tp++; tp->name[0]; tp++)
-- {
-- struct gaih_servtuple *newp;
-+ return 0;
-+ }
-+
-+ /* Neither socket type nor protocol is set. Return all socket types
-+ we know about. */
-+ for (i = 0, ++tp; tp->name[0]; ++tp)
-+ if (tp->defaultflag)
-+ {
-+ st[i].socktype = tp->socktype;
-+ st[i].protocol = tp->protocol;
-+ st[i].port = port;
-+ st[i++].set = true;
-+ }
-
-- if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
-- continue;
-+ return 0;
-+ }
-
-- if (req->ai_socktype != 0
-- && req->ai_socktype != tp->socktype)
-- continue;
-- if (req->ai_protocol != 0
-- && !(tp->protoflag & GAI_PROTO_PROTOANY)
-- && req->ai_protocol != tp->protocol)
-- continue;
--
-- newp = (struct gaih_servtuple *)
-- alloca_account (sizeof (struct gaih_servtuple),
-- alloca_used);
--
-- if (gaih_inet_serv (service->name,
-- tp, req, newp, tmpbuf) != 0)
-- continue;
-+ if (tp->name[0])
-+ return gaih_inet_serv (service->name, tp, req, st, tmpbuf);
-
-- *pst = newp;
-- pst = &(newp->next);
-- }
-- if (st == (struct gaih_servtuple *) &nullserv)
-- return -EAI_SERVICE;
-- }
-- }
-- else
-+ for (i = 0, tp++; tp->name[0]; tp++)
-+ {
-+ if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
-+ continue;
-+
-+ if (req->ai_socktype != 0
-+ && req->ai_socktype != tp->socktype)
-+ continue;
-+ if (req->ai_protocol != 0
-+ && !(tp->protoflag & GAI_PROTO_PROTOANY)
-+ && req->ai_protocol != tp->protocol)
-+ continue;
-+
-+ if (gaih_inet_serv (service->name,
-+ tp, req, &st[i], tmpbuf) != 0)
-+ continue;
-+
-+ i++;
-+ }
-+
-+ if (!st[0].set)
-+ return -EAI_SERVICE;
-+
-+ return 0;
-+}
-+
-+#ifdef USE_NSCD
-+/* Query addresses from nscd cache, returning a non-zero value on error.
-+ RES members have the lookup result; RES->AT is NULL if there were no errors
-+ but also no results. */
-+
-+static int
-+get_nscd_addresses (const char *name, const struct addrinfo *req,
-+ struct gaih_result *res)
-+{
-+ if (__nss_not_use_nscd_hosts > 0
-+ && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
-+ __nss_not_use_nscd_hosts = 0;
-+
-+ res->at = NULL;
-+
-+ if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
-+ return 0;
-+
-+ /* Try to use nscd. */
-+ struct nscd_ai_result *air = NULL;
-+ int err = __nscd_getai (name, &air, &h_errno);
-+
-+ if (__glibc_unlikely (air == NULL))
-+ {
-+ /* The database contains a negative entry. */
-+ if (err == 0)
-+ return -EAI_NONAME;
-+ if (__nss_not_use_nscd_hosts == 0)
- {
-- port = htons (service->num);
-- goto got_port;
-+ if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
-+ return -EAI_MEMORY;
-+ if (h_errno == TRY_AGAIN)
-+ return -EAI_AGAIN;
-+ return -EAI_SYSTEM;
- }
-+ return 0;
- }
-- else
-+
-+ /* Transform into gaih_addrtuple list. */
-+ int result = 0;
-+ char *addrs = air->addrs;
-+
-+ struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree));
-+ struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
-+ if (at == NULL)
- {
-- got_port:
-+ result = -EAI_MEMORY;
-+ goto out;
-+ }
-
-- if (req->ai_socktype || req->ai_protocol)
-+ res->free_at = true;
-+
-+ int count = 0;
-+ for (int i = 0; i < air->naddrs; ++i)
-+ {
-+ socklen_t size = (air->family[i] == AF_INET
-+ ? INADDRSZ : IN6ADDRSZ);
-+
-+ if (!((air->family[i] == AF_INET
-+ && req->ai_family == AF_INET6
-+ && (req->ai_flags & AI_V4MAPPED) != 0)
-+ || req->ai_family == AF_UNSPEC
-+ || air->family[i] == req->ai_family))
- {
-- st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
-- st->next = NULL;
-- st->socktype = tp->socktype;
-- st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
-- ? req->ai_protocol : tp->protocol);
-- st->port = port;
-+ /* Skip over non-matching result. */
-+ addrs += size;
-+ continue;
- }
-- else
-+
-+ if (air->family[i] == AF_INET && req->ai_family == AF_INET6
-+ && (req->ai_flags & AI_V4MAPPED))
- {
-- /* Neither socket type nor protocol is set. Return all socket types
-- we know about. */
-- struct gaih_servtuple **lastp = &st;
-- for (++tp; tp->name[0]; ++tp)
-- if (tp->defaultflag)
-- {
-- struct gaih_servtuple *newp;
--
-- newp = alloca_account (sizeof (struct gaih_servtuple),
-- alloca_used);
-- newp->next = NULL;
-- newp->socktype = tp->socktype;
-- newp->protocol = tp->protocol;
-- newp->port = port;
--
-- *lastp = newp;
-- lastp = &newp->next;
-- }
-+ at[count].family = AF_INET6;
-+ at[count].addr[3] = *(uint32_t *) addrs;
-+ at[count].addr[2] = htonl (0xffff);
- }
-+ else if (req->ai_family == AF_UNSPEC
-+ || air->family[count] == req->ai_family)
-+ {
-+ at[count].family = air->family[count];
-+ memcpy (at[count].addr, addrs, size);
-+ if (air->family[count] == AF_INET6)
-+ res->got_ipv6 = true;
-+ }
-+ at[count].next = at + count + 1;
-+ count++;
-+ addrs += size;
- }
-
-- bool malloc_name = false;
-- struct gaih_addrtuple *addrmem = NULL;
-- char *canonbuf = NULL;
-+ if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL)
-+ {
-+ char *canonbuf = __strdup (air->canon);
-+ if (canonbuf == NULL)
-+ {
-+ result = -EAI_MEMORY;
-+ goto out;
-+ }
-+ res->canon = canonbuf;
-+ }
-+
-+ if (count == 0)
-+ {
-+ result = -EAI_NONAME;
-+ goto out;
-+ }
-+
-+ at[count - 1].next = NULL;
-+
-+ res->at = at;
-+
-+out:
-+ free (air);
-+ if (result != 0)
-+ {
-+ free (at);
-+ res->free_at = false;
-+ }
-+
-+ return result;
-+}
-+#endif
-+
-+static int
-+get_nss_addresses (const char *name, const struct addrinfo *req,
-+ struct scratch_buffer *tmpbuf, struct gaih_result *res)
-+{
-+ int no_data = 0;
-+ int no_inet6_data = 0;
-+ nss_action_list nip;
-+ enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
-+ enum nss_status status = NSS_STATUS_UNAVAIL;
-+ int no_more;
-+ struct resolv_context *res_ctx = NULL;
-+ bool do_merge = false;
- int result = 0;
-
-- if (name != NULL)
-+ no_more = !__nss_database_get (nss_database_hosts, &nip);
-+
-+ /* If we are looking for both IPv4 and IPv6 address we don't
-+ want the lookup functions to automatically promote IPv4
-+ addresses to IPv6 addresses, so we use the no_inet6
-+ function variant. */
-+ res_ctx = __resolv_context_get ();
-+ if (res_ctx == NULL)
-+ no_more = 1;
-+
-+ while (!no_more)
- {
-- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
-- at->family = AF_UNSPEC;
-- at->scopeid = 0;
-- at->next = NULL;
-+ /* Always start afresh; continue should discard previous results
-+ and the hosts database does not support merge. */
-+ gaih_result_reset (res);
-
-- if (req->ai_flags & AI_IDN)
-+ if (do_merge)
- {
-- char *out;
-- result = __idna_to_dns_encoding (name, &out);
-- if (result != 0)
-- return -result;
-- name = out;
-- malloc_name = true;
-+ __set_h_errno (NETDB_INTERNAL);
-+ __set_errno (EBUSY);
-+ break;
- }
-
-- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
-- {
-- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
-- at->family = AF_INET;
-- else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
-- {
-- at->addr[3] = at->addr[0];
-- at->addr[2] = htonl (0xffff);
-- at->addr[1] = 0;
-- at->addr[0] = 0;
-- at->family = AF_INET6;
-- }
-- else
-- {
-- result = -EAI_ADDRFAMILY;
-- goto free_and_return;
-- }
-+ no_data = 0;
-+ nss_gethostbyname4_r *fct4 = NULL;
-
-- if (req->ai_flags & AI_CANONNAME)
-- canon = name;
-- }
-- else if (at->family == AF_UNSPEC)
-+ /* gethostbyname4_r sends out parallel A and AAAA queries and
-+ is thus only suitable for PF_UNSPEC. */
-+ if (req->ai_family == PF_UNSPEC)
-+ fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
-+
-+ if (fct4 != NULL)
- {
-- char *scope_delim = strchr (name, SCOPE_DELIMITER);
-- int e;
-- if (scope_delim == NULL)
-- e = inet_pton (AF_INET6, name, at->addr);
-- else
-- e = __inet_pton_length (AF_INET6, name, scope_delim - name,
-- at->addr);
-- if (e > 0)
-+ while (1)
- {
-- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
-- at->family = AF_INET6;
-- else if (req->ai_family == AF_INET
-- && IN6_IS_ADDR_V4MAPPED (at->addr))
-- {
-- at->addr[0] = at->addr[3];
-- at->family = AF_INET;
-- }
-- else
-+ status = DL_CALL_FCT (fct4, (name, &res->at,
-+ tmpbuf->data, tmpbuf->length,
-+ &errno, &h_errno,
-+ NULL));
-+ if (status == NSS_STATUS_SUCCESS)
-+ break;
-+ /* gethostbyname4_r may write into AT, so reset it. */
-+ res->at = NULL;
-+ if (status != NSS_STATUS_TRYAGAIN
-+ || errno != ERANGE || h_errno != NETDB_INTERNAL)
- {
-- result = -EAI_ADDRFAMILY;
-- goto free_and_return;
-+ if (h_errno == TRY_AGAIN)
-+ no_data = EAI_AGAIN;
-+ else
-+ no_data = h_errno == NO_DATA;
-+ break;
- }
-
-- if (scope_delim != NULL
-- && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
-- scope_delim + 1,
-- &at->scopeid) != 0)
-+ if (!scratch_buffer_grow (tmpbuf))
- {
-- result = -EAI_NONAME;
-- goto free_and_return;
-+ __resolv_context_put (res_ctx);
-+ result = -EAI_MEMORY;
-+ goto out;
- }
--
-- if (req->ai_flags & AI_CANONNAME)
-- canon = name;
- }
-- }
-
-- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
-- {
-- struct gaih_addrtuple **pat = &at;
-- int no_data = 0;
-- int no_inet6_data = 0;
-- nss_action_list nip;
-- enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
-- enum nss_status status = NSS_STATUS_UNAVAIL;
-- int no_more;
-- struct resolv_context *res_ctx = NULL;
--
-- /* If we do not have to look for IPv6 addresses or the canonical
-- name, use the simple, old functions, which do not support
-- IPv6 scope ids, nor retrieving the canonical name. */
-- if (req->ai_family == AF_INET
-- && (req->ai_flags & AI_CANONNAME) == 0)
-+ if (status == NSS_STATUS_SUCCESS)
- {
-- int rc;
-- struct hostent th;
-- struct hostent *h;
-+ assert (!no_data);
-+ no_data = 1;
-
-- while (1)
-+ if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL)
- {
-- rc = __gethostbyname2_r (name, AF_INET, &th,
-- tmpbuf->data, tmpbuf->length,
-- &h, &h_errno);
-- if (rc != ERANGE || h_errno != NETDB_INTERNAL)
-- break;
-- if (!scratch_buffer_grow (tmpbuf))
-+ char *canonbuf = __strdup (res->at->name);
-+ if (canonbuf == NULL)
- {
-+ __resolv_context_put (res_ctx);
- result = -EAI_MEMORY;
-- goto free_and_return;
-+ goto out;
- }
-+ res->canon = canonbuf;
- }
-
-- if (rc == 0)
-+ struct gaih_addrtuple **pat = &res->at;
-+
-+ while (*pat != NULL)
- {
-- if (h != NULL)
-+ if ((*pat)->family == AF_INET
-+ && req->ai_family == AF_INET6
-+ && (req->ai_flags & AI_V4MAPPED) != 0)
- {
-- /* We found data, convert it. */
-- if (!convert_hostent_to_gaih_addrtuple
-- (req, AF_INET, h, &addrmem))
-- {
-- result = -EAI_MEMORY;
-- goto free_and_return;
-- }
-- *pat = addrmem;
-+ uint32_t *pataddr = (*pat)->addr;
-+ (*pat)->family = AF_INET6;
-+ pataddr[3] = pataddr[0];
-+ pataddr[2] = htonl (0xffff);
-+ pataddr[1] = 0;
-+ pataddr[0] = 0;
-+ pat = &((*pat)->next);
-+ no_data = 0;
- }
-- else
-+ else if (req->ai_family == AF_UNSPEC
-+ || (*pat)->family == req->ai_family)
- {
-- if (h_errno == NO_DATA)
-- result = -EAI_NODATA;
-- else
-- result = -EAI_NONAME;
-- goto free_and_return;
-+ pat = &((*pat)->next);
-+
-+ no_data = 0;
-+ if (req->ai_family == AF_INET6)
-+ res->got_ipv6 = true;
- }
-- }
-- else
-- {
-- if (h_errno == NETDB_INTERNAL)
-- result = -EAI_SYSTEM;
-- else if (h_errno == TRY_AGAIN)
-- result = -EAI_AGAIN;
- else
-- /* We made requests but they turned out no data.
-- The name is known, though. */
-- result = -EAI_NODATA;
--
-- goto free_and_return;
-+ *pat = ((*pat)->next);
- }
--
-- goto process_list;
- }
-
--#ifdef USE_NSCD
-- if (__nss_not_use_nscd_hosts > 0
-- && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
-- __nss_not_use_nscd_hosts = 0;
-+ no_inet6_data = no_data;
-+ }
-+ else
-+ {
-+ nss_gethostbyname3_r *fct = NULL;
-+ if (req->ai_flags & AI_CANONNAME)
-+ /* No need to use this function if we do not look for
-+ the canonical name. The function does not exist in
-+ all NSS modules and therefore the lookup would
-+ often fail. */
-+ fct = __nss_lookup_function (nip, "gethostbyname3_r");
-+ if (fct == NULL)
-+ /* We are cheating here. The gethostbyname2_r
-+ function does not have the same interface as
-+ gethostbyname3_r but the extra arguments the
-+ latter takes are added at the end. So the
-+ gethostbyname2_r code will just ignore them. */
-+ fct = __nss_lookup_function (nip, "gethostbyname2_r");
-
-- if (!__nss_not_use_nscd_hosts
-- && !__nss_database_custom[NSS_DBSIDX_hosts])
-+ if (fct != NULL)
- {
-- /* Try to use nscd. */
-- struct nscd_ai_result *air = NULL;
-- int err = __nscd_getai (name, &air, &h_errno);
-- if (air != NULL)
-+ if (req->ai_family == AF_INET6
-+ || req->ai_family == AF_UNSPEC)
- {
-- /* Transform into gaih_addrtuple list. */
-- bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
-- char *addrs = air->addrs;
--
-- addrmem = calloc (air->naddrs, sizeof (*addrmem));
-- if (addrmem == NULL)
-+ if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf,
-+ res, &status, &no_data)) != 0)
- {
-- result = -EAI_MEMORY;
-- goto free_and_return;
-+ __resolv_context_put (res_ctx);
-+ goto out;
- }
--
-- struct gaih_addrtuple *addrfree = addrmem;
-- for (int i = 0; i < air->naddrs; ++i)
-+ no_inet6_data = no_data;
-+ inet6_status = status;
-+ }
-+ if (req->ai_family == AF_INET
-+ || req->ai_family == AF_UNSPEC
-+ || (req->ai_family == AF_INET6
-+ && (req->ai_flags & AI_V4MAPPED)
-+ /* Avoid generating the mapped addresses if we
-+ know we are not going to need them. */
-+ && ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
-+ {
-+ if ((result = gethosts (fct, AF_INET, name, req, tmpbuf,
-+ res, &status, &no_data)) != 0)
- {
-- socklen_t size = (air->family[i] == AF_INET
-- ? INADDRSZ : IN6ADDRSZ);
--
-- if (!((air->family[i] == AF_INET
-- && req->ai_family == AF_INET6
-- && (req->ai_flags & AI_V4MAPPED) != 0)
-- || req->ai_family == AF_UNSPEC
-- || air->family[i] == req->ai_family))
-- {
-- /* Skip over non-matching result. */
-- addrs += size;
-- continue;
-- }
--
-- if (*pat == NULL)
-- {
-- *pat = addrfree++;
-- (*pat)->scopeid = 0;
-- }
-- uint32_t *pataddr = (*pat)->addr;
-- (*pat)->next = NULL;
-- if (added_canon || air->canon == NULL)
-- (*pat)->name = NULL;
-- else if (canonbuf == NULL)
-- {
-- canonbuf = __strdup (air->canon);
-- if (canonbuf == NULL)
-- {
-- result = -EAI_MEMORY;
-- goto free_and_return;
-- }
-- canon = (*pat)->name = canonbuf;
-- }
--
-- if (air->family[i] == AF_INET
-- && req->ai_family == AF_INET6
-- && (req->ai_flags & AI_V4MAPPED))
-- {
-- (*pat)->family = AF_INET6;
-- pataddr[3] = *(uint32_t *) addrs;
-- pataddr[2] = htonl (0xffff);
-- pataddr[1] = 0;
-- pataddr[0] = 0;
-- pat = &((*pat)->next);
-- added_canon = true;
-- }
-- else if (req->ai_family == AF_UNSPEC
-- || air->family[i] == req->ai_family)
-- {
-- (*pat)->family = air->family[i];
-- memcpy (pataddr, addrs, size);
-- pat = &((*pat)->next);
-- added_canon = true;
-- if (air->family[i] == AF_INET6)
-- got_ipv6 = true;
-- }
-- addrs += size;
-+ __resolv_context_put (res_ctx);
-+ goto out;
- }
-
-- free (air);
--
-- if (at->family == AF_UNSPEC)
-+ if (req->ai_family == AF_INET)
- {
-- result = -EAI_NONAME;
-- goto free_and_return;
-+ no_inet6_data = no_data;
-+ inet6_status = status;
- }
--
-- goto process_list;
- }
-- else if (err == 0)
-- /* The database contains a negative entry. */
-- goto free_and_return;
-- else if (__nss_not_use_nscd_hosts == 0)
-- {
-- if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
-- result = -EAI_MEMORY;
-- else if (h_errno == TRY_AGAIN)
-- result = -EAI_AGAIN;
-- else
-- result = -EAI_SYSTEM;
--
-- goto free_and_return;
-- }
-- }
--#endif
--
-- no_more = !__nss_database_get (nss_database_hosts, &nip);
--
-- /* If we are looking for both IPv4 and IPv6 address we don't
-- want the lookup functions to automatically promote IPv4
-- addresses to IPv6 addresses, so we use the no_inet6
-- function variant. */
-- res_ctx = __resolv_context_get ();
-- if (res_ctx == NULL)
-- no_more = 1;
--
-- while (!no_more)
-- {
-- no_data = 0;
-- nss_gethostbyname4_r *fct4 = NULL;
--
-- /* gethostbyname4_r sends out parallel A and AAAA queries and
-- is thus only suitable for PF_UNSPEC. */
-- if (req->ai_family == PF_UNSPEC)
-- fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
-
-- if (fct4 != NULL)
-+ /* If we found one address for AF_INET or AF_INET6,
-+ don't continue the search. */
-+ if (inet6_status == NSS_STATUS_SUCCESS
-+ || status == NSS_STATUS_SUCCESS)
- {
-- while (1)
-+ if ((req->ai_flags & AI_CANONNAME) != 0
-+ && res->canon == NULL)
- {
-- status = DL_CALL_FCT (fct4, (name, pat,
-- tmpbuf->data, tmpbuf->length,
-- &errno, &h_errno,
-- NULL));
-- if (status == NSS_STATUS_SUCCESS)
-- break;
-- if (status != NSS_STATUS_TRYAGAIN
-- || errno != ERANGE || h_errno != NETDB_INTERNAL)
-- {
-- if (h_errno == TRY_AGAIN)
-- no_data = EAI_AGAIN;
-- else
-- no_data = h_errno == NO_DATA;
-- break;
-- }
--
-- if (!scratch_buffer_grow (tmpbuf))
-+ char *canonbuf = getcanonname (nip, res->h_name, name);
-+ if (canonbuf == NULL)
- {
- __resolv_context_put (res_ctx);
- result = -EAI_MEMORY;
-- goto free_and_return;
-+ goto out;
- }
-+ res->canon = canonbuf;
- }
-+ status = NSS_STATUS_SUCCESS;
-+ }
-+ else
-+ {
-+ /* We can have different states for AF_INET and
-+ AF_INET6. Try to find a useful one for both. */
-+ if (inet6_status == NSS_STATUS_TRYAGAIN)
-+ status = NSS_STATUS_TRYAGAIN;
-+ else if (status == NSS_STATUS_UNAVAIL
-+ && inet6_status != NSS_STATUS_UNAVAIL)
-+ status = inet6_status;
-+ }
-+ }
-+ else
-+ {
-+ /* Could not locate any of the lookup functions.
-+ The NSS lookup code does not consistently set
-+ errno, so we need to supply our own error
-+ code here. The root cause could either be a
-+ resource allocation failure, or a missing
-+ service function in the DSO (so it should not
-+ be listed in /etc/nsswitch.conf). Assume the
-+ former, and return EBUSY. */
-+ status = NSS_STATUS_UNAVAIL;
-+ __set_h_errno (NETDB_INTERNAL);
-+ __set_errno (EBUSY);
-+ }
-+ }
-
-- if (status == NSS_STATUS_SUCCESS)
-- {
-- assert (!no_data);
-- no_data = 1;
-+ if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
-+ break;
-
-- if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
-- canon = (*pat)->name;
-+ /* The hosts database does not support MERGE. */
-+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
-+ do_merge = true;
-+
-+ nip++;
-+ if (nip->module == NULL)
-+ no_more = -1;
-+ }
-
-- while (*pat != NULL)
-- {
-- if ((*pat)->family == AF_INET
-- && req->ai_family == AF_INET6
-- && (req->ai_flags & AI_V4MAPPED) != 0)
-- {
-- uint32_t *pataddr = (*pat)->addr;
-- (*pat)->family = AF_INET6;
-- pataddr[3] = pataddr[0];
-- pataddr[2] = htonl (0xffff);
-- pataddr[1] = 0;
-- pataddr[0] = 0;
-- pat = &((*pat)->next);
-- no_data = 0;
-- }
-- else if (req->ai_family == AF_UNSPEC
-- || (*pat)->family == req->ai_family)
-- {
-- pat = &((*pat)->next);
--
-- no_data = 0;
-- if (req->ai_family == AF_INET6)
-- got_ipv6 = true;
-- }
-- else
-- *pat = ((*pat)->next);
-- }
-- }
-+ __resolv_context_put (res_ctx);
-
-- no_inet6_data = no_data;
-- }
-- else
-- {
-- nss_gethostbyname3_r *fct = NULL;
-- if (req->ai_flags & AI_CANONNAME)
-- /* No need to use this function if we do not look for
-- the canonical name. The function does not exist in
-- all NSS modules and therefore the lookup would
-- often fail. */
-- fct = __nss_lookup_function (nip, "gethostbyname3_r");
-- if (fct == NULL)
-- /* We are cheating here. The gethostbyname2_r
-- function does not have the same interface as
-- gethostbyname3_r but the extra arguments the
-- latter takes are added at the end. So the
-- gethostbyname2_r code will just ignore them. */
-- fct = __nss_lookup_function (nip, "gethostbyname2_r");
-+ /* If we have a failure which sets errno, report it using
-+ EAI_SYSTEM. */
-+ if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
-+ && h_errno == NETDB_INTERNAL)
-+ {
-+ result = -EAI_SYSTEM;
-+ goto out;
-+ }
-
-- if (fct != NULL)
-- {
-- if (req->ai_family == AF_INET6
-- || req->ai_family == AF_UNSPEC)
-- {
-- gethosts (AF_INET6);
-- no_inet6_data = no_data;
-- inet6_status = status;
-- }
-- if (req->ai_family == AF_INET
-- || req->ai_family == AF_UNSPEC
-- || (req->ai_family == AF_INET6
-- && (req->ai_flags & AI_V4MAPPED)
-- /* Avoid generating the mapped addresses if we
-- know we are not going to need them. */
-- && ((req->ai_flags & AI_ALL) || !got_ipv6)))
-- {
-- gethosts (AF_INET);
-+ if (no_data != 0 && no_inet6_data != 0)
-+ {
-+ /* If both requests timed out report this. */
-+ if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
-+ result = -EAI_AGAIN;
-+ else
-+ /* We made requests but they turned out no data. The name
-+ is known, though. */
-+ result = -EAI_NODATA;
-+ }
-
-- if (req->ai_family == AF_INET)
-- {
-- no_inet6_data = no_data;
-- inet6_status = status;
-- }
-- }
-+out:
-+ if (result != 0)
-+ gaih_result_reset (res);
-+ return result;
-+}
-
-- /* If we found one address for AF_INET or AF_INET6,
-- don't continue the search. */
-- if (inet6_status == NSS_STATUS_SUCCESS
-- || status == NSS_STATUS_SUCCESS)
-- {
-- if ((req->ai_flags & AI_CANONNAME) != 0
-- && canon == NULL)
-- {
-- canonbuf = getcanonname (nip, at, name);
-- if (canonbuf == NULL)
-- {
-- __resolv_context_put (res_ctx);
-- result = -EAI_MEMORY;
-- goto free_and_return;
-- }
-- canon = canonbuf;
-- }
-- status = NSS_STATUS_SUCCESS;
-- }
-- else
-- {
-- /* We can have different states for AF_INET and
-- AF_INET6. Try to find a useful one for both. */
-- if (inet6_status == NSS_STATUS_TRYAGAIN)
-- status = NSS_STATUS_TRYAGAIN;
-- else if (status == NSS_STATUS_UNAVAIL
-- && inet6_status != NSS_STATUS_UNAVAIL)
-- status = inet6_status;
-- }
-- }
-- else
-- {
-- /* Could not locate any of the lookup functions.
-- The NSS lookup code does not consistently set
-- errno, so we need to supply our own error
-- code here. The root cause could either be a
-- resource allocation failure, or a missing
-- service function in the DSO (so it should not
-- be listed in /etc/nsswitch.conf). Assume the
-- former, and return EBUSY. */
-- status = NSS_STATUS_UNAVAIL;
-- __set_h_errno (NETDB_INTERNAL);
-- __set_errno (EBUSY);
-- }
-- }
-+/* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
-+ NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
-+ the function cannot determine a result, RES->AT is set to NULL and 0
-+ returned. */
-
-- if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
-- break;
-+static int
-+text_to_binary_address (const char *name, const struct addrinfo *req,
-+ struct gaih_result *res)
-+{
-+ struct gaih_addrtuple *at = res->at;
-+ int result = 0;
-
-- nip++;
-- if (nip->module == NULL)
-- no_more = -1;
-- }
-+ assert (at != NULL);
-
-- __resolv_context_put (res_ctx);
-+ memset (at->addr, 0, sizeof (at->addr));
-+ if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
-+ {
-+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
-+ at->family = AF_INET;
-+ else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
-+ {
-+ at->addr[3] = at->addr[0];
-+ at->addr[2] = htonl (0xffff);
-+ at->addr[1] = 0;
-+ at->addr[0] = 0;
-+ at->family = AF_INET6;
-+ }
-+ else
-+ {
-+ result = -EAI_ADDRFAMILY;
-+ goto out;
-+ }
-
-- /* If we have a failure which sets errno, report it using
-- EAI_SYSTEM. */
-- if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
-- && h_errno == NETDB_INTERNAL)
-+ if (req->ai_flags & AI_CANONNAME)
-+ {
-+ char *canonbuf = __strdup (name);
-+ if (canonbuf == NULL)
- {
-- result = -EAI_SYSTEM;
-- goto free_and_return;
-+ result = -EAI_MEMORY;
-+ goto out;
- }
-+ res->canon = canonbuf;
-+ }
-+ return 0;
-+ }
-
-- if (no_data != 0 && no_inet6_data != 0)
-- {
-- /* If both requests timed out report this. */
-- if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
-- result = -EAI_AGAIN;
-- else
-- /* We made requests but they turned out no data. The name
-- is known, though. */
-- result = -EAI_NODATA;
-+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
-+ int e;
-
-- goto free_and_return;
-- }
-+ if (scope_delim == NULL)
-+ e = inet_pton (AF_INET6, name, at->addr);
-+ else
-+ e = __inet_pton_length (AF_INET6, name, scope_delim - name, at->addr);
-+
-+ if (e > 0)
-+ {
-+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
-+ at->family = AF_INET6;
-+ else if (req->ai_family == AF_INET
-+ && IN6_IS_ADDR_V4MAPPED (at->addr))
-+ {
-+ at->addr[0] = at->addr[3];
-+ at->family = AF_INET;
-+ }
-+ else
-+ {
-+ result = -EAI_ADDRFAMILY;
-+ goto out;
- }
-
-- process_list:
-- if (at->family == AF_UNSPEC)
-+ if (scope_delim != NULL
-+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
-+ scope_delim + 1, &at->scopeid) != 0)
- {
- result = -EAI_NONAME;
-- goto free_and_return;
-+ goto out;
- }
-+
-+ if (req->ai_flags & AI_CANONNAME)
-+ {
-+ char *canonbuf = __strdup (name);
-+ if (canonbuf == NULL)
-+ {
-+ result = -EAI_MEMORY;
-+ goto out;
-+ }
-+ res->canon = canonbuf;
-+ }
-+ return 0;
- }
-- else
-+
-+ if ((req->ai_flags & AI_NUMERICHOST))
-+ result = -EAI_NONAME;
-+
-+out:
-+ res->at = NULL;
-+ return result;
-+}
-+
-+/* If possible, call the simple, old functions, which do not support IPv6 scope
-+ ids, nor retrieving the canonical name. */
-+
-+static int
-+try_simple_gethostbyname (const char *name, const struct addrinfo *req,
-+ struct scratch_buffer *tmpbuf,
-+ struct gaih_result *res)
-+{
-+ res->at = NULL;
-+
-+ if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0)
-+ return 0;
-+
-+ int rc;
-+ struct hostent th;
-+ struct hostent *h;
-+
-+ while (1)
- {
-- struct gaih_addrtuple *atr;
-- atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
-- memset (at, '\0', sizeof (struct gaih_addrtuple));
-+ rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data,
-+ tmpbuf->length, &h, &h_errno);
-+ if (rc != ERANGE || h_errno != NETDB_INTERNAL)
-+ break;
-+ if (!scratch_buffer_grow (tmpbuf))
-+ return -EAI_MEMORY;
-+ }
-
-- if (req->ai_family == AF_UNSPEC)
-+ if (rc == 0)
-+ {
-+ if (h != NULL)
- {
-- at->next = __alloca (sizeof (struct gaih_addrtuple));
-- memset (at->next, '\0', sizeof (struct gaih_addrtuple));
-+ /* We found data, convert it. RES->AT from the conversion will
-+ either be an allocated block or NULL, both of which are safe to
-+ pass to free (). */
-+ if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res))
-+ return -EAI_MEMORY;
-+
-+ res->free_at = true;
-+ return 0;
- }
-+ if (h_errno == NO_DATA)
-+ return -EAI_NODATA;
-
-- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
-+ return -EAI_NONAME;
-+ }
-+
-+ if (h_errno == NETDB_INTERNAL)
-+ return -EAI_SYSTEM;
-+ if (h_errno == TRY_AGAIN)
-+ return -EAI_AGAIN;
-+
-+ /* We made requests but they turned out no data.
-+ The name is known, though. */
-+ return -EAI_NODATA;
-+}
-+
-+/* Add local address information into RES. RES->AT is assumed to have enough
-+ space for two tuples and is zeroed out. */
-+
-+static void
-+get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
-+{
-+ struct gaih_addrtuple *atr = res->at;
-+ if (req->ai_family == AF_UNSPEC)
-+ res->at->next = res->at + 1;
-+
-+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
-+ {
-+ res->at->family = AF_INET6;
-+ if ((req->ai_flags & AI_PASSIVE) == 0)
-+ memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr));
-+ atr = res->at->next;
-+ }
-+
-+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
-+ {
-+ atr->family = AF_INET;
-+ if ((req->ai_flags & AI_PASSIVE) == 0)
-+ atr->addr[0] = htonl (INADDR_LOOPBACK);
-+ }
-+}
-+
-+/* Generate results in PAI and its count in NADDRS. Return 0 on success or an
-+ error code on failure. */
-+
-+static int
-+generate_addrinfo (const struct addrinfo *req, struct gaih_result *res,
-+ const struct gaih_servtuple *st, struct addrinfo **pai,
-+ unsigned int *naddrs)
-+{
-+ size_t socklen;
-+ sa_family_t family;
-+
-+ /* Buffer is the size of an unformatted IPv6 address in printable format. */
-+ for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next)
-+ {
-+ family = at->family;
-+ if (family == AF_INET6)
- {
-- at->family = AF_INET6;
-- if ((req->ai_flags & AI_PASSIVE) == 0)
-- memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
-- atr = at->next;
-+ socklen = sizeof (struct sockaddr_in6);
-+
-+ /* If we looked up IPv4 mapped address discard them here if
-+ the caller isn't interested in all address and we have
-+ found at least one IPv6 address. */
-+ if (res->got_ipv6
-+ && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
-+ && IN6_IS_ADDR_V4MAPPED (at->addr))
-+ continue;
- }
-+ else
-+ socklen = sizeof (struct sockaddr_in);
-
-- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
-+ for (int i = 0; st[i].set; i++)
- {
-- atr->family = AF_INET;
-- if ((req->ai_flags & AI_PASSIVE) == 0)
-- atr->addr[0] = htonl (INADDR_LOOPBACK);
-+ struct addrinfo *ai;
-+ ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
-+ if (ai == NULL)
-+ return -EAI_MEMORY;
-+
-+ ai->ai_flags = req->ai_flags;
-+ ai->ai_family = family;
-+ ai->ai_socktype = st[i].socktype;
-+ ai->ai_protocol = st[i].protocol;
-+ ai->ai_addrlen = socklen;
-+ ai->ai_addr = (void *) (ai + 1);
-+
-+ /* We only add the canonical name once. */
-+ ai->ai_canonname = res->canon;
-+ res->canon = NULL;
-+
-+#ifdef _HAVE_SA_LEN
-+ ai->ai_addr->sa_len = socklen;
-+#endif /* _HAVE_SA_LEN */
-+ ai->ai_addr->sa_family = family;
-+
-+ /* In case of an allocation error the list must be NULL
-+ terminated. */
-+ ai->ai_next = NULL;
-+
-+ if (family == AF_INET6)
-+ {
-+ struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr;
-+ sin6p->sin6_port = st[i].port;
-+ sin6p->sin6_flowinfo = 0;
-+ memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr));
-+ sin6p->sin6_scope_id = at->scopeid;
-+ }
-+ else
-+ {
-+ struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr;
-+ sinp->sin_port = st[i].port;
-+ memcpy (&sinp->sin_addr, at->addr, sizeof (struct in_addr));
-+ memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
-+ }
-+
-+ pai = &(ai->ai_next);
- }
-+
-+ ++*naddrs;
- }
-+ return 0;
-+}
-
-- {
-- struct gaih_servtuple *st2;
-- struct gaih_addrtuple *at2 = at;
-- size_t socklen;
-- sa_family_t family;
--
-- /*
-- buffer is the size of an unformatted IPv6 address in printable format.
-- */
-- while (at2 != NULL)
-- {
-- /* Only the first entry gets the canonical name. */
-- if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
-- {
-- if (canon == NULL)
-- /* If the canonical name cannot be determined, use
-- the passed in string. */
-- canon = orig_name;
--
-- bool do_idn = req->ai_flags & AI_CANONIDN;
-- if (do_idn)
-- {
-- char *out;
-- int rc = __idna_from_dns_encoding (canon, &out);
-- if (rc == 0)
-- canon = out;
-- else if (rc == EAI_IDN_ENCODE)
-- /* Use the punycode name as a fallback. */
-- do_idn = false;
-- else
-- {
-- result = -rc;
-- goto free_and_return;
-- }
-- }
-- if (!do_idn)
-- {
-- if (canonbuf != NULL)
-- /* We already allocated the string using malloc, but
-- the buffer is now owned by canon. */
-- canonbuf = NULL;
-- else
-- {
-- canon = __strdup (canon);
-- if (canon == NULL)
-- {
-- result = -EAI_MEMORY;
-- goto free_and_return;
-- }
-- }
-- }
-- }
-+static int
-+gaih_inet (const char *name, const struct gaih_service *service,
-+ const struct addrinfo *req, struct addrinfo **pai,
-+ unsigned int *naddrs, struct scratch_buffer *tmpbuf)
-+{
-+ struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
-+ / sizeof (struct gaih_typeproto)] = {0};
-
-- family = at2->family;
-- if (family == AF_INET6)
-- {
-- socklen = sizeof (struct sockaddr_in6);
-+ const char *orig_name = name;
-
-- /* If we looked up IPv4 mapped address discard them here if
-- the caller isn't interested in all address and we have
-- found at least one IPv6 address. */
-- if (got_ipv6
-- && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
-- && IN6_IS_ADDR_V4MAPPED (at2->addr))
-- goto ignore;
-- }
-- else
-- socklen = sizeof (struct sockaddr_in);
-+ int rc;
-+ if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
-+ return rc;
-
-- for (st2 = st; st2 != NULL; st2 = st2->next)
-- {
-- struct addrinfo *ai;
-- ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
-- if (ai == NULL)
-- {
-- free ((char *) canon);
-- result = -EAI_MEMORY;
-- goto free_and_return;
-- }
--
-- ai->ai_flags = req->ai_flags;
-- ai->ai_family = family;
-- ai->ai_socktype = st2->socktype;
-- ai->ai_protocol = st2->protocol;
-- ai->ai_addrlen = socklen;
-- ai->ai_addr = (void *) (ai + 1);
--
-- /* We only add the canonical name once. */
-- ai->ai_canonname = (char *) canon;
-- canon = NULL;
-+ bool malloc_name = false;
-+ struct gaih_addrtuple *addrmem = NULL;
-+ int result = 0;
-
--#ifdef _HAVE_SA_LEN
-- ai->ai_addr->sa_len = socklen;
--#endif /* _HAVE_SA_LEN */
-- ai->ai_addr->sa_family = family;
-+ struct gaih_result res = {0};
-+ struct gaih_addrtuple local_at[2] = {0};
-
-- /* In case of an allocation error the list must be NULL
-- terminated. */
-- ai->ai_next = NULL;
--
-- if (family == AF_INET6)
-- {
-- struct sockaddr_in6 *sin6p =
-- (struct sockaddr_in6 *) ai->ai_addr;
--
-- sin6p->sin6_port = st2->port;
-- sin6p->sin6_flowinfo = 0;
-- memcpy (&sin6p->sin6_addr,
-- at2->addr, sizeof (struct in6_addr));
-- sin6p->sin6_scope_id = at2->scopeid;
-- }
-- else
-- {
-- struct sockaddr_in *sinp =
-- (struct sockaddr_in *) ai->ai_addr;
-- sinp->sin_port = st2->port;
-- memcpy (&sinp->sin_addr,
-- at2->addr, sizeof (struct in_addr));
-- memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
-- }
-+ res.at = local_at;
-
-- pai = &(ai->ai_next);
-- }
-+ if (__glibc_unlikely (name == NULL))
-+ {
-+ get_local_addresses (req, &res);
-+ goto process_list;
-+ }
-+
-+ if (req->ai_flags & AI_IDN)
-+ {
-+ char *out;
-+ result = __idna_to_dns_encoding (name, &out);
-+ if (result != 0)
-+ return -result;
-+ name = out;
-+ malloc_name = true;
-+ }
-+
-+ if ((result = text_to_binary_address (name, req, &res)) != 0)
-+ goto free_and_return;
-+ else if (res.at != NULL)
-+ goto process_list;
-+
-+ if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
-+ goto free_and_return;
-+ else if (res.at != NULL)
-+ goto process_list;
-+
-+#ifdef USE_NSCD
-+ if ((result = get_nscd_addresses (name, req, &res)) != 0)
-+ goto free_and_return;
-+ else if (res.at != NULL)
-+ goto process_list;
-+#endif
-
-- ++*naddrs;
-+ if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
-+ goto free_and_return;
-+ else if (res.at != NULL)
-+ goto process_list;
-+
-+ /* None of the lookups worked, so name not found. */
-+ result = -EAI_NONAME;
-+ goto free_and_return;
-+
-+process_list:
-+ /* Set up the canonical name if we need it. */
-+ if ((result = process_canonname (req, orig_name, &res)) != 0)
-+ goto free_and_return;
-
-- ignore:
-- at2 = at2->next;
-- }
-- }
-+ result = generate_addrinfo (req, &res, st, pai, naddrs);
-
-- free_and_return:
-+free_and_return:
- if (malloc_name)
- free ((char *) name);
- free (addrmem);
-- free (canonbuf);
-+ gaih_result_reset (&res);
-
- return result;
- }
diff --git a/SPECS/glibc/CVE-2023-4911.patch b/SPECS/glibc/CVE-2023-4911.patch
index f20443b6e42..98da4526b6d 100644
--- a/SPECS/glibc/CVE-2023-4911.patch
+++ b/SPECS/glibc/CVE-2023-4911.patch
@@ -1,29 +1,9 @@
-From 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa Mon Sep 17 00:00:00 2001
-From: Siddhesh Poyarekar
-Date: Tue, 19 Sep 2023 18:39:32 -0400
-Subject: [PATCH] tunables: Terminate if end of input is reached
- (CVE-2023-4911)
+backport of https://sourceware.org/git/?p=glibc.git;a=patch;h=1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa
-The string parsing routine may end up writing beyond bounds of tunestr
-if the input tunable string is malformed, of the form name=name=val.
-This gets processed twice, first as name=name=val and next as name=val,
-resulting in tunestr being name=name=val:name=val, thus overflowing
-tunestr.
-
-Terminate the parsing loop at the first instance itself so that tunestr
-does not overflow.
-
-This also fixes up tst-env-setuid-tunables to actually handle failures
-correct and add new tests to validate the fix for this CVE.
-
-Signed-off-by: Siddhesh Poyarekar
-Reviewed-by: Carlos O'Donell
-
-diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
-index 8e7ee9d..76cf8b9 100644
---- a/elf/dl-tunables.c
-+++ b/elf/dl-tunables.c
-@@ -187,11 +187,7 @@ parse_tunables (char *tunestr, char *valstring)
+diff -ru glibc-2.38-orig/elf/dl-tunables.c glibc-2.38/elf/dl-tunables.c
+--- glibc-2.38-orig/elf/dl-tunables.c 2024-06-17 21:53:23.756408666 +0000
++++ glibc-2.38/elf/dl-tunables.c 2024-06-17 23:01:00.207961672 +0000
+@@ -180,11 +180,7 @@
/* If we reach the end of the string before getting a valid name-value
pair, bail out. */
if (p[len] == '\0')
@@ -36,7 +16,7 @@ index 8e7ee9d..76cf8b9 100644
/* We did not find a valid name-value pair before encountering the
colon. */
-@@ -251,9 +247,16 @@ parse_tunables (char *tunestr, char *valstring)
+@@ -244,9 +240,16 @@
}
}
@@ -53,13 +33,12 @@ index 8e7ee9d..76cf8b9 100644
+ if (__libc_enable_secure)
+ tunestr[off] = '\0';
}
- #endif
-diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
-index 88182b7..0e77584 100644
---- a/elf/tst-env-setuid-tunables.c
-+++ b/elf/tst-env-setuid-tunables.c
-@@ -52,6 +52,8 @@ const char *teststrings[] =
+ /* Enable the glibc.malloc.check tunable in SETUID/SETGID programs only when
+diff -ru glibc-2.38-orig/elf/tst-env-setuid-tunables.c glibc-2.38/elf/tst-env-setuid-tunables.c
+--- glibc-2.38-orig/elf/tst-env-setuid-tunables.c 2024-06-17 21:53:23.808408845 +0000
++++ glibc-2.38/elf/tst-env-setuid-tunables.c 2024-06-17 23:26:01.648142768 +0000
+@@ -50,6 +50,8 @@
"glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
"glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
"not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
@@ -68,7 +47,7 @@ index 88182b7..0e77584 100644
"glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
"glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
":glibc.malloc.garbage=2:glibc.malloc.check=1",
-@@ -70,6 +72,8 @@ const char *resultstrings[] =
+@@ -68,6 +70,8 @@
"glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
"glibc.malloc.mmap_threshold=4096",
"glibc.malloc.mmap_threshold=4096",
@@ -77,10 +56,10 @@ index 88182b7..0e77584 100644
"",
"",
"",
-@@ -84,11 +88,18 @@ test_child (int off)
+@@ -81,11 +85,18 @@
+ {
const char *val = getenv ("GLIBC_TUNABLES");
- #if HAVE_TUNABLES
+ printf (" [%d] GLIBC_TUNABLES is %s\n", off, val);
+ fflush (stdout);
if (val != NULL && strcmp (val, resultstrings[off]) == 0)
@@ -96,39 +75,39 @@ index 88182b7..0e77584 100644
+ fflush (stdout);
return 1;
- #else
-@@ -118,30 +129,40 @@ do_test (int argc, char **argv)
+ }
+@@ -106,7 +117,9 @@
+ if (ret != 0)
exit (1);
- exit (EXIT_SUCCESS);
+- exit (EXIT_SUCCESS);
+ /* Special return code to make sure that the child executed all the way
+ through. */
+ exit (42);
}
else
{
-- int ret = 0;
--
- /* Spawn tests. */
- for (int i = 0; i < array_length (teststrings); i++)
+@@ -117,10 +130,15 @@
{
char buf[INT_BUFSIZE_BOUND (int)];
- printf ("Spawned test for %s (%d)\n", teststrings[i], i);
+- snprintf (buf, sizeof (buf), "%d\n", i);
+- if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
+- exit (1);
+ printf ("[%d] Spawned test for %s\n", i, teststrings[i]);
- snprintf (buf, sizeof (buf), "%d\n", i);
++ snprintf (buf, sizeof (buf), "%d\n", i);
+ fflush (stdout);
- if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
-- exit (1);
--
++ if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
+ {
+ printf (" [%d] Failed to set GLIBC_TUNABLES: %m", i);
+ support_record_failure ();
+ continue;
+ }
+
int status = support_capture_subprogram_self_sgid (buf);
- /* Bail out early if unsupported. */
+@@ -128,9 +146,14 @@
if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
return EXIT_UNSUPPORTED;
diff --git a/SPECS/glibc/CVE-2023-5156.patch b/SPECS/glibc/CVE-2023-5156.patch
index db562f4a42e..4a869922cf8 100644
--- a/SPECS/glibc/CVE-2023-5156.patch
+++ b/SPECS/glibc/CVE-2023-5156.patch
@@ -1,99 +1,16 @@
-From 17092c0311f954e6f3c010f73ce3a78c24ac279a Mon Sep 17 00:00:00 2001
-From: Romain Geissler
-Date: Mon, 25 Sep 2023 01:21:51 +0100
-Subject: [PATCH] Fix leak in getaddrinfo introduced by the fix for
- CVE-2023-4806 [BZ #30843]
+backport of https://sourceware.org/git?p=glibc.git;a=commit;h=17092c0311f954e6f3c010f73ce3a78c24ac279a
-This patch fixes a very recently added leak in getaddrinfo.
-
-This was assigned CVE-2023-5156.
-
-Resolves: BZ #30884
-Related: BZ #30842
-
-Reviewed-by: Siddhesh Poyarekar
-(cherry picked from commit ec6b95c3303c700eb89eebeda2d7264cc184a796)
----
- nss/Makefile | 20 ++++++++++++++++++++
- nss/tst-nss-gai-hv2-canonname.c | 3 +++
- sysdeps/posix/getaddrinfo.c | 4 +---
- 3 files changed, 24 insertions(+), 3 deletions(-)
-
-diff -ruN a/nss/Makefile b/nss/Makefile
---- a/nss/Makefile 2023-10-03 16:02:01.212592000 -0700
-+++ b/nss/Makefile 2023-10-03 18:03:01.994397600 -0700
-@@ -136,6 +136,15 @@
- extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
- nss_test_gai_hv2_canonname.os
-
-+ifeq ($(run-built-tests),yes)
-+ifneq (no,$(PERL))
-+tests-special += $(objpfx)mtrace-tst-nss-gai-hv2-canonname.out
-+endif
-+endif
-+
-+generated += mtrace-tst-nss-gai-hv2-canonname.out \
-+ tst-nss-gai-hv2-canonname.mtrace
-+
- include ../Rules
-
- ifeq (yes,$(have-selinux))
-@@ -198,6 +207,17 @@
- $(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
- $(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)/libnss_files.so
-
-+tst-nss-gai-hv2-canonname-ENV = \
-+ MALLOC_TRACE=$(objpfx)tst-nss-gai-hv2-canonname.mtrace \
-+ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
-+$(objpfx)mtrace-tst-nss-gai-hv2-canonname.out: \
-+ $(objpfx)tst-nss-gai-hv2-canonname.out
-+ { test -r $(objpfx)tst-nss-gai-hv2-canonname.mtrace \
-+ || ( echo "tst-nss-gai-hv2-canonname.mtrace does not exist"; exit 77; ) \
-+ && $(common-objpfx)malloc/mtrace \
-+ $(objpfx)tst-nss-gai-hv2-canonname.mtrace; } > $@; \
-+ $(evaluate-test)
-+
- # Disable DT_RUNPATH on NSS tests so that the glibc internal NSS
- # functions can load testing NSS modules via DT_RPATH.
- LDFLAGS-tst-nss-test1 = -Wl,--disable-new-dtags
---- a/nss/tst-nss-gai-hv2-canonname.c
-+++ b/nss/tst-nss-gai-hv2-canonname.c
-@@ -21,6 +21,7 @@
- #include
- #include
- #include
-+#include
- #include
- #include
- #include "nss/tst-nss-gai-hv2-canonname.h"
-@@ -41,6 +42,8 @@ static void do_prepare (int a, char **av)
- static int
- do_test (void)
- {
-+ mtrace ();
-+
- __nss_configure_lookup ("hosts", "test_gai_hv2_canonname");
-
- struct addrinfo hints = {};
-diff -ruN a/NEWS b/NEWS
---- a/NEWS 2022-02-02 21:27:54.000000000 -0800
-+++ b/NEWS 2023-10-03 20:04:28.294207226 -0700
-@@ -5,6 +5,18 @@
- Please send GNU C library bug reports via
- using `glibc' in the "product" field.
-
-+
-+Security related changes:
-+
-+ CVE-2023-4806: When an NSS plugin only implements the
-+ _gethostbyname2_r and _getcanonname_r callbacks, getaddrinfo could use
-+ memory that was freed during buffer resizing, potentially causing a
-+ crash or read or write to arbitrary memory.
-+
-+ CVE-2023-5156: The fix for CVE-2023-4806 introduced a memory leak when
-+ an application calls getaddrinfo for AF_INET6 with AI_CANONNAME,
-+ AI_ALL and AI_V4MAPPED flags set.
-+
- Version 2.35
+diff -ru glibc-2.38-orig/sysdeps/posix/getaddrinfo.c glibc-2.38/sysdeps/posix/getaddrinfo.c
+--- glibc-2.38-orig/sysdeps/posix/getaddrinfo.c 2024-06-17 21:53:25.432414431 +0000
++++ glibc-2.38/sysdeps/posix/getaddrinfo.c 2024-06-17 23:44:56.127284457 +0000
+@@ -1187,9 +1187,7 @@
+ if (malloc_name)
+ free ((char *) name);
+ free (addrmem);
+- if (res.free_at)
+- free (res.at);
+- free (res.canon);
++ gaih_result_reset (&res);
- Major new features:
+ return result;
+ }
diff --git a/SPECS/glibc/CVE-2023-6246-CVE-2023-6779-CVE-2023-6780.patch b/SPECS/glibc/CVE-2023-6246-CVE-2023-6779-CVE-2023-6780.patch
new file mode 100644
index 00000000000..41eed5cf391
--- /dev/null
+++ b/SPECS/glibc/CVE-2023-6246-CVE-2023-6779-CVE-2023-6780.patch
@@ -0,0 +1,158 @@
+Backport of the below commit
+CVE-2023-6246 -> https://sourceware.org/git?p=glibc.git;a=commit;h=6bd0e4efcc78f3c0115e5ea9739a1642807450da
+CVE-2023-6779 -> https://sourceware.org/git?p=glibc.git;a=commit;h=7e5a0c286da33159d47d0122007aac016f3e02cd
+CVE-2023-6780 -> https://sourceware.org/git?p=glibc.git;a=commit;h=ddf542da94caf97ff43cc2875c88749880b7259b
+
+
+diff -ru glibc-2.38-orig/misc/Makefile glibc-2.38/misc/Makefile
+--- glibc-2.38-orig/misc/Makefile 2024-06-17 21:53:24.532411335 +0000
++++ glibc-2.38/misc/Makefile 2024-06-17 21:57:25.721213362 +0000
+@@ -351,6 +351,9 @@
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
+ $(evaluate-test)
+
++tst-syslog-long-progname-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
++ LD_PRELOAD=libc_malloc_debug.so.0
++
+ $(objpfx)tst-select: $(librt)
+ $(objpfx)tst-select-time64: $(librt)
+ $(objpfx)tst-pselect: $(librt)
+diff -ru glibc-2.38-orig/misc/syslog.c glibc-2.38/misc/syslog.c
+--- glibc-2.38-orig/misc/syslog.c 2024-06-17 21:53:24.552411404 +0000
++++ glibc-2.38/misc/syslog.c 2024-06-17 22:39:50.400414890 +0000
+@@ -41,6 +41,7 @@
+ #include
+ #include
+ #include
++#include
+
+ static int LogType = SOCK_DGRAM; /* type of socket connection */
+ static int LogFile = -1; /* fd for log */
+@@ -124,8 +125,9 @@
+ {
+ /* Try to use a static buffer as an optimization. */
+ char bufs[1024];
+- char *buf = NULL;
+- size_t bufsize = 0;
++ char *buf = bufs;
++ size_t bufsize;
++
+ int msgoff;
+ int saved_errno = errno;
+
+@@ -177,29 +179,54 @@
+ #define SYSLOG_HEADER_WITHOUT_TS(__pri, __msgoff) \
+ "<%d>: %n", __pri, __msgoff
+
+- int l;
++ int l, vl;
+ if (has_ts)
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ else
+ l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+- if (0 <= l && l < sizeof bufs)
++ if (l < 0)
++ goto out;
++
++ char *pos;
++ size_t len;
++
++ if (l < sizeof bufs)
++ {
++ /* At this point, there is still a chance that we can print the
++ remaining part of the log into bufs and use that. */
++ pos = bufs + l;
++ len = sizeof (bufs) - l;
++ }
++ else
+ {
+- va_list apc;
+- va_copy (apc, ap);
++ buf = NULL;
++ /* We already know that bufs is too small to use for this log message.
++ The next vsnprintf into bufs is used only to calculate the total
++ required buffer length. We will discard bufs contents and allocate
++ an appropriately sized buffer later instead. */
++ pos = bufs;
++ len = sizeof (bufs);
++ }
+
+- /* Restore errno for %m format. */
+- __set_errno (saved_errno);
++ {
++ va_list apc;
++ va_copy (apc, ap);
+
+- int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
+- mode_flags);
+- if (0 <= vl && vl < sizeof bufs - l)
+- buf = bufs;
+- bufsize = l + vl;
++ /* Restore errno for %m format. */
++ __set_errno (saved_errno);
+
+- va_end (apc);
+- }
++ va_end (apc);
++
++ if (vl < 0 || vl >= INT_MAX - l)
++ goto out;
++
++ if (vl >= len)
++ buf = NULL;
++
++ bufsize = l + vl;
++ }
+
+ if (buf == NULL)
+ {
+@@ -209,25 +236,37 @@
+ /* Tell the cancellation handler to free this buffer. */
+ clarg.buf = buf;
+
++ int cl;
+ if (has_ts)
+- __snprintf (buf, l + 1,
+- SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
++ cl = __snprintf (buf, l + 1,
++ SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ else
+- __snprintf (buf, l + 1,
+- SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++ cl = __snprintf (buf, l + 1,
++ SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++ if (cl != l)
++ goto out;
+
+ va_list apc;
+ va_copy (apc, ap);
+- __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+- mode_flags);
+- va_end (apc);
++ cl = __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
++ mode_flags);
++ va_end (apc);
++
++ if (cl != vl)
++ goto out;
+ }
+ else
+ {
++ int bl;
+ /* Nothing much to do but emit an error message. */
+- bufsize = __snprintf (bufs, sizeof bufs,
+- "out of memory[%d]", __getpid ());
++ bl = __snprintf (bufs, sizeof bufs,
++ "out of memory[%d]", __getpid ());
++ if (bl < 0 || bl >= sizeof bufs)
++ goto out;
++
++ bufsize = bl;
+ buf = bufs;
++ msgoff = 0;
+ }
+ }
+
+Only in glibc-2.38/misc: tst-syslog-long-progname.c
diff --git a/SPECS/glibc/glibc.spec b/SPECS/glibc/glibc.spec
index 823566cfb8d..e015978e701 100644
--- a/SPECS/glibc/glibc.spec
+++ b/SPECS/glibc/glibc.spec
@@ -10,7 +10,7 @@
Summary: Main C library
Name: glibc
Version: 2.38
-Release: 5%{?dist}
+Release: 6%{?dist}
License: BSD AND GPLv2+ AND Inner-Net AND ISC AND LGPLv2+ AND MIT
Vendor: Microsoft Corporation
Distribution: Azure Linux
@@ -30,6 +30,10 @@ Patch3: CVE-2020-1751.nopatch
# Rationale: Exploit requires crafted pattern in regex compiler meant only for trusted content
Patch4: CVE-2018-20796.nopatch
Patch5: https://www.linuxfromscratch.org/patches/downloads/glibc/glibc-2.38-memalign_fix-1.patch
+Patch6: CVE-2023-4911.patch
+Patch7: CVE-2023-5156.patch
+Patch8: CVE-2023-6246-CVE-2023-6779-CVE-2023-6780.patch
+
BuildRequires: bison
BuildRequires: gawk
BuildRequires: gettext
@@ -348,6 +352,9 @@ grep "^FAIL: nptl/tst-eintr1" tests.sum >/dev/null && n=$((n+1)) ||:
%exclude %{_libdir}/locale/C.utf8
%changelog
+* Mon Jun 17 2024 Nicolas Guibourge - 2.38-6
+- Address CVE-2023-4911, CVE-2023-5156, CVE-2023-6246, CVE-2023-6779, CVE-2023-6780
+
* Wed May 22 2024 Suresh Babu Chalamalasetty - 2.38-5
- Generate and provide glibc all locales in a sub-package
diff --git a/SPECS/grub2/0001-Add-support-for-Linux-EFI-stub-loading.patch b/SPECS/grub2/0001-Add-support-for-Linux-EFI-stub-loading.patch
deleted file mode 100644
index 74044b8b2a0..00000000000
--- a/SPECS/grub2/0001-Add-support-for-Linux-EFI-stub-loading.patch
+++ /dev/null
@@ -1,983 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Matthew Garrett
-Date: Tue, 10 Jul 2012 11:58:52 -0400
-Subject: [PATCH] Add support for Linux EFI stub loading.
-
-Also:
-
-commit 71c843745f22f81e16d259e2e19c99bf3c1855c1
-Author: Colin Watson
-Date: Tue Oct 23 10:40:49 2012 -0400
-
-Don't allow insmod when secure boot is enabled.
-
-Hi,
-
-Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine
-as far as it goes. However, the insmod command is not the only way that
-modules can be loaded. In particular, the 'normal' command, which
-implements the usual GRUB menu and the fully-featured command prompt,
-will implicitly load commands not currently loaded into memory. This
-permits trivial Secure Boot violations by writing commands implementing
-whatever you want to do and pointing $prefix at the malicious code.
-
-I'm currently test-building this patch (replacing your current
-grub-2.00-no-insmod-on-sb.patch), but this should be more correct. It
-moves the check into grub_dl_load_file.
----
- grub-core/Makefile.core.def | 16 +-
- grub-core/kern/dl.c | 21 +++
- grub-core/kern/efi/efi.c | 28 ++++
- grub-core/kern/efi/mm.c | 32 ++++
- grub-core/loader/arm64/linux.c | 118 +++++++-------
- grub-core/loader/arm64/xen_boot.c | 1 -
- grub-core/loader/efi/linux.c | 70 ++++++++
- grub-core/loader/i386/efi/linux.c | 335 ++++++++++++++++++++++++++++++++++++++
- grub-core/loader/i386/pc/linux.c | 10 +-
- include/grub/arm/linux.h | 9 +
- include/grub/arm64/linux.h | 9 +
- include/grub/efi/efi.h | 7 +-
- include/grub/efi/linux.h | 31 ++++
- 13 files changed, 618 insertions(+), 69 deletions(-)
- create mode 100644 grub-core/loader/efi/linux.c
- create mode 100644 grub-core/loader/i386/efi/linux.c
- create mode 100644 include/grub/efi/linux.h
-
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
-index 8022e1c0a79..45d3edaa4dc 100644
---- a/grub-core/Makefile.core.def
-+++ b/grub-core/Makefile.core.def
-@@ -1734,13 +1734,6 @@ module = {
- enable = i386_pc;
- };
-
--
--module = {
-- name = linux16;
-- common = loader/i386/pc/linux.c;
-- enable = x86;
--};
--
- module = {
- name = ntldr;
- i386_pc = loader/i386/pc/ntldr.c;
-@@ -1796,7 +1789,9 @@ module = {
-
- module = {
- name = linux;
-- x86 = loader/i386/linux.c;
-+ i386_pc = loader/i386/pc/linux.c;
-+ x86_64_efi = loader/i386/efi/linux.c;
-+ i386_efi = loader/i386/efi/linux.c;
- i386_xen_pvh = loader/i386/linux.c;
- xen = loader/i386/xen.c;
- i386_pc = lib/i386/pc/vesa_modes_table.c;
-@@ -1811,9 +1806,14 @@ module = {
- arm64 = loader/arm64/linux.c;
- riscv32 = loader/riscv/linux.c;
- riscv64 = loader/riscv/linux.c;
-+ emu = loader/emu/linux.c;
-+ fdt = lib/fdt.c;
-+
- common = loader/linux.c;
- common = lib/cmdline.c;
- enable = noemu;
-+
-+ efi = loader/efi/linux.c;
- };
-
- module = {
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index 48f8a79073d..b7149370950 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -38,6 +38,14 @@
- #define GRUB_MODULES_MACHINE_READONLY
- #endif
-
-+#ifdef GRUB_MACHINE_EMU
-+#include
-+#endif
-+
-+#ifdef GRUB_MACHINE_EFI
-+#include
-+#endif
-+
-
-
- #pragma GCC diagnostic ignored "-Wcast-align"
-@@ -695,6 +703,19 @@ grub_dl_load_file (const char *filename)
- void *core = 0;
- grub_dl_t mod = 0;
-
-+#ifdef GRUB_MACHINE_EFI
-+ if (grub_efi_secure_boot ())
-+ {
-+#if 0
-+ /* This is an error, but grub2-mkconfig still generates a pile of
-+ * insmod commands, so emitting it would be mostly just obnoxious. */
-+ grub_error (GRUB_ERR_ACCESS_DENIED,
-+ "Secure Boot forbids loading module from %s", filename);
-+#endif
-+ return 0;
-+ }
-+#endif
-+
- grub_boot_time ("Loading module %s", filename);
-
- file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index 8cff7be0289..35b8f670602 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -286,6 +286,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
- return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL);
- }
-
-+grub_efi_boolean_t
-+grub_efi_secure_boot (void)
-+{
-+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
-+ grub_size_t datasize;
-+ char *secure_boot = NULL;
-+ char *setup_mode = NULL;
-+ grub_efi_boolean_t ret = 0;
-+
-+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
-+
-+ if (datasize != 1 || !secure_boot)
-+ goto out;
-+
-+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
-+
-+ if (datasize != 1 || !setup_mode)
-+ goto out;
-+
-+ if (*secure_boot && !*setup_mode)
-+ ret = 1;
-+
-+ out:
-+ grub_free (secure_boot);
-+ grub_free (setup_mode);
-+ return ret;
-+}
-+
- #pragma GCC diagnostic ignored "-Wcast-align"
-
- /* Search the mods section from the PE32/PE32+ image. This code uses
-diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
-index 0cdb063bb1b..74360542062 100644
---- a/grub-core/kern/efi/mm.c
-+++ b/grub-core/kern/efi/mm.c
-@@ -113,6 +113,38 @@ grub_efi_drop_alloc (grub_efi_physical_address_t address,
- }
- }
-
-+/* Allocate pages below a specified address */
-+void *
-+grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
-+ grub_efi_uintn_t pages)
-+{
-+ grub_efi_status_t status;
-+ grub_efi_boot_services_t *b;
-+ grub_efi_physical_address_t address = max;
-+
-+ if (max > 0xffffffff)
-+ return 0;
-+
-+ b = grub_efi_system_table->boot_services;
-+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
-+
-+ if (status != GRUB_EFI_SUCCESS)
-+ return 0;
-+
-+ if (address == 0)
-+ {
-+ /* Uggh, the address 0 was allocated... This is too annoying,
-+ so reallocate another one. */
-+ address = max;
-+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
-+ grub_efi_free_pages (0, pages);
-+ if (status != GRUB_EFI_SUCCESS)
-+ return 0;
-+ }
-+
-+ return (void *) ((grub_addr_t) address);
-+}
-+
- /* Allocate pages. Return the pointer to the first of allocated pages. */
- void *
- grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
-index ef3e9f9444c..a312c668685 100644
---- a/grub-core/loader/arm64/linux.c
-+++ b/grub-core/loader/arm64/linux.c
-@@ -29,6 +29,7 @@
- #include
- #include
- #include
-+#include
- #include
- #include
- #include
-@@ -41,6 +42,7 @@ static int loaded;
-
- static void *kernel_addr;
- static grub_uint64_t kernel_size;
-+static grub_uint32_t handover_offset;
-
- static char *linux_args;
- static grub_uint32_t cmdline_size;
-@@ -67,7 +69,8 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
- static grub_err_t
- finalize_params_linux (void)
- {
-- int node, retval;
-+ grub_efi_loaded_image_t *loaded_image = NULL;
-+ int node, retval, len;
-
- void *fdt;
-
-@@ -102,79 +105,70 @@ finalize_params_linux (void)
- if (grub_fdt_install() != GRUB_ERR_NONE)
- goto failure;
-
-- return GRUB_ERR_NONE;
--
--failure:
-- grub_fdt_unload();
-- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
--}
--
--grub_err_t
--grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
--{
-- grub_efi_memory_mapped_device_path_t *mempath;
-- grub_efi_handle_t image_handle;
-- grub_efi_boot_services_t *b;
-- grub_efi_status_t status;
-- grub_efi_loaded_image_t *loaded_image;
-- int len;
--
-- mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
-- if (!mempath)
-- return grub_errno;
--
-- mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
-- mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
-- mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
-- mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
-- mempath[0].start_address = addr;
-- mempath[0].end_address = addr + size;
--
-- mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-- mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-- mempath[1].header.length = sizeof (grub_efi_device_path_t);
--
-- b = grub_efi_system_table->boot_services;
-- status = b->load_image (0, grub_efi_image_handle,
-- (grub_efi_device_path_t *) mempath,
-- (void *) addr, size, &image_handle);
-- if (status != GRUB_EFI_SUCCESS)
-- return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
--
-- grub_dprintf ("linux", "linux command line: '%s'\n", args);
-+ grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
-+ fdt);
-
- /* Convert command line to UCS-2 */
-- loaded_image = grub_efi_get_loaded_image (image_handle);
-+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
-+ if (!loaded_image)
-+ goto failure;
-+
- loaded_image->load_options_size = len =
-- (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
-+ (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
- loaded_image->load_options =
- grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
- if (!loaded_image->load_options)
-- return grub_errno;
-+ return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
-
- loaded_image->load_options_size =
- 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
-- (grub_uint8_t *) args, len, NULL);
-+ (grub_uint8_t *) linux_args, len, NULL);
-
-- grub_dprintf ("linux", "starting image %p\n", image_handle);
-- status = b->start_image (image_handle, 0, NULL);
-+ return GRUB_ERR_NONE;
-
-- /* When successful, not reached */
-- b->unload_image (image_handle);
-- grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
-- GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
-+failure:
-+ grub_fdt_unload();
-+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
-+}
-
-- return grub_errno;
-+static void
-+free_params (void)
-+{
-+ grub_efi_loaded_image_t *loaded_image = NULL;
-+
-+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
-+ if (loaded_image)
-+ {
-+ if (loaded_image->load_options)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_efi_uintn_t)loaded_image->load_options,
-+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
-+ loaded_image->load_options = NULL;
-+ loaded_image->load_options_size = 0;
-+ }
-+}
-+
-+grub_err_t
-+grub_arch_efi_linux_boot_image (grub_addr_t addr, char *args)
-+{
-+ grub_err_t retval;
-+
-+ retval = finalize_params_linux ();
-+ if (retval != GRUB_ERR_NONE)
-+ return grub_errno;
-+
-+ grub_dprintf ("linux", "linux command line: '%s'\n", args);
-+
-+ retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
-+
-+ /* Never reached... */
-+ free_params();
-+ return retval;
- }
-
- static grub_err_t
- grub_linux_boot (void)
- {
-- if (finalize_params_linux () != GRUB_ERR_NONE)
-- return grub_errno;
--
-- return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
-- kernel_size, linux_args));
-+ return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, linux_args));
- }
-
- static grub_err_t
-@@ -288,6 +282,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- {
- grub_file_t file = 0;
- struct linux_arch_kernel_header lh;
-+ struct grub_armxx_linux_pe_header *pe;
- grub_err_t err;
-
- grub_dl_ref (my_mod);
-@@ -333,6 +328,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
-
-+ if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
-+ {
-+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
-+ goto fail;
-+ }
-+
-+ pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
-+ handover_offset = pe->opt.entry_addr;
-+
- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
- linux_args = grub_malloc (cmdline_size);
- if (!linux_args)
-diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
-index 22cc25eccd9..d9b7a9ba400 100644
---- a/grub-core/loader/arm64/xen_boot.c
-+++ b/grub-core/loader/arm64/xen_boot.c
-@@ -266,7 +266,6 @@ xen_boot (void)
- return err;
-
- return grub_arch_efi_linux_boot_image (xen_hypervisor->start,
-- xen_hypervisor->size,
- xen_hypervisor->cmdline);
- }
-
-diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
-new file mode 100644
-index 00000000000..c24202a5dd1
---- /dev/null
-+++ b/grub-core/loader/efi/linux.c
-@@ -0,0 +1,70 @@
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2014 Free Software Foundation, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#define SHIM_LOCK_GUID \
-+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
-+
-+struct grub_efi_shim_lock
-+{
-+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
-+};
-+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
-+
-+grub_efi_boolean_t
-+grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
-+{
-+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
-+ grub_efi_shim_lock_t *shim_lock;
-+
-+ shim_lock = grub_efi_locate_protocol(&guid, NULL);
-+
-+ if (!shim_lock)
-+ return 1;
-+
-+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wcast-align"
-+
-+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
-+
-+grub_err_t
-+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset,
-+ void *kernel_params)
-+{
-+ handover_func hf;
-+
-+ hf = (handover_func)((char *)kernel_addr + offset);
-+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
-+
-+ return GRUB_ERR_BUG;
-+}
-+
-+#pragma GCC diagnostic pop
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-new file mode 100644
-index 00000000000..bb2616a8092
---- /dev/null
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -0,0 +1,335 @@
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2012 Free Software Foundation, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+GRUB_MOD_LICENSE ("GPLv3+");
-+
-+static grub_dl_t my_mod;
-+static int loaded;
-+static void *kernel_mem;
-+static grub_uint64_t kernel_size;
-+static grub_uint8_t *initrd_mem;
-+static grub_uint32_t handover_offset;
-+struct linux_kernel_params *params;
-+static char *linux_cmdline;
-+
-+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
-+
-+static grub_err_t
-+grub_linuxefi_boot (void)
-+{
-+ int offset = 0;
-+
-+#ifdef __x86_64__
-+ offset = 512;
-+#endif
-+ asm volatile ("cli");
-+
-+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset,
-+ params);
-+}
-+
-+static grub_err_t
-+grub_linuxefi_unload (void)
-+{
-+ grub_dl_unref (my_mod);
-+ loaded = 0;
-+ if (initrd_mem)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem,
-+ BYTES_TO_PAGES(params->ramdisk_size));
-+ if (linux_cmdline)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)
-+ linux_cmdline,
-+ BYTES_TO_PAGES(params->cmdline_size + 1));
-+ if (kernel_mem)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem,
-+ BYTES_TO_PAGES(kernel_size));
-+ if (params)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params,
-+ BYTES_TO_PAGES(16384));
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-+ int argc, char *argv[])
-+{
-+ grub_file_t *files = 0;
-+ int i, nfiles = 0;
-+ grub_size_t size = 0;
-+ grub_uint8_t *ptr;
-+
-+ if (argc == 0)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
-+ goto fail;
-+ }
-+
-+ if (!loaded)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
-+ goto fail;
-+ }
-+
-+ files = grub_zalloc (argc * sizeof (files[0]));
-+ if (!files)
-+ goto fail;
-+
-+ for (i = 0; i < argc; i++)
-+ {
-+ files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD | GRUB_FILE_TYPE_NO_DECOMPRESS);
-+ if (! files[i])
-+ goto fail;
-+ nfiles++;
-+ size += ALIGN_UP (grub_file_size (files[i]), 4);
-+ }
-+
-+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
-+ if (!initrd_mem)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
-+ goto fail;
-+ }
-+
-+ params->ramdisk_size = size;
-+ params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem;
-+
-+ ptr = initrd_mem;
-+
-+ for (i = 0; i < nfiles; i++)
-+ {
-+ grub_ssize_t cursize = grub_file_size (files[i]);
-+ if (grub_file_read (files[i], ptr, cursize) != cursize)
-+ {
-+ if (!grub_errno)
-+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
-+ argv[i]);
-+ goto fail;
-+ }
-+ ptr += cursize;
-+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
-+ ptr += ALIGN_UP_OVERHEAD (cursize, 4);
-+ }
-+
-+ params->ramdisk_size = size;
-+
-+ fail:
-+ for (i = 0; i < nfiles; i++)
-+ grub_file_close (files[i]);
-+ grub_free (files);
-+
-+ if (initrd_mem && grub_errno)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem,
-+ BYTES_TO_PAGES(size));
-+
-+ return grub_errno;
-+}
-+
-+static grub_err_t
-+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-+ int argc, char *argv[])
-+{
-+ grub_file_t file = 0;
-+ struct linux_i386_kernel_header lh;
-+ grub_ssize_t len, start, filelen;
-+ void *kernel = NULL;
-+
-+ grub_dl_ref (my_mod);
-+
-+ if (argc == 0)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
-+ goto fail;
-+ }
-+
-+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
-+ if (! file)
-+ goto fail;
-+
-+ filelen = grub_file_size (file);
-+
-+ kernel = grub_malloc(filelen);
-+
-+ if (!kernel)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
-+ goto fail;
-+ }
-+
-+ if (grub_file_read (file, kernel, filelen) != filelen)
-+ {
-+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
-+ goto fail;
-+ }
-+
-+ if (! grub_linuxefi_secure_validate (kernel, filelen))
-+ {
-+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
-+ argv[0]);
-+ goto fail;
-+ }
-+
-+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
-+
-+ if (! params)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
-+ goto fail;
-+ }
-+
-+ grub_memset (params, 0, 16384);
-+
-+ grub_memcpy (&lh, kernel, sizeof (lh));
-+
-+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
-+ {
-+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
-+ goto fail;
-+ }
-+
-+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
-+ {
-+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
-+ goto fail;
-+ }
-+
-+ if (lh.version < grub_cpu_to_le16 (0x020b))
-+ {
-+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
-+ goto fail;
-+ }
-+
-+ if (!lh.handover_offset)
-+ {
-+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
-+ goto fail;
-+ }
-+
-+ grub_dprintf ("linux", "setting up cmdline\n");
-+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
-+ BYTES_TO_PAGES(lh.cmdline_size + 1));
-+
-+ if (!linux_cmdline)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
-+ goto fail;
-+ }
-+
-+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
-+ grub_create_loader_cmdline (argc, argv,
-+ linux_cmdline + sizeof (LINUX_IMAGE) - 1,
-+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1),
-+ GRUB_VERIFY_KERNEL_CMDLINE);
-+
-+ lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline;
-+
-+ handover_offset = lh.handover_offset;
-+
-+ start = (lh.setup_sects + 1) * 512;
-+ len = grub_file_size(file) - start;
-+
-+ kernel_mem = grub_efi_allocate_pages_max(lh.pref_address,
-+ BYTES_TO_PAGES(lh.init_size));
-+
-+ if (!kernel_mem)
-+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
-+ BYTES_TO_PAGES(lh.init_size));
-+
-+ if (!kernel_mem)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
-+ goto fail;
-+ }
-+
-+ grub_memcpy (kernel_mem, (char *)kernel + start, len);
-+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
-+ loaded=1;
-+
-+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
-+ grub_memcpy (params, &lh, 2 * 512);
-+
-+ params->type_of_loader = 0x21;
-+
-+ fail:
-+
-+ if (file)
-+ grub_file_close (file);
-+
-+ if (kernel)
-+ grub_free (kernel);
-+
-+ if (grub_errno != GRUB_ERR_NONE)
-+ {
-+ grub_dl_unref (my_mod);
-+ loaded = 0;
-+ }
-+
-+ if (linux_cmdline && !loaded)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)
-+ linux_cmdline,
-+ BYTES_TO_PAGES(lh.cmdline_size + 1));
-+
-+ if (kernel_mem && !loaded)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem,
-+ BYTES_TO_PAGES(kernel_size));
-+
-+ if (params && !loaded)
-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params,
-+ BYTES_TO_PAGES(16384));
-+
-+ return grub_errno;
-+}
-+
-+static grub_command_t cmd_linux, cmd_initrd;
-+static grub_command_t cmd_linuxefi, cmd_initrdefi;
-+
-+GRUB_MOD_INIT(linux)
-+{
-+ cmd_linux =
-+ grub_register_command ("linux", grub_cmd_linux,
-+ 0, N_("Load Linux."));
-+ cmd_linuxefi =
-+ grub_register_command ("linuxefi", grub_cmd_linux,
-+ 0, N_("Load Linux."));
-+ cmd_initrd =
-+ grub_register_command ("initrd", grub_cmd_initrd,
-+ 0, N_("Load initrd."));
-+ cmd_initrdefi =
-+ grub_register_command ("initrdefi", grub_cmd_initrd,
-+ 0, N_("Load initrd."));
-+ my_mod = mod;
-+}
-+
-+GRUB_MOD_FINI(linux)
-+{
-+ grub_unregister_command (cmd_linux);
-+ grub_unregister_command (cmd_linuxefi);
-+ grub_unregister_command (cmd_initrd);
-+ grub_unregister_command (cmd_initrdefi);
-+}
-diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
-index 2a299520160..8be4c3b3f48 100644
---- a/grub-core/loader/i386/pc/linux.c
-+++ b/grub-core/loader/i386/pc/linux.c
-@@ -474,14 +474,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
- return grub_errno;
- }
-
--static grub_command_t cmd_linux, cmd_initrd;
-+static grub_command_t cmd_linux, cmd_linux16, cmd_initrd, cmd_initrd16;
-
- GRUB_MOD_INIT(linux16)
- {
- cmd_linux =
-+ grub_register_command ("linux", grub_cmd_linux,
-+ 0, N_("Load Linux."));
-+ cmd_linux16 =
- grub_register_command ("linux16", grub_cmd_linux,
- 0, N_("Load Linux."));
- cmd_initrd =
-+ grub_register_command ("initrd", grub_cmd_initrd,
-+ 0, N_("Load initrd."));
-+ cmd_initrd16 =
- grub_register_command ("initrd16", grub_cmd_initrd,
- 0, N_("Load initrd."));
- my_mod = mod;
-@@ -490,5 +496,7 @@ GRUB_MOD_INIT(linux16)
- GRUB_MOD_FINI(linux16)
- {
- grub_unregister_command (cmd_linux);
-+ grub_unregister_command (cmd_linux16);
- grub_unregister_command (cmd_initrd);
-+ grub_unregister_command (cmd_initrd16);
- }
-diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
-index bcd5a7eb186..b582f67f661 100644
---- a/include/grub/arm/linux.h
-+++ b/include/grub/arm/linux.h
-@@ -20,6 +20,7 @@
- #ifndef GRUB_ARM_LINUX_HEADER
- #define GRUB_ARM_LINUX_HEADER 1
-
-+#include
- #include "system.h"
-
- #define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
-@@ -34,9 +35,17 @@ struct linux_arm_kernel_header {
- grub_uint32_t hdr_offset;
- };
-
-+struct grub_arm_linux_pe_header
-+{
-+ grub_uint32_t magic;
-+ struct grub_pe32_coff_header coff;
-+ struct grub_pe32_optional_header opt;
-+};
-+
- #if defined(__arm__)
- # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
- # define linux_arch_kernel_header linux_arm_kernel_header
-+# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
- #endif
-
- #if defined GRUB_MACHINE_UBOOT
-diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
-index 7e22b4ab699..ea030312df3 100644
---- a/include/grub/arm64/linux.h
-+++ b/include/grub/arm64/linux.h
-@@ -19,6 +19,7 @@
- #ifndef GRUB_ARM64_LINUX_HEADER
- #define GRUB_ARM64_LINUX_HEADER 1
-
-+#include
- #include
-
- #define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */
-@@ -38,9 +39,17 @@ struct linux_arm64_kernel_header
- grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
- };
-
-+struct grub_arm64_linux_pe_header
-+{
-+ grub_uint32_t magic;
-+ struct grub_pe32_coff_header coff;
-+ struct grub_pe64_optional_header opt;
-+};
-+
- #if defined(__aarch64__)
- # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
- # define linux_arch_kernel_header linux_arm64_kernel_header
-+# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
- #endif
-
- #endif /* ! GRUB_ARM64_LINUX_HEADER */
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
-index 83d958f9945..6295df85f3f 100644
---- a/include/grub/efi/efi.h
-+++ b/include/grub/efi/efi.h
-@@ -47,6 +47,9 @@ EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address,
- grub_efi_uintn_t pages);
- void *
- EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages);
-+void *
-+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max,
-+ grub_efi_uintn_t pages);
- void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
- grub_efi_uintn_t pages);
- grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void);
-@@ -88,6 +91,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var,
- const grub_efi_guid_t *guid,
- void *data,
- grub_size_t datasize);
-+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void);
- int
- EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
- const grub_efi_device_path_t *dp2);
-@@ -101,8 +105,7 @@ void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
- grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
- #include
- grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh);
--grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
-- char *args);
-+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args);
- #endif
-
- grub_addr_t grub_efi_modules_addr (void);
-diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
-new file mode 100644
-index 00000000000..d9ede36773b
---- /dev/null
-+++ b/include/grub/efi/linux.h
-@@ -0,0 +1,31 @@
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2014 Free Software Foundation, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+#ifndef GRUB_EFI_LINUX_HEADER
-+#define GRUB_EFI_LINUX_HEADER 1
-+
-+#include
-+#include
-+#include
-+
-+grub_efi_boolean_t
-+EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
-+grub_err_t
-+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
-+ void *kernel_param);
-+
-+#endif /* ! GRUB_EFI_LINUX_HEADER */
diff --git a/SPECS/grub2/0002-Rework-linux-command.patch b/SPECS/grub2/0002-Rework-linux-command.patch
deleted file mode 100644
index 9954dd0a61c..00000000000
--- a/SPECS/grub2/0002-Rework-linux-command.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Matthew Garrett
-Date: Sun, 9 Aug 2015 16:12:39 -0700
-Subject: [PATCH] Rework linux command
-
-We want a single buffer that contains the entire kernel image in order to
-perform a TPM measurement. Allocate one and copy the entire kernel into it
-before pulling out the individual blocks later on.
-
-Signed-off-by: Matthew Garrett
----
- grub-core/loader/i386/linux.c | 35 +++++++++++++++++++++++------------
- 1 file changed, 23 insertions(+), 12 deletions(-)
-
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
-index 9f74a96b19a..dccf3bb3005 100644
---- a/grub-core/loader/i386/linux.c
-+++ b/grub-core/loader/i386/linux.c
-@@ -649,13 +649,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- {
- grub_file_t file = 0;
- struct linux_i386_kernel_header lh;
-+ grub_uint8_t *linux_params_ptr;
- grub_uint8_t setup_sects;
-- grub_size_t real_size, prot_size, prot_file_size;
-+ grub_size_t real_size, prot_size, prot_file_size, kernel_offset;
- grub_ssize_t len;
- int i;
- grub_size_t align, min_align;
- int relocatable;
- grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR;
-+ grub_uint8_t *kernel = NULL;
-
- grub_dl_ref (my_mod);
-
-@@ -669,7 +671,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- if (! file)
- goto fail;
-
-- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
-+ len = grub_file_size (file);
-+ kernel = grub_malloc (len);
-+ if (!kernel)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
-+ goto fail;
-+ }
-+
-+ if (grub_file_read (file, kernel, len) != len)
- {
- if (!grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-@@ -677,6 +687,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- goto fail;
- }
-
-+ grub_memcpy (&lh, kernel, sizeof (lh));
-+ kernel_offset = sizeof (lh);
-+
- if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
- {
- grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
-@@ -784,13 +797,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- /* We've already read lh so there is no need to read it second time. */
- len -= sizeof(lh);
-
-- if ((len > 0) &&
-- (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len))
-+ linux_params_ptr = (void *)&linux_params;
-+ if (len > 0)
- {
-- if (!grub_errno)
-- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-- argv[0]);
-- goto fail;
-+ grub_memcpy (linux_params_ptr + sizeof (lh), kernel + kernel_offset, len);
-+ kernel_offset += len;
- }
-
- linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
-@@ -853,7 +864,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- /* The other parameters are filled when booting. */
-
-- grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
-+ kernel_offset = real_size + GRUB_DISK_SECTOR_SIZE;
-
- grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
- (unsigned) real_size, (unsigned) prot_size);
-@@ -1007,9 +1018,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- }
-
- len = prot_file_size;
-- if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
-- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-- argv[0]);
-+ grub_memcpy (prot_mode_mem, kernel + kernel_offset, len);
-
- if (grub_errno == GRUB_ERR_NONE)
- {
-@@ -1020,6 +1029,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- fail:
-
-+ grub_free (kernel);
-+
- if (file)
- grub_file_close (file);
-
diff --git a/SPECS/grub2/0003-Rework-linux16-command.patch b/SPECS/grub2/0003-Rework-linux16-command.patch
deleted file mode 100644
index 2c2d6f0ba6c..00000000000
--- a/SPECS/grub2/0003-Rework-linux16-command.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Matthew Garrett
-Date: Sun, 9 Aug 2015 16:20:58 -0700
-Subject: [PATCH] Rework linux16 command
-
-We want a single buffer that contains the entire kernel image in order to
-perform a TPM measurement. Allocate one and copy the entire kernel int it
-before pulling out the individual blocks later on.
-
-Signed-off-by: Matthew Garrett
----
- grub-core/loader/i386/pc/linux.c | 33 +++++++++++++++++++++------------
- 1 file changed, 21 insertions(+), 12 deletions(-)
-
-diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
-index 8be4c3b3f48..4b1750e360e 100644
---- a/grub-core/loader/i386/pc/linux.c
-+++ b/grub-core/loader/i386/pc/linux.c
-@@ -124,13 +124,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- grub_file_t file = 0;
- struct linux_i386_kernel_header lh;
- grub_uint8_t setup_sects;
-- grub_size_t real_size;
-+ grub_size_t real_size, kernel_offset = 0;
- grub_ssize_t len;
- int i;
- char *grub_linux_prot_chunk;
- int grub_linux_is_bzimage;
- grub_addr_t grub_linux_prot_target;
- grub_err_t err;
-+ grub_uint8_t *kernel = NULL;
-
- grub_dl_ref (my_mod);
-
-@@ -144,7 +145,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- if (! file)
- goto fail;
-
-- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
-+ len = grub_file_size (file);
-+ kernel = grub_malloc (len);
-+ if (!kernel)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
-+ goto fail;
-+ }
-+
-+ if (grub_file_read (file, kernel, len) != len)
- {
- if (!grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-@@ -152,6 +161,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- goto fail;
- }
-
-+ grub_memcpy (&lh, kernel, sizeof (lh));
-+ kernel_offset = sizeof (lh);
-+
- if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
- {
- grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
-@@ -320,13 +332,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh));
-
- len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
-- if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len)
-- {
-- if (!grub_errno)
-- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-- argv[0]);
-- goto fail;
-- }
-+ grub_memcpy (grub_linux_real_chunk + sizeof (lh), kernel + kernel_offset,
-+ len);
-+ kernel_offset += len;
-
- if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE)
- || grub_le_to_cpu16 (lh.version) < 0x0200)
-@@ -364,9 +372,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- }
-
- len = grub_linux16_prot_size;
-- if (grub_file_read (file, grub_linux_prot_chunk, len) != len && !grub_errno)
-- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-- argv[0]);
-+ grub_memcpy (grub_linux_prot_chunk, kernel + kernel_offset, len);
-+ kernel_offset += len;
-
- if (grub_errno == GRUB_ERR_NONE)
- {
-@@ -376,6 +383,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- fail:
-
-+ grub_free (kernel);
-+
- if (file)
- grub_file_close (file);
-
diff --git a/SPECS/grub2/0004-Add-secureboot-support-on-efi-chainloader.patch b/SPECS/grub2/0004-Add-secureboot-support-on-efi-chainloader.patch
deleted file mode 100644
index bfb5a9b6770..00000000000
--- a/SPECS/grub2/0004-Add-secureboot-support-on-efi-chainloader.patch
+++ /dev/null
@@ -1,1382 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Raymund Will
-Date: Mon, 8 Jul 2019 11:55:18 +0200
-Subject: [PATCH] Add secureboot support on efi chainloader
-
-Expand the chainloader to be able to verify the image by means of shim
-lock protocol. The PE/COFF image is loaded and relocated by the
-chainloader instead of calling LoadImage and StartImage UEFI boot
-Service as they require positive verification result from keys enrolled
-in KEK or DB. The shim will use MOK in addition to firmware enrolled
-keys to verify the image.
-
-The chainloader module could be used to load other UEFI bootloaders,
-such as xen.efi, and could be signed by any of MOK, KEK or DB.
-
-Based on https://build.opensuse.org/package/view_file/openSUSE:Factory/grub2/grub2-secureboot-chainloader.patch
-
-Signed-off-by: Peter Jones
-
-Also:
-
-commit cd7a8984d4fda905877b5bfe466339100156b3bc
-Author: Raymund Will
-Date: Fri Apr 10 01:45:02 2015 -0400
-
-Use device part of chainloader target, if present.
-
-Otherwise chainloading is restricted to '$root', which might not even
-be readable by EFI!
-
-v1. use grub_file_get_device_name() to get device name
-
-Signed-off-by: Michael Chang
-Signed-off-by: Peter Jones
-
-Also:
-
-commit 0872a2310a0eeac4ecfe9e1b49dd2d72ab373039
-Author: Peter Jones
-Date: Fri Jun 10 14:06:15 2016 -0400
-
-Rework even more of efi chainload so non-sb cases work right.
-
-This ensures that if shim protocol is not loaded, or is loaded but shim
-is disabled, we will fall back to a correct load method for the efi
-chain loader.
-
-Here's what I tested with this version:
-
-results expected actual
-------------------------------------------------------------
-sb + enabled + shim + fedora success success
-sb + enabled + shim + win success success
-sb + enabled + grub + fedora fail fail
-sb + enabled + grub + win fail fail
-
-sb + mokdisabled + shim + fedora success success
-sb + mokdisabled + shim + win success success
-sb + mokdisabled + grub + fedora fail fail
-sb + mokdisabled + grub + win fail fail
-
-sb disabled + shim + fedora success success*
-sb disabled + shim + win success success*
-sb disabled + grub + fedora success success
-sb disabled + grub + win success success
-
-nosb + shim + fedora success success*
-nosb + shim + win success success*
-nosb + grub + fedora success success
-nosb + grub + win success success
-
-* for some reason shim protocol is being installed in these cases, and I
- can't see why, but I think it may be this firmware build returning an
- erroneous value. But this effectively falls back to the mokdisabled
- behavior, which works correctly, and the presence of the "grub" (i.e.
- no shim) tests effectively tests the desired behavior here.
-
-Resolves: rhbz#1344512
-
-Signed-off-by: Peter Jones
-
-Also:
-
-commit ff7b1cb7f69487870211aeb69ff4f54470fbcb58
-Author: Laszlo Ersek
-Date: Mon Nov 21 15:34:00 2016 +0100
-
-efi/chainloader: fix wrong sanity check in relocate_coff()
-
-In relocate_coff(), the relocation entries are parsed from the original
-image (not the section-wise copied image). The original image is
-pointed-to by the "orig" pointer. The current check
-
- (void *)reloc_end < data
-
-compares the addresses of independent memory allocations. "data" is a typo
-here, it should be "orig".
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1347291
-Signed-off-by: Laszlo Ersek
-Tested-by: Bogdan Costescu
-Tested-by: Juan Orti
-
-Also:
-
-commit ab4ba9997ad4832449e54d930fa2aac6a160d0e9
-Author: Laszlo Ersek
-Date: Wed Nov 23 06:27:09 2016 +0100
-
-efi/chainloader: truncate overlong relocation section
-
-The UEFI Windows 7 boot loader ("EFI/Microsoft/Boot/bootmgfw.efi", SHA1
-31b410e029bba87d2068c65a80b88882f9f8ea25) has inconsistent headers.
-
-Compare:
-
-> The Data Directory
-> ...
-> Entry 5 00000000000d9000 00000574 Base Relocation Directory [.reloc]
-
-Versus:
-
-> Sections:
-> Idx Name Size VMA LMA File off ...
-> ...
-> 10 .reloc 00000e22 00000000100d9000 00000000100d9000 000a1800 ...
-
-That is, the size reported by the RelocDir entry (0x574) is smaller than
-the virtual size of the .reloc section (0xe22).
-
-Quoting the grub2 debug log for the same:
-
-> chainloader.c:595: reloc_dir: 0xd9000 reloc_size: 0x00000574
-> chainloader.c:603: reloc_base: 0x7d208000 reloc_base_end: 0x7d208573
-> ...
-> chainloader.c:620: Section 10 ".reloc" at 0x7d208000..0x7d208e21
-> chainloader.c:661: section is not reloc section?
-> chainloader.c:663: rds: 0x00001000, vs: 00000e22
-> chainloader.c:664: base: 0x7d208000 end: 0x7d208e21
-> chainloader.c:666: reloc_base: 0x7d208000 reloc_base_end: 0x7d208573
-> chainloader.c:671: Section characteristics are 42000040
-> chainloader.c:673: Section virtual size: 00000e22
-> chainloader.c:675: Section raw_data size: 00001000
-> chainloader.c:678: Discarding section
-
-After hexdumping "bootmgfw.efi" and manually walking its relocation blocks
-(yes, really), I determined that the (smaller) RelocDir value is correct.
-The remaining area that extends up to the .reloc section size (== 0xe22 -
-0x574 == 0x8ae bytes) exists as zero padding in the file.
-
-This zero padding shouldn't be passed to relocate_coff() for parsing. In
-order to cope with it, split the handling of .reloc sections into the
-following branches:
-
-- original case (equal size): original behavior (--> relocation
- attempted),
-
-- overlong .reloc section (longer than reported by RelocDir): truncate the
- section to the RelocDir size for the purposes of relocate_coff(), and
- attempt relocation,
-
-- .reloc section is too short, or other checks fail: original behavior
- (--> relocation not attempted).
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1347291
-Signed-off-by: Laszlo Ersek
----
- grub-core/kern/efi/efi.c | 14 +-
- grub-core/loader/arm64/linux.c | 4 +-
- grub-core/loader/efi/chainloader.c | 816 +++++++++++++++++++++++++++++++++----
- grub-core/loader/efi/linux.c | 25 +-
- grub-core/loader/i386/efi/linux.c | 17 +-
- include/grub/efi/linux.h | 2 +-
- include/grub/efi/pe32.h | 52 ++-
- 7 files changed, 840 insertions(+), 90 deletions(-)
-
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index 35b8f670602..4a2259aa1c7 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -296,14 +296,20 @@ grub_efi_secure_boot (void)
- grub_efi_boolean_t ret = 0;
-
- secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
--
- if (datasize != 1 || !secure_boot)
-- goto out;
-+ {
-+ grub_dprintf ("secureboot", "No SecureBoot variable\n");
-+ goto out;
-+ }
-+ grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot);
-
- setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
--
- if (datasize != 1 || !setup_mode)
-- goto out;
-+ {
-+ grub_dprintf ("secureboot", "No SetupMode variable\n");
-+ goto out;
-+ }
-+ grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode);
-
- if (*secure_boot && !*setup_mode)
- ret = 1;
-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
-index a312c668685..04994d5c67d 100644
---- a/grub-core/loader/arm64/linux.c
-+++ b/grub-core/loader/arm64/linux.c
-@@ -284,6 +284,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- struct linux_arch_kernel_header lh;
- struct grub_armxx_linux_pe_header *pe;
- grub_err_t err;
-+ int rc;
-
- grub_dl_ref (my_mod);
-
-@@ -328,7 +329,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
-
-- if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
-+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
-+ if (rc < 0)
- {
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
- goto fail;
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index 2bd80f4db3d..b54cf6986fc 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -32,6 +32,8 @@
- #include
- #include
- #include
-+#include
-+#include
- #include
- #include
- #include
-@@ -46,9 +48,14 @@ static grub_dl_t my_mod;
-
- static grub_efi_physical_address_t address;
- static grub_efi_uintn_t pages;
-+static grub_ssize_t fsize;
- static grub_efi_device_path_t *file_path;
- static grub_efi_handle_t image_handle;
- static grub_efi_char16_t *cmdline;
-+static grub_ssize_t cmdline_len;
-+static grub_efi_handle_t dev_handle;
-+
-+static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
-
- static grub_err_t
- grub_chainloader_unload (void)
-@@ -63,6 +70,7 @@ grub_chainloader_unload (void)
- grub_free (cmdline);
- cmdline = 0;
- file_path = 0;
-+ dev_handle = 0;
-
- grub_dl_unref (my_mod);
- return GRUB_ERR_NONE;
-@@ -213,20 +221,690 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
- return file_path;
- }
-
-+#define SHIM_LOCK_GUID \
-+ { 0x605dab50, 0xe046, 0x4300, { 0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23 } }
-+
-+typedef union
-+{
-+ struct grub_pe32_header_32 pe32;
-+ struct grub_pe32_header_64 pe32plus;
-+} grub_pe_header_t;
-+
-+struct pe_coff_loader_image_context
-+{
-+ grub_efi_uint64_t image_address;
-+ grub_efi_uint64_t image_size;
-+ grub_efi_uint64_t entry_point;
-+ grub_efi_uintn_t size_of_headers;
-+ grub_efi_uint16_t image_type;
-+ grub_efi_uint16_t number_of_sections;
-+ grub_efi_uint32_t section_alignment;
-+ struct grub_pe32_section_table *first_section;
-+ struct grub_pe32_data_directory *reloc_dir;
-+ struct grub_pe32_data_directory *sec_dir;
-+ grub_efi_uint64_t number_of_rva_and_sizes;
-+ grub_pe_header_t *pe_hdr;
-+};
-+
-+typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t;
-+
-+struct grub_efi_shim_lock
-+{
-+ grub_efi_status_t (*verify)(void *buffer,
-+ grub_efi_uint32_t size);
-+ grub_efi_status_t (*hash)(void *data,
-+ grub_efi_int32_t datasize,
-+ pe_coff_loader_image_context_t *context,
-+ grub_efi_uint8_t *sha256hash,
-+ grub_efi_uint8_t *sha1hash);
-+ grub_efi_status_t (*context)(void *data,
-+ grub_efi_uint32_t size,
-+ pe_coff_loader_image_context_t *context);
-+};
-+
-+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
-+
-+static grub_efi_boolean_t
-+read_header (void *data, grub_efi_uint32_t size,
-+ pe_coff_loader_image_context_t *context)
-+{
-+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
-+ grub_efi_shim_lock_t *shim_lock;
-+ grub_efi_status_t status;
-+
-+ shim_lock = grub_efi_locate_protocol (&guid, NULL);
-+ if (!shim_lock)
-+ {
-+ grub_dprintf ("chain", "no shim lock protocol");
-+ return 0;
-+ }
-+
-+ status = shim_lock->context (data, size, context);
-+
-+ if (status == GRUB_EFI_SUCCESS)
-+ {
-+ grub_dprintf ("chain", "context success\n");
-+ return 1;
-+ }
-+
-+ switch (status)
-+ {
-+ case GRUB_EFI_UNSUPPORTED:
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported");
-+ break;
-+ case GRUB_EFI_INVALID_PARAMETER:
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter");
-+ break;
-+ default:
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code");
-+ break;
-+ }
-+
-+ return -1;
-+}
-+
-+static void*
-+image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr)
-+{
-+ if (adr > sz)
-+ return NULL;
-+
-+ return ((grub_uint8_t*)image + adr);
-+}
-+
-+static int
-+image_is_64_bit (grub_pe_header_t *pe_hdr)
-+{
-+ /* .Magic is the same offset in all cases */
-+ if (pe_hdr->pe32plus.optional_header.magic == GRUB_PE32_PE64_MAGIC)
-+ return 1;
-+ return 0;
-+}
-+
-+static const grub_uint16_t machine_type __attribute__((__unused__)) =
-+#if defined(__x86_64__)
-+ GRUB_PE32_MACHINE_X86_64;
-+#elif defined(__aarch64__)
-+ GRUB_PE32_MACHINE_ARM64;
-+#elif defined(__arm__)
-+ GRUB_PE32_MACHINE_ARMTHUMB_MIXED;
-+#elif defined(__i386__) || defined(__i486__) || defined(__i686__)
-+ GRUB_PE32_MACHINE_I386;
-+#elif defined(__ia64__)
-+ GRUB_PE32_MACHINE_IA64;
-+#else
-+#error this architecture is not supported by grub2
-+#endif
-+
-+static grub_efi_status_t
-+relocate_coff (pe_coff_loader_image_context_t *context,
-+ struct grub_pe32_section_table *section,
-+ void *orig, void *data)
-+{
-+ struct grub_pe32_data_directory *reloc_base, *reloc_base_end;
-+ grub_efi_uint64_t adjust;
-+ struct grub_pe32_fixup_block *reloc, *reloc_end;
-+ char *fixup, *fixup_base, *fixup_data = NULL;
-+ grub_efi_uint16_t *fixup_16;
-+ grub_efi_uint32_t *fixup_32;
-+ grub_efi_uint64_t *fixup_64;
-+ grub_efi_uint64_t size = context->image_size;
-+ void *image_end = (char *)orig + size;
-+ int n = 0;
-+
-+ if (image_is_64_bit (context->pe_hdr))
-+ context->pe_hdr->pe32plus.optional_header.image_base =
-+ (grub_uint64_t)(unsigned long)data;
-+ else
-+ context->pe_hdr->pe32.optional_header.image_base =
-+ (grub_uint32_t)(unsigned long)data;
-+
-+ /* Alright, so here's how this works:
-+ *
-+ * context->reloc_dir gives us two things:
-+ * - the VA the table of base relocation blocks are (maybe) to be
-+ * mapped at (reloc_dir->rva)
-+ * - the virtual size (reloc_dir->size)
-+ *
-+ * The .reloc section (section here) gives us some other things:
-+ * - the name! kind of. (section->name)
-+ * - the virtual size (section->virtual_size), which should be the same
-+ * as RelocDir->Size
-+ * - the virtual address (section->virtual_address)
-+ * - the file section size (section->raw_data_size), which is
-+ * a multiple of optional_header->file_alignment. Only useful for image
-+ * validation, not really useful for iteration bounds.
-+ * - the file address (section->raw_data_offset)
-+ * - a bunch of stuff we don't use that's 0 in our binaries usually
-+ * - Flags (section->characteristics)
-+ *
-+ * and then the thing that's actually at the file address is an array
-+ * of struct grub_pe32_fixup_block structs with some values packed behind
-+ * them. The block_size field of this structure includes the
-+ * structure itself, and adding it to that structure's address will
-+ * yield the next entry in the array.
-+ */
-+
-+ reloc_base = image_address (orig, size, section->raw_data_offset);
-+ reloc_base_end = image_address (orig, size, section->raw_data_offset
-+ + section->virtual_size);
-+
-+ grub_dprintf ("chain", "relocate_coff(): reloc_base %p reloc_base_end %p\n",
-+ reloc_base, reloc_base_end);
-+
-+ if (!reloc_base && !reloc_base_end)
-+ return GRUB_EFI_SUCCESS;
-+
-+ if (!reloc_base || !reloc_base_end)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary");
-+ return GRUB_EFI_UNSUPPORTED;
-+ }
-+
-+ adjust = (grub_uint64_t)(grub_efi_uintn_t)data - context->image_address;
-+ if (adjust == 0)
-+ return GRUB_EFI_SUCCESS;
-+
-+ while (reloc_base < reloc_base_end)
-+ {
-+ grub_uint16_t *entry;
-+ reloc = (struct grub_pe32_fixup_block *)((char*)reloc_base);
-+
-+ if ((reloc_base->size == 0) ||
-+ (reloc_base->size > context->reloc_dir->size))
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT,
-+ "Reloc %d block size %d is invalid\n", n,
-+ reloc_base->size);
-+ return GRUB_EFI_UNSUPPORTED;
-+ }
-+
-+ entry = &reloc->entries[0];
-+ reloc_end = (struct grub_pe32_fixup_block *)
-+ ((char *)reloc_base + reloc_base->size);
-+
-+ if ((void *)reloc_end < orig || (void *)reloc_end > image_end)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc entry %d overflows binary",
-+ n);
-+ return GRUB_EFI_UNSUPPORTED;
-+ }
-+
-+ fixup_base = image_address(data, size, reloc_base->rva);
-+
-+ if (!fixup_base)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc %d Invalid fixupbase", n);
-+ return GRUB_EFI_UNSUPPORTED;
-+ }
-+
-+ while ((void *)entry < (void *)reloc_end)
-+ {
-+ fixup = fixup_base + (*entry & 0xFFF);
-+ switch ((*entry) >> 12)
-+ {
-+ case GRUB_PE32_REL_BASED_ABSOLUTE:
-+ break;
-+ case GRUB_PE32_REL_BASED_HIGH:
-+ fixup_16 = (grub_uint16_t *)fixup;
-+ *fixup_16 = (grub_uint16_t)
-+ (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16)));
-+ if (fixup_data != NULL)
-+ {
-+ *(grub_uint16_t *) fixup_data = *fixup_16;
-+ fixup_data = fixup_data + sizeof (grub_uint16_t);
-+ }
-+ break;
-+ case GRUB_PE32_REL_BASED_LOW:
-+ fixup_16 = (grub_uint16_t *)fixup;
-+ *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust);
-+ if (fixup_data != NULL)
-+ {
-+ *(grub_uint16_t *) fixup_data = *fixup_16;
-+ fixup_data = fixup_data + sizeof (grub_uint16_t);
-+ }
-+ break;
-+ case GRUB_PE32_REL_BASED_HIGHLOW:
-+ fixup_32 = (grub_uint32_t *)fixup;
-+ *fixup_32 = *fixup_32 + (grub_uint32_t)adjust;
-+ if (fixup_data != NULL)
-+ {
-+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t));
-+ *(grub_uint32_t *) fixup_data = *fixup_32;
-+ fixup_data += sizeof (grub_uint32_t);
-+ }
-+ break;
-+ case GRUB_PE32_REL_BASED_DIR64:
-+ fixup_64 = (grub_uint64_t *)fixup;
-+ *fixup_64 = *fixup_64 + (grub_uint64_t)adjust;
-+ if (fixup_data != NULL)
-+ {
-+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t));
-+ *(grub_uint64_t *) fixup_data = *fixup_64;
-+ fixup_data += sizeof (grub_uint64_t);
-+ }
-+ break;
-+ default:
-+ grub_error (GRUB_ERR_BAD_ARGUMENT,
-+ "Reloc %d unknown relocation type %d",
-+ n, (*entry) >> 12);
-+ return GRUB_EFI_UNSUPPORTED;
-+ }
-+ entry += 1;
-+ }
-+ reloc_base = (struct grub_pe32_data_directory *)reloc_end;
-+ n++;
-+ }
-+
-+ return GRUB_EFI_SUCCESS;
-+}
-+
-+static grub_efi_device_path_t *
-+grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
-+{
-+ while (1)
-+ {
-+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
-+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
-+
-+ if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
-+ break;
-+ else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
-+ && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
-+ return dp;
-+
-+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
-+ }
-+
-+ return NULL;
-+}
-+
-+static grub_efi_boolean_t
-+handle_image (void *data, grub_efi_uint32_t datasize)
-+{
-+ grub_efi_boot_services_t *b;
-+ grub_efi_loaded_image_t *li, li_bak;
-+ grub_efi_status_t efi_status;
-+ char *buffer = NULL;
-+ char *buffer_aligned = NULL;
-+ grub_efi_uint32_t i;
-+ struct grub_pe32_section_table *section;
-+ char *base, *end;
-+ pe_coff_loader_image_context_t context;
-+ grub_uint32_t section_alignment;
-+ grub_uint32_t buffer_size;
-+ int found_entry_point = 0;
-+ int rc;
-+
-+ b = grub_efi_system_table->boot_services;
-+
-+ rc = read_header (data, datasize, &context);
-+ if (rc < 0)
-+ {
-+ grub_dprintf ("chain", "Failed to read header\n");
-+ goto error_exit;
-+ }
-+ else if (rc == 0)
-+ {
-+ grub_dprintf ("chain", "Secure Boot is not enabled\n");
-+ return 0;
-+ }
-+ else
-+ {
-+ grub_dprintf ("chain", "Header read without error\n");
-+ }
-+
-+ /*
-+ * The spec says, uselessly, of SectionAlignment:
-+ * =====
-+ * The alignment (in bytes) of sections when they are loaded into
-+ * memory. It must be greater than or equal to FileAlignment. The
-+ * default is the page size for the architecture.
-+ * =====
-+ * Which doesn't tell you whose responsibility it is to enforce the
-+ * "default", or when. It implies that the value in the field must
-+ * be > FileAlignment (also poorly defined), but it appears visual
-+ * studio will happily write 512 for FileAlignment (its default) and
-+ * 0 for SectionAlignment, intending to imply PAGE_SIZE.
-+ *
-+ * We only support one page size, so if it's zero, nerf it to 4096.
-+ */
-+ section_alignment = context.section_alignment;
-+ if (section_alignment == 0)
-+ section_alignment = 4096;
-+
-+ buffer_size = context.image_size + section_alignment;
-+ grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n",
-+ context.image_size, datasize);
-+
-+ efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
-+ buffer_size, &buffer);
-+
-+ if (efi_status != GRUB_EFI_SUCCESS)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
-+ goto error_exit;
-+ }
-+
-+ buffer_aligned = (char *)ALIGN_UP ((grub_addr_t)buffer, section_alignment);
-+ if (!buffer_aligned)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
-+ goto error_exit;
-+ }
-+
-+ grub_memcpy (buffer_aligned, data, context.size_of_headers);
-+
-+ entry_point = image_address (buffer_aligned, context.image_size,
-+ context.entry_point);
-+
-+ grub_dprintf ("chain", "entry_point: %p\n", entry_point);
-+ if (!entry_point)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point");
-+ goto error_exit;
-+ }
-+
-+ char *reloc_base, *reloc_base_end;
-+ grub_dprintf ("chain", "reloc_dir: %p reloc_size: 0x%08x\n",
-+ (void *)(unsigned long)context.reloc_dir->rva,
-+ context.reloc_dir->size);
-+ reloc_base = image_address (buffer_aligned, context.image_size,
-+ context.reloc_dir->rva);
-+ /* RelocBaseEnd here is the address of the last byte of the table */
-+ reloc_base_end = image_address (buffer_aligned, context.image_size,
-+ context.reloc_dir->rva
-+ + context.reloc_dir->size - 1);
-+ grub_dprintf ("chain", "reloc_base: %p reloc_base_end: %p\n",
-+ reloc_base, reloc_base_end);
-+
-+ struct grub_pe32_section_table *reloc_section = NULL, fake_reloc_section;
-+
-+ section = context.first_section;
-+ for (i = 0; i < context.number_of_sections; i++, section++)
-+ {
-+ char name[9];
-+
-+ base = image_address (buffer_aligned, context.image_size,
-+ section->virtual_address);
-+ end = image_address (buffer_aligned, context.image_size,
-+ section->virtual_address + section->virtual_size -1);
-+
-+ grub_strncpy(name, section->name, 9);
-+ name[8] = '\0';
-+ grub_dprintf ("chain", "Section %d \"%s\" at %p..%p\n", i,
-+ name, base, end);
-+
-+ if (end < base)
-+ {
-+ grub_dprintf ("chain", " base is %p but end is %p... bad.\n",
-+ base, end);
-+ grub_error (GRUB_ERR_BAD_ARGUMENT,
-+ "Image has invalid negative size");
-+ goto error_exit;
-+ }
-+
-+ if (section->virtual_address <= context.entry_point &&
-+ (section->virtual_address + section->raw_data_size - 1)
-+ > context.entry_point)
-+ {
-+ found_entry_point++;
-+ grub_dprintf ("chain", " section contains entry point\n");
-+ }
-+
-+ /* We do want to process .reloc, but it's often marked
-+ * discardable, so we don't want to memcpy it. */
-+ if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0)
-+ {
-+ if (reloc_section)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT,
-+ "Image has multiple relocation sections");
-+ goto error_exit;
-+ }
-+
-+ /* If it has nonzero sizes, and our bounds check
-+ * made sense, and the VA and size match RelocDir's
-+ * versions, then we believe in this section table. */
-+ if (section->raw_data_size && section->virtual_size &&
-+ base && end && reloc_base == base)
-+ {
-+ if (reloc_base_end == end)
-+ {
-+ grub_dprintf ("chain", " section is relocation section\n");
-+ reloc_section = section;
-+ }
-+ else if (reloc_base_end && reloc_base_end < end)
-+ {
-+ /* Bogus virtual size in the reloc section -- RelocDir
-+ * reported a smaller Base Relocation Directory. Decrease
-+ * the section's virtual size so that it equal RelocDir's
-+ * idea, but only for the purposes of relocate_coff(). */
-+ grub_dprintf ("chain",
-+ " section is (overlong) relocation section\n");
-+ grub_memcpy (&fake_reloc_section, section, sizeof *section);
-+ fake_reloc_section.virtual_size -= (end - reloc_base_end);
-+ reloc_section = &fake_reloc_section;
-+ }
-+ }
-+
-+ if (!reloc_section)
-+ {
-+ grub_dprintf ("chain", " section is not reloc section?\n");
-+ grub_dprintf ("chain", " rds: 0x%08x, vs: %08x\n",
-+ section->raw_data_size, section->virtual_size);
-+ grub_dprintf ("chain", " base: %p end: %p\n", base, end);
-+ grub_dprintf ("chain", " reloc_base: %p reloc_base_end: %p\n",
-+ reloc_base, reloc_base_end);
-+ }
-+ }
-+
-+ grub_dprintf ("chain", " Section characteristics are %08x\n",
-+ section->characteristics);
-+ grub_dprintf ("chain", " Section virtual size: %08x\n",
-+ section->virtual_size);
-+ grub_dprintf ("chain", " Section raw_data size: %08x\n",
-+ section->raw_data_size);
-+ if (section->characteristics & GRUB_PE32_SCN_MEM_DISCARDABLE)
-+ {
-+ grub_dprintf ("chain", " Discarding section\n");
-+ continue;
-+ }
-+
-+ if (!base || !end)
-+ {
-+ grub_dprintf ("chain", " section is invalid\n");
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size");
-+ goto error_exit;
-+ }
-+
-+ if (section->characteristics & GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA)
-+ {
-+ if (section->raw_data_size != 0)
-+ grub_dprintf ("chain", " UNINITIALIZED_DATA section has data?\n");
-+ }
-+ else if (section->virtual_address < context.size_of_headers ||
-+ section->raw_data_offset < context.size_of_headers)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT,
-+ "Section %d is inside image headers", i);
-+ goto error_exit;
-+ }
-+
-+ if (section->raw_data_size > 0)
-+ {
-+ grub_dprintf ("chain", " copying 0x%08x bytes to %p\n",
-+ section->raw_data_size, base);
-+ grub_memcpy (base,
-+ (grub_efi_uint8_t*)data + section->raw_data_offset,
-+ section->raw_data_size);
-+ }
-+
-+ if (section->raw_data_size < section->virtual_size)
-+ {
-+ grub_dprintf ("chain", " padding with 0x%08x bytes at %p\n",
-+ section->virtual_size - section->raw_data_size,
-+ base + section->raw_data_size);
-+ grub_memset (base + section->raw_data_size, 0,
-+ section->virtual_size - section->raw_data_size);
-+ }
-+
-+ grub_dprintf ("chain", " finished section %s\n", name);
-+ }
-+
-+ /* 5 == EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC */
-+ if (context.number_of_rva_and_sizes <= 5)
-+ {
-+ grub_dprintf ("chain", "image has no relocation entry\n");
-+ goto error_exit;
-+ }
-+
-+ if (context.reloc_dir->size && reloc_section)
-+ {
-+ /* run the relocation fixups */
-+ efi_status = relocate_coff (&context, reloc_section, data,
-+ buffer_aligned);
-+
-+ if (efi_status != GRUB_EFI_SUCCESS)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed");
-+ goto error_exit;
-+ }
-+ }
-+
-+ if (!found_entry_point)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "entry point is not within sections");
-+ goto error_exit;
-+ }
-+ if (found_entry_point > 1)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "%d sections contain entry point",
-+ found_entry_point);
-+ goto error_exit;
-+ }
-+
-+ li = grub_efi_get_loaded_image (grub_efi_image_handle);
-+ if (!li)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available");
-+ goto error_exit;
-+ }
-+
-+ grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t));
-+ li->image_base = buffer_aligned;
-+ li->image_size = context.image_size;
-+ li->load_options = cmdline;
-+ li->load_options_size = cmdline_len;
-+ li->file_path = grub_efi_get_media_file_path (file_path);
-+ li->device_handle = dev_handle;
-+ if (!li->file_path)
-+ {
-+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
-+ goto error_exit;
-+ }
-+
-+ grub_dprintf ("chain", "booting via entry point\n");
-+ efi_status = efi_call_2 (entry_point, grub_efi_image_handle,
-+ grub_efi_system_table);
-+
-+ grub_dprintf ("chain", "entry_point returned %ld\n", efi_status);
-+ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t));
-+ efi_status = efi_call_1 (b->free_pool, buffer);
-+
-+ return 1;
-+
-+error_exit:
-+ grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno);
-+ if (buffer)
-+ efi_call_1 (b->free_pool, buffer);
-+
-+ return 0;
-+}
-+
-+static grub_err_t
-+grub_secureboot_chainloader_unload (void)
-+{
-+ grub_efi_boot_services_t *b;
-+
-+ b = grub_efi_system_table->boot_services;
-+ efi_call_2 (b->free_pages, address, pages);
-+ grub_free (file_path);
-+ grub_free (cmdline);
-+ cmdline = 0;
-+ file_path = 0;
-+ dev_handle = 0;
-+
-+ grub_dl_unref (my_mod);
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_load_and_start_image(void *boot_image)
-+{
-+ grub_efi_boot_services_t *b;
-+ grub_efi_status_t status;
-+ grub_efi_loaded_image_t *loaded_image;
-+
-+ b = grub_efi_system_table->boot_services;
-+
-+ status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
-+ boot_image, fsize, &image_handle);
-+ if (status != GRUB_EFI_SUCCESS)
-+ {
-+ if (status == GRUB_EFI_OUT_OF_RESOURCES)
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
-+ else
-+ grub_error (GRUB_ERR_BAD_OS, "cannot load image");
-+ return -1;
-+ }
-+
-+ /* LoadImage does not set a device handler when the image is
-+ loaded from memory, so it is necessary to set it explicitly here.
-+ This is a mess. */
-+ loaded_image = grub_efi_get_loaded_image (image_handle);
-+ if (! loaded_image)
-+ {
-+ grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
-+ return -1;
-+ }
-+ loaded_image->device_handle = dev_handle;
-+
-+ if (cmdline)
-+ {
-+ loaded_image->load_options = cmdline;
-+ loaded_image->load_options_size = cmdline_len;
-+ }
-+
-+ return 0;
-+}
-+
-+static grub_err_t
-+grub_secureboot_chainloader_boot (void)
-+{
-+ int rc;
-+ rc = handle_image ((void *)(unsigned long)address, fsize);
-+ if (rc == 0)
-+ {
-+ grub_load_and_start_image((void *)(unsigned long)address);
-+ }
-+
-+ grub_loader_unset ();
-+ return grub_errno;
-+}
-+
- static grub_err_t
- grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- int argc, char *argv[])
- {
- grub_file_t file = 0;
-- grub_ssize_t size;
- grub_efi_status_t status;
- grub_efi_boot_services_t *b;
- grub_device_t dev = 0;
- grub_efi_device_path_t *dp = 0;
-- grub_efi_loaded_image_t *loaded_image;
- char *filename;
- void *boot_image = 0;
-- grub_efi_handle_t dev_handle = 0;
-+ int rc;
-
- if (argc == 0)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
-@@ -238,15 +916,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- address = 0;
- image_handle = 0;
- file_path = 0;
-+ dev_handle = 0;
-
- b = grub_efi_system_table->boot_services;
-
-+ if (argc > 1)
-+ {
-+ int i;
-+ grub_efi_char16_t *p16;
-+
-+ for (i = 1, cmdline_len = 0; i < argc; i++)
-+ cmdline_len += grub_strlen (argv[i]) + 1;
-+
-+ cmdline_len *= sizeof (grub_efi_char16_t);
-+ cmdline = p16 = grub_malloc (cmdline_len);
-+ if (! cmdline)
-+ goto fail;
-+
-+ for (i = 1; i < argc; i++)
-+ {
-+ char *p8;
-+
-+ p8 = argv[i];
-+ while (*p8)
-+ *(p16++) = *(p8++);
-+
-+ *(p16++) = ' ';
-+ }
-+ *(--p16) = 0;
-+ }
-+
- file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
- if (! file)
- goto fail;
-
-- /* Get the root device's device path. */
-- dev = grub_device_open (0);
-+ /* Get the device path from filename. */
-+ char *devname = grub_file_get_device_name (filename);
-+ dev = grub_device_open (devname);
-+ if (devname)
-+ grub_free (devname);
- if (! dev)
- goto fail;
-
-@@ -283,17 +991,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- if (! file_path)
- goto fail;
-
-- grub_printf ("file path: ");
-- grub_efi_print_device_path (file_path);
--
-- size = grub_file_size (file);
-- if (!size)
-+ fsize = grub_file_size (file);
-+ if (!fsize)
- {
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- filename);
- goto fail;
- }
-- pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
-+ pages = (((grub_efi_uintn_t) fsize + ((1 << 12) - 1)) >> 12);
-
- status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
- GRUB_EFI_LOADER_CODE,
-@@ -307,7 +1012,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- }
-
- boot_image = (void *) ((grub_addr_t) address);
-- if (grub_file_read (file, boot_image, size) != size)
-+ if (grub_file_read (file, boot_image, fsize) != fsize)
- {
- if (grub_errno == GRUB_ERR_NONE)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-@@ -317,7 +1022,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- }
-
- #if defined (__i386__) || defined (__x86_64__)
-- if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
-+ if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
- {
- struct grub_macho_fat_header *head = boot_image;
- if (head->magic
-@@ -326,6 +1031,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- grub_uint32_t i;
- struct grub_macho_fat_arch *archs
- = (struct grub_macho_fat_arch *) (head + 1);
-+
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ {
-+ grub_error (GRUB_ERR_BAD_OS,
-+ "MACHO binaries are forbidden with Secure Boot");
-+ goto fail;
-+ }
-+
- for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++)
- {
- if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype))
-@@ -340,79 +1053,39 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- > ~grub_cpu_to_le32 (archs[i].size)
- || grub_cpu_to_le32 (archs[i].offset)
- + grub_cpu_to_le32 (archs[i].size)
-- > (grub_size_t) size)
-+ > (grub_size_t) fsize)
- {
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- filename);
- goto fail;
- }
- boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset);
-- size = grub_cpu_to_le32 (archs[i].size);
-+ fsize = grub_cpu_to_le32 (archs[i].size);
- }
- }
- #endif
-
-- status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
-- boot_image, size,
-- &image_handle);
-- if (status != GRUB_EFI_SUCCESS)
-+ rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize);
-+ grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc);
-+ if (rc > 0)
- {
-- if (status == GRUB_EFI_OUT_OF_RESOURCES)
-- grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
-- else
-- grub_error (GRUB_ERR_BAD_OS, "cannot load image");
--
-- goto fail;
-+ grub_file_close (file);
-+ grub_device_close (dev);
-+ grub_loader_set (grub_secureboot_chainloader_boot,
-+ grub_secureboot_chainloader_unload, 0);
-+ return 0;
- }
--
-- /* LoadImage does not set a device handler when the image is
-- loaded from memory, so it is necessary to set it explicitly here.
-- This is a mess. */
-- loaded_image = grub_efi_get_loaded_image (image_handle);
-- if (! loaded_image)
-+ else if (rc == 0)
- {
-- grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
-- goto fail;
-- }
-- loaded_image->device_handle = dev_handle;
--
-- if (argc > 1)
-- {
-- int i, len;
-- grub_efi_char16_t *p16;
--
-- for (i = 1, len = 0; i < argc; i++)
-- len += grub_strlen (argv[i]) + 1;
--
-- len *= sizeof (grub_efi_char16_t);
-- cmdline = p16 = grub_malloc (len);
-- if (! cmdline)
-- goto fail;
-+ grub_load_and_start_image(boot_image);
-+ grub_file_close (file);
-+ grub_device_close (dev);
-+ grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
-
-- for (i = 1; i < argc; i++)
-- {
-- char *p8;
--
-- p8 = argv[i];
-- while (*p8)
-- *(p16++) = *(p8++);
--
-- *(p16++) = ' ';
-- }
-- *(--p16) = 0;
--
-- loaded_image->load_options = cmdline;
-- loaded_image->load_options_size = len;
-+ return 0;
- }
-
-- grub_file_close (file);
-- grub_device_close (dev);
--
-- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
-- return 0;
--
-- fail:
--
-+fail:
- if (dev)
- grub_device_close (dev);
-
-@@ -424,6 +1097,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- if (address)
- efi_call_2 (b->free_pages, address, pages);
-
-+ if (cmdline)
-+ grub_free (cmdline);
-+
- grub_dl_unref (my_mod);
-
- return grub_errno;
-diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
-index c24202a5dd1..c8ecce6dfd0 100644
---- a/grub-core/loader/efi/linux.c
-+++ b/grub-core/loader/efi/linux.c
-@@ -33,21 +33,34 @@ struct grub_efi_shim_lock
- };
- typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
-
--grub_efi_boolean_t
-+int
- grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
- {
- grub_efi_guid_t guid = SHIM_LOCK_GUID;
- grub_efi_shim_lock_t *shim_lock;
-+ grub_efi_status_t status;
-
- shim_lock = grub_efi_locate_protocol(&guid, NULL);
--
-+ grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock);
- if (!shim_lock)
-- return 1;
-+ {
-+ grub_dprintf ("secureboot", "shim not available\n");
-+ return 0;
-+ }
-
-- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
-- return 1;
-+ grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n");
-+ status = shim_lock->verify (data, size);
-+ grub_dprintf ("secureboot", "shim_lock->verify(): %ld\n", (long int)status);
-+ if (status == GRUB_EFI_SUCCESS)
-+ {
-+ grub_dprintf ("secureboot", "Kernel signature verification passed\n");
-+ return 1;
-+ }
-
-- return 0;
-+ grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n",
-+ (unsigned long) status);
-+
-+ return -1;
- }
-
- #pragma GCC diagnostic push
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-index bb2616a8092..6b24cbb9483 100644
---- a/grub-core/loader/i386/efi/linux.c
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -117,6 +117,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
- goto fail;
- }
-
-+ grub_dprintf ("linux", "initrd_mem = %lx\n", (unsigned long) initrd_mem);
-+
- params->ramdisk_size = size;
- params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem;
-
-@@ -159,6 +161,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- struct linux_i386_kernel_header lh;
- grub_ssize_t len, start, filelen;
- void *kernel = NULL;
-+ int rc;
-
- grub_dl_ref (my_mod);
-
-@@ -184,11 +187,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- if (grub_file_read (file, kernel, filelen) != filelen)
- {
-- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
-+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"),
-+ argv[0]);
- goto fail;
- }
-
-- if (! grub_linuxefi_secure_validate (kernel, filelen))
-+ rc = grub_linuxefi_secure_validate (kernel, filelen);
-+ if (rc < 0)
- {
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
- argv[0]);
-@@ -203,6 +208,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- goto fail;
- }
-
-+ grub_dprintf ("linux", "params = %lx\n", (unsigned long) params);
-+
- grub_memset (params, 0, 16384);
-
- grub_memcpy (&lh, kernel, sizeof (lh));
-@@ -241,6 +248,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- goto fail;
- }
-
-+ grub_dprintf ("linux", "linux_cmdline = %lx\n",
-+ (unsigned long)linux_cmdline);
-+
- grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_cmdline + sizeof (LINUX_IMAGE) - 1,
-@@ -275,9 +285,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- grub_memcpy (params, &lh, 2 * 512);
-
- params->type_of_loader = 0x21;
-+ grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n",
-+ kernel_mem, handover_offset);
-
- fail:
--
- if (file)
- grub_file_close (file);
-
-diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
-index d9ede36773b..0033d9305a9 100644
---- a/include/grub/efi/linux.h
-+++ b/include/grub/efi/linux.h
-@@ -22,7 +22,7 @@
- #include
- #include
-
--grub_efi_boolean_t
-+int
- EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
- grub_err_t
- EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
-diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
-index 0ed8781f037..a43adf27464 100644
---- a/include/grub/efi/pe32.h
-+++ b/include/grub/efi/pe32.h
-@@ -223,7 +223,11 @@ struct grub_pe64_optional_header
- struct grub_pe32_section_table
- {
- char name[8];
-- grub_uint32_t virtual_size;
-+ union
-+ {
-+ grub_uint32_t physical_address;
-+ grub_uint32_t virtual_size;
-+ };
- grub_uint32_t virtual_address;
- grub_uint32_t raw_data_size;
- grub_uint32_t raw_data_offset;
-@@ -234,12 +238,18 @@ struct grub_pe32_section_table
- grub_uint32_t characteristics;
- };
-
-+#define GRUB_PE32_SCN_TYPE_NO_PAD 0x00000008
- #define GRUB_PE32_SCN_CNT_CODE 0x00000020
- #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
--#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
--#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
--#define GRUB_PE32_SCN_MEM_READ 0x40000000
--#define GRUB_PE32_SCN_MEM_WRITE 0x80000000
-+#define GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA 0x00000080
-+#define GRUB_PE32_SCN_LNK_OTHER 0x00000100
-+#define GRUB_PE32_SCN_LNK_INFO 0x00000200
-+#define GRUB_PE32_SCN_LNK_REMOVE 0x00000800
-+#define GRUB_PE32_SCN_LNK_COMDAT 0x00001000
-+#define GRUB_PE32_SCN_GPREL 0x00008000
-+#define GRUB_PE32_SCN_MEM_16BIT 0x00020000
-+#define GRUB_PE32_SCN_MEM_LOCKED 0x00040000
-+#define GRUB_PE32_SCN_MEM_PRELOAD 0x00080000
-
- #define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
- #define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
-@@ -248,10 +258,28 @@ struct grub_pe32_section_table
- #define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
- #define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
- #define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
-+#define GRUB_PE32_SCN_ALIGN_128BYTES 0x00800000
-+#define GRUB_PE32_SCN_ALIGN_256BYTES 0x00900000
-+#define GRUB_PE32_SCN_ALIGN_512BYTES 0x00A00000
-+#define GRUB_PE32_SCN_ALIGN_1024BYTES 0x00B00000
-+#define GRUB_PE32_SCN_ALIGN_2048BYTES 0x00C00000
-+#define GRUB_PE32_SCN_ALIGN_4096BYTES 0x00D00000
-+#define GRUB_PE32_SCN_ALIGN_8192BYTES 0x00E00000
-
- #define GRUB_PE32_SCN_ALIGN_SHIFT 20
- #define GRUB_PE32_SCN_ALIGN_MASK 7
-
-+#define GRUB_PE32_SCN_LNK_NRELOC_OVFL 0x01000000
-+#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
-+#define GRUB_PE32_SCN_MEM_NOT_CACHED 0x04000000
-+#define GRUB_PE32_SCN_MEM_NOT_PAGED 0x08000000
-+#define GRUB_PE32_SCN_MEM_SHARED 0x10000000
-+#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
-+#define GRUB_PE32_SCN_MEM_READ 0x40000000
-+#define GRUB_PE32_SCN_MEM_WRITE 0x80000000
-+
-+
-+
- #define GRUB_PE32_SIGNATURE_SIZE 4
-
- struct grub_pe32_header
-@@ -274,6 +302,20 @@ struct grub_pe32_header
- #endif
- };
-
-+struct grub_pe32_header_32
-+{
-+ char signature[GRUB_PE32_SIGNATURE_SIZE];
-+ struct grub_pe32_coff_header coff_header;
-+ struct grub_pe32_optional_header optional_header;
-+};
-+
-+struct grub_pe32_header_64
-+{
-+ char signature[GRUB_PE32_SIGNATURE_SIZE];
-+ struct grub_pe32_coff_header coff_header;
-+ struct grub_pe64_optional_header optional_header;
-+};
-+
- struct grub_pe32_fixup_block
- {
- grub_uint32_t page_rva;
diff --git a/SPECS/grub2/0005-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch b/SPECS/grub2/0005-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch
deleted file mode 100644
index 3182fe99305..00000000000
--- a/SPECS/grub2/0005-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch
+++ /dev/null
@@ -1,390 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones
-Date: Tue, 6 Oct 2015 16:09:25 -0400
-Subject: [PATCH] Make any of the loaders that link in efi mode honor secure
- boot.
-
-And in this case "honor" means "even if somebody does link this in, they
-won't register commands if SB is enabled."
-
-Signed-off-by: Peter Jones
----
- grub-core/commands/iorw.c | 7 +++++++
- grub-core/commands/memrw.c | 7 +++++++
- grub-core/kern/dl.c | 3 ++-
- grub-core/kern/efi/efi.c | 34 ----------------------------------
- grub-core/loader/efi/appleloader.c | 7 +++++++
- grub-core/loader/efi/chainloader.c | 1 +
- grub-core/loader/i386/bsd.c | 7 +++++++
- grub-core/loader/i386/linux.c | 7 +++++++
- grub-core/loader/i386/pc/linux.c | 7 +++++++
- grub-core/loader/multiboot.c | 7 +++++++
- grub-core/loader/xnu.c | 7 +++++++
- include/grub/efi/efi.h | 1 -
- include/grub/ia64/linux.h | 0
- include/grub/mips/linux.h | 0
- include/grub/powerpc/linux.h | 0
- include/grub/sparc64/linux.h | 0
- 16 files changed, 59 insertions(+), 36 deletions(-)
- create mode 100644 include/grub/ia64/linux.h
- create mode 100644 include/grub/mips/linux.h
- create mode 100644 include/grub/powerpc/linux.h
- create mode 100644 include/grub/sparc64/linux.h
-
-diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c
-index 584baec8f91..7b2999b14b5 100644
---- a/grub-core/commands/iorw.c
-+++ b/grub-core/commands/iorw.c
-@@ -24,6 +24,7 @@
- #include
- #include
- #include
-+#include
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -119,6 +120,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
-
- GRUB_MOD_INIT(memrw)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- cmd_read_byte =
- grub_register_extcmd ("inb", grub_cmd_read, 0,
- N_("PORT"), N_("Read 8-bit value from PORT."),
-@@ -147,6 +151,9 @@ GRUB_MOD_INIT(memrw)
-
- GRUB_MOD_FINI(memrw)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_extcmd (cmd_read_byte);
- grub_unregister_extcmd (cmd_read_word);
- grub_unregister_extcmd (cmd_read_dword);
-diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c
-index d401a6db0ef..39cf3a06dbd 100644
---- a/grub-core/commands/memrw.c
-+++ b/grub-core/commands/memrw.c
-@@ -23,6 +23,7 @@
- #include
- #include
- #include
-+#include
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -121,6 +122,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
-
- GRUB_MOD_INIT(memrw)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- cmd_read_byte =
- grub_register_extcmd ("read_byte", grub_cmd_read, 0,
- N_("ADDR"), N_("Read 8-bit value from ADDR."),
-@@ -149,6 +153,9 @@ GRUB_MOD_INIT(memrw)
-
- GRUB_MOD_FINI(memrw)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_extcmd (cmd_read_byte);
- grub_unregister_extcmd (cmd_read_word);
- grub_unregister_extcmd (cmd_read_dword);
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index b7149370950..7afb9e6f724 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -32,6 +32,7 @@
- #include
- #include
- #include
-+#include
-
- /* Platforms where modules are in a readonly area of memory. */
- #if defined(GRUB_MACHINE_QEMU)
-@@ -704,7 +705,7 @@ grub_dl_load_file (const char *filename)
- grub_dl_t mod = 0;
-
- #ifdef GRUB_MACHINE_EFI
-- if (grub_efi_secure_boot ())
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
- {
- #if 0
- /* This is an error, but grub2-mkconfig still generates a pile of
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index 4a2259aa1c7..8cff7be0289 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -286,40 +286,6 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
- return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL);
- }
-
--grub_efi_boolean_t
--grub_efi_secure_boot (void)
--{
-- grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
-- grub_size_t datasize;
-- char *secure_boot = NULL;
-- char *setup_mode = NULL;
-- grub_efi_boolean_t ret = 0;
--
-- secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
-- if (datasize != 1 || !secure_boot)
-- {
-- grub_dprintf ("secureboot", "No SecureBoot variable\n");
-- goto out;
-- }
-- grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot);
--
-- setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
-- if (datasize != 1 || !setup_mode)
-- {
-- grub_dprintf ("secureboot", "No SetupMode variable\n");
-- goto out;
-- }
-- grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode);
--
-- if (*secure_boot && !*setup_mode)
-- ret = 1;
--
-- out:
-- grub_free (secure_boot);
-- grub_free (setup_mode);
-- return ret;
--}
--
- #pragma GCC diagnostic ignored "-Wcast-align"
-
- /* Search the mods section from the PE32/PE32+ image. This code uses
-diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c
-index 74888c463ba..585f2b57385 100644
---- a/grub-core/loader/efi/appleloader.c
-+++ b/grub-core/loader/efi/appleloader.c
-@@ -24,6 +24,7 @@
- #include
- #include
- #include
-+#include
- #include
- #include
-
-@@ -227,6 +228,9 @@ static grub_command_t cmd;
-
- GRUB_MOD_INIT(appleloader)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- cmd = grub_register_command ("appleloader", grub_cmd_appleloader,
- N_("[OPTS]"),
- /* TRANSLATORS: This command is used on EFI to
-@@ -238,5 +242,8 @@ GRUB_MOD_INIT(appleloader)
-
- GRUB_MOD_FINI(appleloader)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_command (cmd);
- }
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index b54cf6986fc..3ff305b1d32 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -34,6 +34,7 @@
- #include
- #include
- #include
-+#include
- #include
- #include
- #include
-diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
-index 5f3290ce17b..54befc26626 100644
---- a/grub-core/loader/i386/bsd.c
-+++ b/grub-core/loader/i386/bsd.c
-@@ -40,6 +40,7 @@
- #ifdef GRUB_MACHINE_PCBIOS
- #include
- #endif
-+#include
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -2137,6 +2138,9 @@ static grub_command_t cmd_netbsd_module_elf, cmd_openbsd_ramdisk;
-
- GRUB_MOD_INIT (bsd)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- /* Net and OpenBSD kernels are often compressed. */
- grub_dl_load ("gzio");
-
-@@ -2176,6 +2180,9 @@ GRUB_MOD_INIT (bsd)
-
- GRUB_MOD_FINI (bsd)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_extcmd (cmd_freebsd);
- grub_unregister_extcmd (cmd_openbsd);
- grub_unregister_extcmd (cmd_netbsd);
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
-index dccf3bb3005..4aeb0e4b9a6 100644
---- a/grub-core/loader/i386/linux.c
-+++ b/grub-core/loader/i386/linux.c
-@@ -37,6 +37,7 @@
- #include
- #include
- #include
-+#include
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -1138,6 +1139,9 @@ static grub_command_t cmd_linux, cmd_initrd;
-
- GRUB_MOD_INIT(linux)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- cmd_linux = grub_register_command ("linux", grub_cmd_linux,
- 0, N_("Load Linux."));
- cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-@@ -1147,6 +1151,9 @@ GRUB_MOD_INIT(linux)
-
- GRUB_MOD_FINI(linux)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_command (cmd_linux);
- grub_unregister_command (cmd_initrd);
- }
-diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
-index 4b1750e360e..e3fa1221e81 100644
---- a/grub-core/loader/i386/pc/linux.c
-+++ b/grub-core/loader/i386/pc/linux.c
-@@ -36,6 +36,7 @@
- #include
- #include
- #include
-+#include
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -487,6 +488,9 @@ static grub_command_t cmd_linux, cmd_linux16, cmd_initrd, cmd_initrd16;
-
- GRUB_MOD_INIT(linux16)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- cmd_linux =
- grub_register_command ("linux", grub_cmd_linux,
- 0, N_("Load Linux."));
-@@ -504,6 +508,9 @@ GRUB_MOD_INIT(linux16)
-
- GRUB_MOD_FINI(linux16)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_command (cmd_linux);
- grub_unregister_command (cmd_linux16);
- grub_unregister_command (cmd_initrd);
-diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
-index facb13f3d36..47e481f4576 100644
---- a/grub-core/loader/multiboot.c
-+++ b/grub-core/loader/multiboot.c
-@@ -50,6 +50,7 @@
- #include
- #include
- #include
-+#include
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -444,6 +445,9 @@ static grub_command_t cmd_multiboot, cmd_module;
-
- GRUB_MOD_INIT(multiboot)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- cmd_multiboot =
- #ifdef GRUB_USE_MULTIBOOT2
- grub_register_command ("multiboot2", grub_cmd_multiboot,
-@@ -464,6 +468,9 @@ GRUB_MOD_INIT(multiboot)
-
- GRUB_MOD_FINI(multiboot)
- {
-+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
-+ return;
-+
- grub_unregister_command (cmd_multiboot);
- grub_unregister_command (cmd_module);
- }
-diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
-index 1c0cf6a430a..baa54e652ab 100644
---- a/grub-core/loader/xnu.c
-+++ b/grub-core/loader/xnu.c
-@@ -35,6 +35,7 @@
- #include
- #include
- #include