Project: Crossplane (Orchestration & Management / Scheduling & Orchestration)
File: ADA-fuzzing-audit-22.pdf

P R E S E N T S 
C r o s s p l a n e
F u z z i n g
A u d i t
In
collaboration
with
the
Crossplane
project
maintainers
and
The
Linux
Foundation
A u t h o r s
Adam
Korczynski
<
adam@adalogics.com
>
David
Korczynski
<
david@adalogics.com
>
Date:
23rd
March,
2023
This
report
is
licensed
under
Creative
Commons
4.0
(CC
BY
4.0)
Crossplane
fuzzing
audit
2022
C N C F
s e c u r i t y
a n d
f u z z i n g
a u d i t s
This
report
details
a
fuzzing
audit
commissioned
by
the
CNCF
and
the
engagement
is
part
of
the
broader
eﬀorts
carried
out
by
CNCF
in
securing
the
soware
in
the
CNCF
landscape.
Demonstrating
and
ensuring
the
security
of
these
soware
packages
is
vital
for
the
CNCF
ecosystem
and
the
CNCF
continues
to
use
state
of
the
art
techniques
to
secure
its
projects
as
well
as
carrying
out
manual
audits.
Over
the
last
handful
of
years,
CNCF
has
been
investing
in
security
audits,
fuzzing
and
soware
supply
chain
security
that
has
helped
proactively
discover
and
fix
hundreds
of
issues.
Fuzzing
is
a
proven
technique
for
finding
security
and
reliability
issues
in
soware
and
the
eﬀorts
so
far
have
enabled
fuzzing
integration
into
more
than
twenty
CNCF
projects
through
a
series
of
dedicated
fuzzing
audits.
In
total,
more
than
350
bugs
have
been
found
through
fuzzing
of
CNCF
projects.
The
fuzzing
eﬀorts
of
CNCF
have
focused
on
enabling
continuous
fuzzing
of
projects
to
ensure
continued
security
analysis,
which
is
done
by
way
of
the
open
source
fuzzing
project
OSS-Fuzz
1
.
CNCF
continues
work
in
this
space
and
will
further
increase
investment
to
improve
security
across
its
projects
and
community.
The
focus
for
future
work
is
integrating
fuzzing
into
more
projects,
enabling
sustainable
fuzzer
maintenance,
increasing
maintainer
involvement
and
enabling
fuzzing
to
find
more
vulnerabilities
in
memory
safe
languages.
Maintainers
who
are
interested
in
getting
fuzzing
integrated
into
their
projects
or
have
questions
about
fuzzing
are
encouraged
to
visit
the
dedicated
cncf-fuzzing
repository
https://github.com/cncf/cncf-fuzzing
where
questions
and
queries
are
welcome.
1
https://github.com/google/oss-fuzz
1Crossplane
fuzzing
audit
2022
Ex ecutive
summary
In
July
2022,
Ada
Logics
started
a
fuzzing
audit
of
Crossplane.
The
goal
of
the
audit
was
to
improve
Crossplanes
fuzzing
eﬀorts.
At
the
time
the
audit
started,
Crossplane
had
not
done
any
prior
fuzz
testing,
and
the
audit
began
with
integrating
Crossplane
into
OSS-Fuzz
-
Googles
open
source
project
that
runs
the
fuzzers
of
critical
open
source
projects
and
reports
issues
to
maintainers
if
the
fuzzers
detect
any.
Once
Crossplane
was
integrated
into
OSS-Fuzz,
Ada
Logics
began
assessing
Crossplanes
code
base
to
determine
which
entrypoints
the
fuzzers
should
target.
In
total
three
code
assets
were
tested
in
this
audit:
https://github.com/crossplane/crossplane:
The
core
Crossplane
repository.
https://github.com/crossplane/crossplane-runtime:
A
set
of
go
libraries
used
to
build
controllers
in
the
Crossplane
stack.
github.com/google/go-containerregistry:
A
3rd-party
dependency
that
handles 
complex
parsing
for
Crossplane
All
fuzzers
were
merged
into
the
cncf-fuzzing
repository,
https://github.com/cncf/cncf-fuzzing
,
from
which
OSS-Fuzz
would
pull
them
and
test
against
the
latest
master
branches
of
the
three
repositories
being
tested.
Ada
Logics
created
a
PR
for
CI
integration,
so
that
the
fuzzers
can
test
new
code
contributions
to
Crossplane:
https://github.com/crossplane/crossplane/pull/3553
.
The
audit
found
4
issues:
2
in
Crossplane
and
2
in
3rd-party
dependencies.
Results
summarised
13
fuzzers
written
for
Crossplane
4
issues
found
All
fuzzers
integrated
into
OSS-Fuzz
2
security
vulnerabilities
found
by
the
fuzzers
Fuzzers
supported
by
Crossplanes
CI
2Crossplane
fuzzing
audit
2022
T able
of
Contents
CNCF
security
and
fuzzing
audits
1
Executive
summary
2
Table
of
Contents
3
Project
Summary
4
Crossplane
fuzzing
5
Issues
found
by
fuzzers
10
Runtime
stats
19
Conclusions
and
future
work
20
3Crossplane
fuzzing
audit
2022
P r o j e c t
S u m m a r y
Ada
Logics
auditors
Name
Title
Email
Adam
Korczynski
Security
Engineer
Adam@adalogics.com
David
Korczynski
Security
Researcher
David@adalogics.com
Crossplane
maintainers
involved
in
the
audit
Name
Title
Email
Philippe
Scorsolini
Senior
Soware
Engineer
philippe.scorsolini@upbound.io
Jared
Watts
Steering
Committee
and 
Crossplane
Maintainer
jared@upbound.io
Alper
Ulucinar
Staﬀ
Soware
Engineer
alper@upbound.io
Nic
Cope
Crossplane
Steering 
Committee
negz@upbound.io
Assets
Url
Branch
https://github.com/crossplane/crossplanemaster
https://github.com/crossplane/crossplane-runtimemaster
https://github.com/google/go-containerregistrymain
4Crossplane
fuzzing
audit
2022
Crossplane
fuzzing
In
this
section
we
present
details
on
Crossplaneʼs
fuzzing
setup,
and
in
particular
the
overall
fuzzing
architecture
as
well
as
the
specific
fuzzers
developed.
Architecture
A
central
component
in
Crossplaneʼs
fuzzing
suite
is
continuous
fuzzing
by
way
of
OSS-Fuzz.
Crossplaneʼs
upstream
source
tree
is
the
key
soware
package
that
OSS-Fuzz
uses
to
fuzz
Crossplane.
The
following
figure
gives
an
overview
of
how
OSS-Fuzz
uses
Crossplaneʼs
upstream
repository
and
what
happens
when
an
issue
is
found/fixed.
Figure0.1:Crossplane’sfuzzingarchitecture
5
Crossplane
fuzzing
audit
2022
The
current
OSS-Fuzz
setup
builds
the
fuzzers
by
cloning
the
upstream
Crossplane
Github
repository
to
get
the
latest
Crossplane
source
code
and
then
builds
the
fuzzers
in
the
cloned
Crossplane
source
tree.
As
such,
the
fuzzers
are
always
run
against
the
latest
Crossplane
commit.
This
build
cycle
happens
daily
and
OSS-Fuzz
will
verify
if
any
existing
bugs
have
been
fixed.
If
OSS-fuzz
finds
that
any
bugs
have
been
fixed,
OSS-Fuzz
marks
the
crashes
as
fixed
in
the
Monorail
bug
tracker
and
notifies
the
Crossplane
maintainers.
In
each
fuzzing
iteration,
OSS-Fuzz
uses
its
corpus
accumulated
from
previous
fuzz
runs.
If
OSS-Fuzz
detects
any
crashes
when
running
the
fuzzers,
OSS-Fuzz
performs
the
following
actions:
1.
A
detailed
crash
report
is
created.
2.
An
issue
in
the
bug
tracker
is
created.
3.
An
email
is
sent
to
maintainers
with
links
to
the
report
and
relevant
entry
in
the
bug
tracker.
OSS-Fuzz
has
a
90
day
disclosure
policy,
meaning
that
a
bug
becomes
public
in
the
bug
tracker
if
it
has
not
been
fixed.
The
detailed
report
is
never
made
public.
The
Crossplane
maintainers
will
fix
issues
upstream,
and
OSS-Fuzz
will
pull
the
latest
Crossplane
master
branch
the
next
time
it
performs
a
fuzz
run
and
verify
that
a
given
issue
has
been
fixed.
Fuzzers
Ada
Logics
wrote
13
fuzzers
during
the
fuzzing
audit.
In
this
section
we
present
a
highlight
of
the
fuzzers
and
which
parts
of
Crossplane
they
test.
O v e r v i e w
#
Name
Package
1FuzzPatchApplygithub.com/crossplane/crossplane/internal/controller/apiextensions/composite
2FuzzTransformgithub.com/crossplane/crossplane/internal/controller/apiextensions/composite
3FuzzParsegithub.com/crossplane/crossplane/internal/xpkg
4FuzzPropagateConnectiongithub.com/crossplane/crossplane/internal/controller/apiextensions/claim
5FuzzNewCompositionRevisiongithub.com/crossplane/crossplane/internal/controller/apiextensions/composition
6FuzzAsCompositiongithub.com/crossplane/crossplane/internal/controller/apiextensions/composite
7FuzzPackageRevisiongithub.com/crossplane/crossplane/internal/controller/pkg/manager
8FuzzGCRExtract*github.com/crossplane/crossplane/internal/controller/pkg/revision
6Crossplane
fuzzing
audit
2022
9FuzzParseReference*github.com/crossplane/crossplane/internal/controller/pkg/revision
10FuzzForCompositeResourceXcrdgithub.com/crossplane/crossplane/internal/xcrd
11FuzzForCompositeResourceClaimgithub.com/crossplane/crossplane/internal/xcrd
12FuzzFindXpkgInDirgithub.com/crossplane/crossplane/internal/xpkg
13FuzzDaggithub.com/crossplane/crossplane/internal/dag
*
Removed
aer
the
audit.
T a r g e t
A P I s
1 :
F u z z P a t c h A p p l y
Invokesgithub.com/crossplane/crossplane/internal/controller/apiextensions/composite.Apply()
with
a
pseudo-randomizedPatch
and
two
mocked
types
asComposite
andComposed
respectively.
2 :
F u z z T r a n s f o r m
Creates
a
pseudo-randomizedgithub.com/crossplane/crossplane/apis/apiextensions/v1.Transform
and
passes
it
togithub.com/crossplane/crossplane/internal/controller/apiextensions/composite.Resolve()
together
with
a
pseudo-random
string
as
the
second
parameter.
3 :
F u z z P a r s e
Tests
the
Crossplane
Runtime
parser
with
aNopCloser
containing
the
testcase
from
the
fuzzer.
4 :
F u z z P r o p a g a t e C o n n e c t i o n
Testsgithub.com/crossplane/crossplane/internal/controller/apiextensions/claim.(a*APIConnectionPropagator).PropagateConnection()
.
The
fuzzer
creates
anAPIConnectionPropagator
with
a
mock
client
and
invokes
itsPropagateConnection()
method
with
a
pseudo-randomizedComposite
andComposed
.
5 :
F u z z N e w C o m p o s i t i o n R e v i s i o n
Invokesgithub.com/crossplane/crossplane/internal/controller/apiextensions/composition.NewCompositionRevision()
with
pseudo-randomizedrevision
andcompSpecHash
parameters.
6 :
F u z z A s C o m p o s i t i o n
Randomizes
agithub.com/crossplane/crossplane/apis/apiextensions/v1beta1.CompositionRevision
and
passes
it
to
7Crossplane
fuzzing
audit
2022
github.com/crossplane/crossplane/internal/controller/apiextensions/composite.AsComposition()
.
7 :
F u z z P a c k a g e R e v i s i o n
Has
two
targets:github.com/crossplane/crossplane/internal/controller/pkg/manager.(r*PackageRevisioner).Revision()
andgithub.com/crossplane/crossplane/internal/xpkg.FriendlyID()
.
To
invokeRevision()
,
the
fuzzer
creates
a*PackageRevisioner
with
a
mock
fetcher.
It
then
invokesRevision()
with
a
pseudo-randomizedgithub.com/crossplane/crossplane/apis/pkg/v1.Provider
.
Aer
that,
the
fuzzer
proceeds
to
creating
two
strings
and
passing
them
ontoFriendlyID()
.
8 :
F u z z G C R E x t r a c t *
Tests
the
3rd-party
API
used
by
Crossplane:github.com/google/go-containerregistry/pkg/v1/mutate.Extract()
.
The
fuzzer
creates
a
tar
file
that
it
then
passes
to
the
target
API
to
be
extracted.
9 :
F u z z P a r s e R e f e r e n c e *
Tests
the
3rd-party
API
used
by
Crossplane:github.com/google/go-containerregistry/pkg/name.ParseReference()
.
The
testcase
from
the
fuzzer
is
passed
to
the
target
API.
1 0 :
F u z z F o r C o m p o s i t e R e s o u r c e X c r d
Testsgithub.com/crossplane/crossplane/internal/xcrd.ForCompositeResourceXcrd()
by
creating
a
pseudo-randomgithub.com/crossplane/crossplane/apis/apiextensions/v1.CompositeResourceDefinition
and
passing
it
to
the
target
API.
1 1 :
F u z z F o r C o m p o s i t e R e s o u r c e C l a i m
Testsgithub.com/crossplane/crossplane/internal/xcrd.FuzzForCompositeResourceClaim()
by
creating
a
pseudo-randomgithub.com/crossplane/crossplane/apis/apiextensions/v1.CompositeResourceDefinition
and
passing
it
to
the
target
API.
1 2 :
F u z z F i n d X p k g I n D i r
The
goal
of
this
fuzzer
is
to
testgithub.com/crossplane/crossplane/internal/xpkg.FindXpkgInDir()
andgithub.com/crossplane/crossplane/internal/xpkg.ParseNameFromMeta()
.
The
fuzzer
prepares
agithub.com/spf13/afero.MemMapFs
and
creates
pseudo-random
files
in
it.
TheMemMapFs
is
then
passed
to
the
two
target
APIs
as
the
first
argument
and“/”
as
the
second.
8Crossplane
fuzzing
audit
2022
1 3 :
F u z z D a g
TestsMapDag
initialization
by
creating
a
slice
of
pseudo-random
nodes
and
passing
it
togithub.com/crossplane/crossplane/internal/dag.(d*MapDag).Init()
.
*
Removed
aer
the
audit.
9Crossplane
fuzzing
audit
2022
Issues
found
by
fuzzers
The
audit
resulted
in
4
unique
issues.
Some
of
these
were
reported
with
multiple
similar
crashes
by
OSS-Fuzz.
This
happens
for
several
reasons:
For
example,
changes
in
Crossplane
meant
that
a
crash
was
moved
from
one
place
to
another
in
the
codebase
causing
a
testcase
to
be
invalid
and
a
new
one
to
be
valid.
Ada
Logics
assessed
all
crashes
reported
by
OSS-Fuzz
and
have
only
included
the
unique
ones
in
this
report.
#
ID
Title
Severity
Fixed
1
ADA-CROSS-FUZZ-1
User-controlled
variable
determines
slice
size
High
Yes
2
ADA-CROSS-FUZZ-2
runtime.DefaultUnstructuredConverter.ToUnstructur 
ed
panics
if
if
a
pointer-typed
field
without 
omitempty
specifier
is
attempted
to
be
converted
Moderate
Yes
3
ADA-CROSS-FUZZ-3
Missing
slice
length
checks
causes
out
of
bounds 
read
Low
Yes
4
ADA-CROSS-FUZZ-4
Time
out
in
3rd-party
dependency
Moderate
Yes
The
most
interesting
finding
was
ADA-CROSS-FUZZ-1
which
was
a
bug
that
allowed
partially-trusted
users
to
control
the
size
of
allocated
memory
of
the
node
without
an
upper
limit.
The
issue
was
triaged
by
the
Crossplane
maintainers
and
was
assigned
assigned
CVEʼs
in
both
Crossplane
and
Crossplane-runtime:
Project
Github
Advisory
CVE
Crossplane
GHSA-v829-x6hh-cqfq
CVE-2023-27484
Crossplane-runtime
GHSA-vfvj-3m3g-m532
CVE-2023-27483
10Crossplane
fuzzing
audit
2022
1 :
U s e r - c o n t r o l l e d
v a r i a b l e
d e t e r m i n e s
s l i c e
s i z e
ID
ADA-CROSS-FUZZ-1
Severity
High
Fixed
Yes
FuzzerFuzzPatchApply
OSS-Fuzz
bug
tracker:
●
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49338&q=crossplane&can=1 
(expired)
●
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53819&q=crossplane&can=1
Description
Crossplane
runtime
attempts
to
create
a
slice
that
is
larger
than
the
memory
available.
The
size
of
the
slice
is
determined
by
input
controlled
by
the
fuzzer.
The
Crossplane
team
triaged
the
issue
and
found
that
it
was
security-critical
and
impacted
both
Crossplane
and
Crossplane-runtime.
They
requested
CVEʼs
for
both
projects:
Project
Github
Advisory
CVE
Crossplane
GHSA-v829-x6hh-cqfq
CVE-2023-27484
Crossplane-runtime
GHSA-vfvj-3m3g-m532
CVE-2023-27483
This
issue
existed
in
two
places
in
https://github.com/crossplane/crossplane-runtime/blob/master/pkg/fieldpath/paved.go
highlighted
below:
funcprepareElement(array[]any,current,nextSegment){//Ifthissegmentisnotthefinaloneanddoesn'texistweneedto//createitforournextsegment.ifarray[current.Index]==nil{switchnext.Type{caseSegmentIndex:array[current.Index]=make([]any,next.Index+1)caseSegmentField:array[current.Index]=make(map[string]any)}return}
//Ifournextsegmentindexesanarraythatexistsinourcurrentsegment's//elementwemustensurethearrayislongenoughtosetthenextsegment.ifnext.Type!=SegmentIndex{return
11Crossplane
fuzzing
audit
2022
}
na,ok:=array[current.Index].([]any)if!ok{return}
ifint(next.Index)<len(na){return}
array[current.Index]=append(na,make([]any,int(next.Index)-len(na)+1)...)}
funcprepareField(objectmap[string]any,current,nextSegment){//Ifthissegmentisnotthefinaloneanddoesn'texistweneedto//createitforournextsegment.if_,ok:=object[current.Field];!ok{switchnext.Type{caseSegmentIndex:object[current.Field]=make([]any,next.Index+1)caseSegmentField:object[current.Field]=make(map[string]any)}return}
//Ifournextsegmentindexesanarraythatexistsinourcurrentsegment's//fieldwemustensurethearrayislongenoughtosetthenextsegment.ifnext.Type!=SegmentIndex{return}
na,ok:=object[current.Field].([]any)if!ok{return}
ifint(next.Index)<len(na){return}
object[current.Field]=append(na,make([]any,int(next.Index)-len(na)+1)...)}
Stack
trace
fatal
error:
runtime:
out
of
memory
runtime
stack:
runtime.throw({0x26766c4?,
0x2430?})
runtime/panic.go:1047
+0x5f
fp=0x7ffe30995c50
sp=0x7ffe30995c20
pc=0x5a4edf
runtime.sysMapOS(0x10c001400000,
0x472800000?)
runtime/mem_linux.go:187
+0x11b
fp=0x7ffe30995c98
sp=0x7ffe30995c50
pc=0x586adb
runtime.sysMap(0x3fdfca0?,
0x7ff0e0300000?,
0x599fa0?)
runtime/mem.go:142
+0x35
fp=0x7ffe30995cc8
sp=0x7ffe30995c98
pc=0x5864b5
12Crossplane
fuzzing
audit
2022
runtime.(*mheap).grow(0x3fdfca0,
0x239374?)
runtime/mheap.go:1459
+0x23d
fp=0x7ffe30995d38
sp=0x7ffe30995cc8
pc=0x59705d
runtime.(*mheap).allocSpan(0x3fdfca0,
0x239374,
0x0,
0x0)
runtime/mheap.go:1 191
+0x1be
fp=0x7ffe30995dd0
sp=0x7ffe30995d38
pc=0x59679e
runtime.(*mheap).alloc.func1()
runtime/mheap.go:910
+0x65
fp=0x7ffe30995e18
sp=0x7ffe30995dd0
pc=0x596225
runtime.systemstack()
runtime/asm_amd64.s:492
+0x46
fp=0x7ffe30995e20
sp=0x7ffe30995e18
pc=0x5d3266
goroutine
17
[running,
locked
to
thread]:
runtime.systemstack_switch()
runtime/asm_amd64.s:459
fp=0x10c000da3628
sp=0x10c000da3620
pc=0x5d3200
runtime.(*mheap).alloc(0x4726e8000?,
0x239374?,
0x0?)
runtime/mheap.go:904
+0x65
fp=0x10c000da3670
sp=0x10c000da3628
pc=0x596165
runtime.(*mcache).allocLarge(0x455960?,
0x4726e7120,
0x0)
runtime/mcache.go:233
+0x85
fp=0x10c000da36c0
sp=0x10c000da3670
pc=0x585445
runtime.mallocgc(0x4726e7120,
0x29c9420,
0x1)
runtime/malloc.go:1029
+0x57e
fp=0x10c000da3738
sp=0x10c000da36c0
pc=0x57b69e
runtime.makeslice(0x29df3a0?,
0x10c000b4f590?,
0x10c000b38900?)
runtime/slice.go:103
+0x52
fp=0x10c000da3760
sp=0x10c000da3738
pc=0x5bb912
github.com/crossplane/crossplane-runtime/pkg/fieldpath.prepareField(0x10c000b5e1f8?,
{0x4?,
{0x10c000b38900?,
0x2951920?},
0x10c000b50fa0?},
{0x10c000da3930?,
{0x0?,
0x5742d8?},
0x10c000c0c1e0?})
github.com/crossplane/crossplane-runtime@v0.19.0-rc.0.0.20221 114195150-65044f043902/pkg/fieldpath/pav
ed.go:426
+0x59e
fp=0x10c000da3808
sp=0x10c000da3760
pc=0x25f7f3e
github.com/crossplane/crossplane-runtime/pkg/fieldpath.(*Paved).setV alue(0x10c0004acd60,
{0x10c000497180,
0x3,
0x4},
{0x0,
0x0})
github.com/crossplane/crossplane-runtime@v0.19.0-rc.0.0.20221 114195150-65044f043902/pkg/fieldpath/pav
ed.go:381
+0x6a5
fp=0x10c000da3970
sp=0x10c000da3808
pc=0x25f6de5
github.com/crossplane/crossplane-runtime/pkg/fieldpath.(*Paved).SetV alue(0x0?,
{0x10c000b38900,
0x60},
{0x0,
0x0})
github.com/crossplane/crossplane-runtime@v0.19.0-rc.0.0.20221 114195150-65044f043902/pkg/fieldpath/pav
ed.go:457
+0x1a5
fp=0x10c000da39f8
sp=0x10c000da3970
pc=0x25f8205
github.com/crossplane/crossplane-runtime/pkg/fieldpath.(*Paved).MergeV alue(0x2b73cb0?,
{0x10c000b38900,
0x60},
{0x0,
0x0},
0x0)
github.com/crossplane/crossplane-runtime@v0.19.0-rc.0.0.20221 114195150-65044f043902/pkg/fieldpath/mer
ge.go:47
+0x2eb
fp=0x10c000da3a60
sp=0x10c000da39f8
pc=0x25f2a8b
github.com/crossplane/crossplane/internal/controller/apiextensions/composite.patchFieldV alueToObject({0x10
c000b38900,
0x60},
{0x0,
0x0},
{0x2b73cb0?,
0x10c000b58ea0},
0x0?)
github.com/crossplane/crossplane/internal/controller/apiextensions/composite/merge.go:96
+0x152
fp=0x10c000da3ad8
sp=0x10c000da3a60
pc=0x261e3b2
github.com/crossplane/crossplane/internal/controller/apiextensions/composite.ApplyFromFieldPathPatch({{0x2
675bf0,
0x16},
0x10c000b50d40,
0x10c000b4f290,
0x10c000b50d60,
0x10c000b50d70,
{0x0,
0x0,
0x0},
0
x0},
...)
github.com/crossplane/crossplane/internal/controller/apiextensions/composite/patches.go:194
+0x62c
fp=0x10c000da3bc0
sp=0x10c000da3ad8
pc=0x261f f8c
github.com/crossplane/crossplane/internal/controller/apiextensions/composite.ApplyT oObjects({{0x2675bf0,
0x16},
0x10c000b50d40,
0x10c000b4f290,
0x10c000b50d60,
0x10c000b50d70,
{0x0,
0x0,
0x0},
0x0},
...)
github.com/crossplane/crossplane/internal/controller/apiextensions/composite/patches.go:85
+0xa38
fp=0x10c000da3cd8
sp=0x10c000da3bc0
pc=0x261ef98
github.com/crossplane/crossplane/internal/controller/apiextensions/composite.Apply(...)
github.com/crossplane/crossplane/internal/controller/apiextensions/composite/patches.go:71
13Crossplane
fuzzing
audit
2022
github.com/crossplane/crossplane/internal/controller/apiextensions/composite.FuzzPatchApply({0x60f0000231
d0,
0xa9,
0xa9})
Parameters
The
three
parameters
passed
to
Apply
are:
P a t c h
{"type":"FromCompositeFieldPath","fromFieldPath":"","combine":{"variables":[],"strategy":"","string":{"fmt":""}},"toFieldPath":"\u0000\u0004\u0000\ufffdB\ufffd\ufffd\ufffdterface\u0000\u0003\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000`\u0000\u0000\u0000\u0000**X[000000000000000001193731857]i\u0000\u0001\u001a\tn\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\t\u0000\u0000\u0000\u0000\u0000\u0000\u0000tefac","patchSetName":""}
C o m p o s i t e
{"creationTimestamp":null,"Policy":null,"To":null}
C o m p o s e d
{"creationTimestamp":null,"Ref":null,"To":null}
14Crossplane
fuzzing
audit
2022
2 :
r u n t i m e . D e f a u l t U n s t r u c t u r e d C o n v e r t e r . T o U n s t r u c t u r e d
p a n i c s
i f
i f
a
p o i n t e r - t y p e d
ﬁ e l d
w i t h o u t
o m i t e m p t y
s p e c i ﬁ e r
i s
a t t e m p t e d
t o
b e
c o n v e r t e d
ID
ADA-CROSS-FUZZ-2
Severity
Moderate
Fixed
Yes
FuzzerFuzzPatchApply
OSS-Fuzz
bug
tracker:
●
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50987
Description
TheFuzzPatchApply
fuzzer
found
that
ifresource.Composite
with
a
nil
connection
details
last
published
time
toPatch.Apply
,
subsequent
calls
toruntime.DefaultUnstructuredConverter.ToUnstructured
to
convert
it
to
anunstructured.Unstructured
will
panic.
The
issue
has
been
fixed
in
Crossplane
here:
https://github.com/crossplane/crossplane/pull/3394
and
here:
https://github.com/crossplane/crossplane-runtime/pull/361
,
and
an
upstream
PR
has
been
created
here:
https://github.com/kubernetes-sigs/structured-merge-diﬀ/issues/229
.
Credit
to
Alper
Rifat
Ulucinar
for
his
work
on
triaging
this
issue.
Stack
trace
panic:
value
method
k8s.io/apimachinery/pkg/apis/meta/v1.T ime.ToUnstructured
called
using
nil
*Time
pointer 
goroutine
17
[running,
locked
to
thread]: 
k8s.io/apimachinery/pkg/apis/meta/v1.(*T ime).ToUnstructured(0x100000001?) 
 <autogenerated>:1
+0x71 
sigs.k8s.io/structured-merge-dif f/v4/value.T ypeReflectCacheEntry .ToUnstructured({0x1,
0x0,
0x0,
0x0,
0x1, 
0x0,
0x0,
{0x0,
0x0,
0x0}},
...) 
 sigs.k8s.io/structured-merge-dif f/v4@v4.2.1/value/reflectcache.go:188
+0xa9a 
k8s.io/apimachinery/pkg/runtime.toUnstructured({0x1f3c540?,
0x10c00013b4e0?,
0x0?},
{0x1da6580?, 
0x10c0002b85b0?,
0x0?}) 
 k8s.io/apimachinery@v0.24.0/pkg/runtime/converter .go:655
+0x19a 
k8s.io/apimachinery/pkg/runtime.structT oUnstructured({0x1de9c00?,
0x10c00013b4e0?,
0x6305b0?}, 
{0x1da6580?,
0x10c0002b8570?,
0x10c000017668?}) 
 k8s.io/apimachinery@v0.24.0/pkg/runtime/converter .go:843
+0xb91 
k8s.io/apimachinery/pkg/runtime.toUnstructured({0x1de9c00?,
0x10c00013b4e0?,
0xa?},
{0x1da6580?, 
0x10c0002b8570?,
0x98?}) 
 k8s.io/apimachinery@v0.24.0/pkg/runtime/converter .go:692
+0x119f 
k8s.io/apimachinery/pkg/runtime.structT oUnstructured({0x1edae00?,
0x10c00013b380?,
0x1005c85e5?}, 
{0x1dbbe40?,
0x10c00012c688?,
0x0?}) 
 k8s.io/apimachinery@v0.24.0/pkg/runtime/converter .go:843
+0xb91 
k8s.io/apimachinery/pkg/runtime.toUnstructured({0x1edae00?,
0x10c00013b380?,
0x10c00013b380?}, 
{0x1dbbe40?,
0x10c00012c688?,
0x7f89fe5604d0?})
15Crossplane
fuzzing
audit
2022
 k8s.io/apimachinery@v0.24.0/pkg/runtime/converter .go:692
+0x119f 
k8s.io/apimachinery/pkg/runtime.(*unstructuredConverter).T oUnstructured(0x3337830,
{0x1f3acc0?, 
0x10c00013b380})
 k8s.io/apimachinery@v0.24.0/pkg/runtime/converter .go:586
+0x6f6 
github.com/crossplane/crossplane-runtime/pkg/fieldpath.PaveObject({0x1f48288?,
0x10c00013b380?}) 
 github.com/crossplane/crossplane-runtime@v0.18.0-rc.0.0.20220722162506-9ea84ae53615/pkg/fieldpath/p
aved.go:55
+0x52 
github.com/crossplane/crossplane/apis/apiextensions/v1.patchFieldV alueToObject({0x0,
0x0},
{0x0,
0x0}, 
{0x1f48288?,
0x10c00013b380},
0x0?) 
 github.com/crossplane/crossplane/apis/apiextensions/v1/composition_patches.go:199
+0x5d 
github.com/crossplane/crossplane/apis/apiextensions/v1.(*Patch).applyFromFieldPathPatch(0x10c00003d450,
{0x1f48260?,
0x10c0004677a0?},
{0x1f48288,
0x10c00013b380}) 
 github.com/crossplane/crossplane/apis/apiextensions/v1/composition_patches.go:253
+0x2e5 
github.com/crossplane/crossplane/apis/apiextensions/v1.(*Patch).Apply(0x10c00003d450,
{0x1f48260, 
0x10c0004677a0},
{0x1f48288,
0x10c00013b380},
{0x0,
0x0,
0x0?}) 
 github.com/crossplane/crossplane/apis/apiextensions/v1/composition_patches.go:129
+0x4a5 
github.com/crossplane/crossplane/apis/apiextensions/v1.FuzzPatchApply({0x603000001900,
0x16,
0x16}) 
 github.com/crossplane/crossplane/apis/apiextensions/v1/patch_fuzzer .go:84
+0x425
16Crossplane
fuzzing
audit
2022
3 :
M i s s i n g
s l i c e
l e n g t h
c h e c k s
c a u s e s
o u t
o f
b o u n d s
r e a d
ID
ADA-CROSS-FUZZ-3
Severity
Low
Fixed
Yes
FuzzerFuzzNewCompositionRevision
OSS-Fuzz
bug
tracker:
●
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53815
Description
NewCompositionRevision
reads
the
first
bytes
of
the
compSpecHash
without
checking
the
length
first.
If
the
compSpecHash
is
too
short,
an
out
of
bounds
read
panic
will
occur:
https://github.com/crossplane/crossplane/blob/8c77706ﬀ8b180b3bb4cd43920a8afce85dfe312/int
ernal/controller/apiextensions/composition/revision.go#L31-L53
funcNewCompositionRevision(c*v1.Composition,revisionint64,compSpecHashstring)*v1beta1.CompositionRevision{cr:=&v1beta1.CompositionRevision{ObjectMeta:metav1.ObjectMeta{Name:fmt.Sprintf("%s-%s",c.GetName(),compSpecHash[0:7]),Labels:map[string]string{v1beta1.LabelCompositionName:c.GetName(),//Wecannothavealabelvaluelongerthan63chars//https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-setv1beta1.LabelCompositionHash:compSpecHash[0:63],},},Spec:NewCompositionRevisionSpec(c.Spec,revision),}
ref:=meta.TypedReferenceTo(c,v1.CompositionGroupVersionKind)meta.AddOwnerReference(cr,meta.AsController(ref))
fork,v:=rangec.GetLabels(){cr.ObjectMeta.Labels[k]=v}
returncr}
17Crossplane
fuzzing
audit
2022
4 :
T i m e
o u t
i n
3 r d - p a r t y
d e p e n d e n c y
ID
ADA-CROSS-FUZZ-4
Severity
Moderate
Fixed
Yes
FuzzerFuzzParse
OSS-Fuzz
bug
tracker:
●
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49192
Description
FuzzParse
,
which
tests
a
3rd-party
parsing
routine,
found
that
a
particularly
well-craed
string
could
cause
the
parser
to
spend
excessive
time
on
a
single
request
invocation.
At
the
time
of
the
audit,
Crossplane
uses
thegithub.com/google/go-containerregistry/pkg/name.ParseReference()
the
following
places:
●
https://github.com/crossplane/crossplane/blob/master/internal/initializer/installer.go
●
https://github.com/crossplane/crossplane/blob/master/cmd/crank/update.go
●
https://github.com/crossplane/crossplane/blob/master/internal/controller/pkg/manager/r
evisioner.go
●
https://github.com/crossplane/crossplane/blob/master/cmd/crank/install.go
●
https://github.com/crossplane/crossplane/blob/master/internal/controller/pkg/revision/i
mageback.go
●
https://github.com/crossplane/crossplane/blob/master/internal/controller/pkg/revision/d
ependency.go
●
https://github.com/crossplane/crossplane/blob/master/internal/controller/pkg/resolver/r
econciler.go
18Crossplane
fuzzing
audit
2022
Runtime
stats
All
fuzzers
written
during
this
audit
were
added
ad-hoc
to
Crossplanes
OSS-Fuzz
integration.
OSS-Fuzz
ran
the
fuzzers
continuously
and
reported
the
issues
via
email
to
the
maintainers.
In
this
table
we
present
the
runtime
stats
as
of
the
30th
December
2022
for
each
fuzzer.
#
Name
Times
executed
Total
runtime
hours
1FuzzPatchApply11,337,642146.2
2FuzzTransform103,067,031373.2
3FuzzParse181,758,787411.3
4FuzzPropagateConnection538,134,219316.9
5FuzzNewCompositionRevision22,7560.3
6FuzzAsComposition394,622,293365.1
7FuzzPackageRevision458,470,899348.5
8FuzzGCRExtract1,062,095,023373.9
9FuzzParseReference343,394,432332.9
10FuzzForCompositeResource906,398,749309.6
11FuzzForCompositeResourceClaim1,220,542,269375.8
12FuzzFindXpkgInDir294,206,967380.3
13FuzzDag3,050,774,637378.9
19Crossplane
fuzzing
audit
2022
C o n c l u s i o n s
a n d
f u t u r e
w o r k
In
this
audit,
Ada
Logics
initiated
and
improved
crossplanes
fuzzing
eﬀorts.
The
eﬀorts
resulted
in
13
fuzzers,
4
issues
found
and
an
OSS-Fuzz
integration
with
support
for
continuous
testing
and
CI
integration.
4
issues
is
a
low
amount
for
a
fuzzing
audit,
and
credit
goes
to
the
Crossplane
team
for
developing
and
maintaining
a
high
level
of
code
quality
throughout
the
Crossplane
code
base.
Fuzzing
has
added
value
to
the
Crossplane
ecosystem
by
identifying
two
vulnerabilities
and
continued
testing
by
OSS-Fuzz.
Fuzzing
is
a
continuous
discipline,
and
we
recommend
that
Crossplane
takes
the
following
steps
moving
forward:
Maintaining
the
fuzzers
The
fuzzers
should
keep
running
without
breaking
to
keep
testing
the
code
for
harder-to-find
bugs
and
build
up
the
corpus.
Over
time,
Crossplanes
fuzzing
suite
will
improve
passively
from
new
features
in
fuzzing
as
the
industry
is
working
to
implement
new
bug
detectors
into
fuzzing.
These
will
be
added
in
a
non-intrusive
way,
meaning
that
as
long
as
Crossplanes
fuzzers
run
continuously,
they
will
over
time
test
for
more
classes
of
bugs.
Improve
coverage
We
recommend
making
it
a
continuous
eﬀort
to
identify
missing
test
coverage
of
the
fuzzers.
This
can
be
done
using
the
code
coverage
visualisations
provided
by
OSS-Fuzz.
Require
fuzzers
for
new
code
We
recommend
that
new
code
contributions
are
required
to
be
accompanied
by
fuzz
tests.
This
will
both
ensure
that
new
code
gets
tested
from
the
moment
it
gets
merged
into
Crossplane,
and
it
will
ensure
that
the
fuzzer
is
written
by
the
developer
itself.
We
thank
the
Linux
Foundation
for
sponsoring
this
project
as
well
as
the
team
at
Crossplane
for
a
fruitful
and
enjoyable
collaboration.
We
also
thank
the
maintainers
and
team
of
OSS-Fuzz
for
their
eﬀorts
in
making
open
source
fuzzing
possible
in
this
manner.
20