NetBSD Problem Report #60858
From www@netbsd.org Tue Oct 6 14:49:41 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 37A851A923B
for <gnats-bugs@gnats.NetBSD.org>; Tue, 6 Oct 2026 14:49:41 +0000 (UTC)
Message-Id: <20261006144939.7B81F1A923C@mollari.NetBSD.org>
Date: Tue, 6 Oct 2026 14:49:39 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: fortuitous embarrassment: fortify is all kinds of busted
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>
>Number: 60858
>Category: lib
>Synopsis: fortuitous embarrassment: fortify is all kinds of busted
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: needs-pullups
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 06 14:50:00 +0000 2026
>Closed-Date:
>Last-Modified: Mon Oct 19 18:35:01 +0000 2026
>Originator: Taylor R Campbell
>Release: current, 11, 10
>Organization:
__ssp_protected_bsd, inc.
>Environment:
>Description:
tl;dr:
1. NetBSD 10 ssp/fortify wrappers are broken by `static inline'
instead of `extern inline', causing function pointer
equality in library symbols to break (PR bin/45200: Scp
hangs after sending <https://gnats.NetBSD.org/45200>, worked
around locally and upstream but never properly fixed, and
recently rediscovered, when openssh-portable upstream
removed the workaround, as PR pkg/60563: exposed sshd w/o
password-login causes sshd-auth looping
<https://gnats.NetBSD.org/60563>).
2. NetBSD 11/current ssp/fortify wrappers may be broken by
creating symbol references that should not exist, and we are
now shipping symbols __ssp_protected_getcwd,
__ssp_protected_read, and __ssp_protected_readlink (which
are just trivial jump wrappers for getcwd/read/readlink) in
libc that should never have existed but can't be removed.
3. We are not actually building many things in base with
fortify despite having USE_FORT=yes in their Makefiles,
because putting that _after_ including bsd.own.mk has no
effect.
* Background
Under -D_FORTIFY_SOURCE=2, various libc functions that store
into a caller-provided buffer with caller-provided length are
wrapped with inline functions that check the caller-provided
length against any compile-time-known length. This way, for
instance, code like
uint8_t x[2];
read(fd, x, N);
gets runtime bounds checks as if it had been written like
uint8_t x[2];
if (N > sizeof(x))
__chk_fail();
read(fd, x, N);
If the size of x is not known, there is no impact. And taking
the address of the function read to pass a function pointer
around shouldn't be any different with or without
-D_FORTIFY_SOURCE=2.
* Issues
The mechanism of the wrappers, in src/include/ssp/ssp.h, has
changed over the years a little bit, but from NetBSD 6 through
NetBSD 10, it was essentially for <unistd.h> to add the
following declarations to declare an external C function
`__ssp_real_read' whose ELF symbol is `read', and an inline C
function `read' that does the check and calls the ELF symbol:
ssize_t __ssp_real_read(int, void *, size_t)
__RENAME(read);
static inline ssize_t read(int, void *, size_t)
__RENAME(__ssp_protected_read);
static inline ssize_t
read(int fd, void *buf, size_t len)
{
if (__builtin_object_size(buf) != (size_t)-1 &&
len > __builtin_object_size(buf))
__chk_fail();
return __ssp_real_read(fd, buf, len)
}
https://nxr.netbsd.org/xref/src/include/ssp/ssp.h?r=1.9#63
** Issue 1: static inline is wrong (applicable to netbsd-10)
Unfortunately, using `static inline' means that if you take the
address of `read' after the definition, _this definition_ gets
materialized as a distinct function from the library function
`read' -- and each .o file has its own distinct definition,
under symbols named __ssp_protected_read because of the middle
declaration above:
$ head a.c b.c main.c
==> a.c <==
#include <unistd.h>
void *read_a = read;
==> b.c <==
#include <unistd.h>
void *read_b = read;
==> main.c <==
#include <stdio.h>
extern void *read_a, *read_b;
int main(void) { return read_a == read_b; }
$ rm -f *.o && make a.o b.o main.o
cc -O2 -c a.c
cc -O2 -c b.c
cc -O2 -c main.c
$ cc -o test a.o b.o main.o && ./test; echo $?
1
$ rm -f *.o && make a.o b.o main.o CPPFLAGS=-D_FORTIFY_SOURCE=2
cc -O2 -D_FORTIFY_SOURCE=2 -c a.c
cc -O2 -D_FORTIFY_SOURCE=2 -c b.c
cc -O2 -D_FORTIFY_SOURCE=2 -c main.c
$ cc -o test a.o b.o main.o && ./test; echo $?
0
$ nm test | grep __ssp_protected_
000000000040096a t __ssp_protected_read
000000000040096f t __ssp_protected_read
Fortunately, it is relatively easy to search for _possible_
cases of the library function pointer equality problem by just
searching for the string `__ssp_protected_' in objdirs.
In 2023, `static inline' was replaced by `extern inline' in
response to PR lib/57689 (getcwd() not overridable with
-D_FORTIFY_SOURCE <https://gnats.NetBSD.org/57689>). That was
good: it meant that the inline wrapper would not be
materialized as a distinct function pointer when taking the
address of a library function like read().
** Issue 2: extern inline with __RENAME is wrong
However, we are still generating this declaration with a symbol
rename:
extern inline ssize_t read(int, void *, size_t)
__RENAME(__ssp_protected_read);
This causes the .o file to have a reference to an external
symbol __ssp_protected_read. It's not used for anything! It's
just required to be defined or else the program won't link, as
observed by prlw1@ in 2023:
=> Bootstrap dependency digest>=20211023: found digest-20220214
===> Checking for vulnerabilities in ffmpeg6-6.0nb6
===> Building for ffmpeg6-6.0nb6
LD ffmpeg6_g
LD ffprobe6_g
ld: /usr/lib/crt0.o and /usr/lib/crt0.o: warning: multiple common of `environ'
ld: /usr/lib/crt0.o and /usr/lib/crt0.o: warning: multiple common of `environ'
ld: libavdevice/libavdevice.so: undefined reference to `__ssp_protected_read'
ld: libavdevice/libavdevice.so: undefined reference to `__ssp_protected_read'
gmake: *** [Makefile:131: ffprobe6_g] Error 1
gmake: *** Waiting for unfinished jobs....
gmake: *** [Makefile:131: ffmpeg6_g] Error 1
*** Error code 2
https://mail-index.netbsd.org/pkgsrc-users/2023/11/13/msg038461.html
readelf(1) shows that the file has an undefined
__ssp_protected_read, even though it's not used by anything:
$ readelf -s a.o
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS a.c
2: 0000000000000000 8 OBJECT GLOBAL DEFAULT 4 read_a
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __ssp_protected_read
This happens only because of the spurious declaration of read()
with a symbol rename.
** Issue 3: fortify
Both fortuitously and embarrassingly, this library symbol
equality bug hasn't affected many programs in base by default
because although we explicitly enable USE_FORT=yes in many
Makefiles, it only takes effect if it happens _before_
bsd.own.mk -- because bsd.own.mk uses a `.if' conditional,
which does eager expansion, to define USE_SSP which is used to
decide whether to add -D_FORTIFY_SOURCE=2:
274 .if !defined(NOFORT) && ${USE_FORT:Uno} != "no"
275 USE_SSP?= yes
276 .endif
https://nxr.netbsd.org/xref/src/share/mk/bsd.own.mk?r=1.1487#274
181 .if !defined(NOSSP) && (${USE_SSP:Uno} != "no") && (${BINDIR:Ux} != "/usr/mdec")
182 . if !defined(KERNSRCDIR) && !defined(KERN) # not for kernels / kern modules
183 CPPFLAGS+= -D_FORTIFY_SOURCE=2
184 . endif
https://nxr.netbsd.org/xref/src/share/mk/bsd.sys.mk?r=1.319#181
So use cases like usr.bin/ftp/Makefile don't do anything:
4 .include <bsd.own.mk>
5
6 USE_FORT?= yes # network client
https://nxr.netbsd.org/xref/src/usr.bin/ftp/Makefile?r=1.46
You can verify this by showing all the variables:
$ nbmake-amd64 -v USE_FORT -v USE_SSP -v CPPFLAGS
yes
--sysroot=/home/riastradh/netbsd/current/src/../obj.amd64/destdir.amd64 -DWITH_SSL -DINET6
It's not because of the `?=' -- if USE_FORT?=yes is moved above
.include <bsd.own.mk>, it works:
$ nbmake-amd64 -v USE_FORT -v USE_SSP -v CPPFLAGS
yes
yes
--sysroot=/home/riastradh/netbsd/current/src/../obj.amd64/destdir.amd64 -DWITH_SSL -DINET6 -D_FORTIFY_SOURCE=2
>How-To-Repeat:
Please don't; this problem is pretty embarrassing!
>Fix:
1. In NetBSD 10: change `static inline' to `extern inline'.
(Won't help package builds against 10.0 -- unless the
builders patch their `10.0' trees, which won't create new
ABI issue (as long as the patch covers (2) below -- but will
help the base system...once (3) below is done too.)
2. In NetBSD 10/11/current: nix the
__RENAME(__ssp_protected_ ## fun) declaration.
3. In bsd.own.mk, use CFLAGS+= ${...:?...:...} for lazy
expansion instead of `.if ... CFLAGS+= ... .endif' for eager
expansion.
>Release-Note:
>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src
Date: Wed, 7 Oct 2026 00:51:18 +0000
Module Name: src
Committed By: riastradh
Date: Wed Oct 7 00:51:18 UTC 2026
Modified Files:
src/include/ssp: ssp.h
src/lib/libc/ssp: ssp_redirect.c
Log Message:
ssp.h: Stop creating references to useless __ssp_protected_* symbols.
The ssp wrappers are useful _only_ when they are actually used for
inline function call expansion; if the function is used for anything
else like a function pointer, only the underlying library symbol
should be used.
To pacify linker complaints about spurious references to
__ssp_protected_getcwd/read/readlink, we added equally spurious
definitions of those symbols to libc without understanding why; it
turns out it only happened because the ssp wrappers declared, e.g.:
extern inline read(...) __RENAME(__ssp_protected_read);
extern inline read(...) { <ssp check>; return __ssp_real_read(...); }
The declaration with __RENAME caused the compiler to generate
references, required by the linker to be resolved, to the symbol
`__ssp_protected_read' when compiling code that takes the address of
the function read() to pass around a function pointer. Instead, the
generated code should simply have a reference to the symbol `read',
which is what we achieve by deleting that declaration.
Now that the declaration is gone, we also need to redo the useless
ssp_redirect.c so that the getcwd/read/readlink definitions are
preceded by the appropriate prototypes. Rather than try to integrate
it into the ssp.h macrology, it is simpler to just define these three
wrappers explicitly here because the pattern has no value to
generalize; leave comments exhorting the reader never to extend it.
We can't simply delete the symbols, though, because programs built
against NetBSD 11 may rely on them (they won't _use_ the symbols in
code, but the ELF files might have symbol references that have to be
resolved).
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/include/ssp/ssp.h
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/ssp/ssp_redirect.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src/lib/libc
Date: Wed, 7 Oct 2026 00:51:26 +0000
Module Name: src
Committed By: riastradh
Date: Wed Oct 7 00:51:26 UTC 2026
Modified Files:
src/lib/libc: shlib_version
Log Message:
libc: Add a note to shlib_version about nixing __ssp_protected_*.
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.301 -r1.302 src/lib/libc/shlib_version
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src/share/mk
Date: Wed, 7 Oct 2026 00:59:11 +0000
Module Name: src
Committed By: riastradh
Date: Wed Oct 7 00:59:11 UTC 2026
Modified Files:
src/share/mk: bsd.own.mk
Log Message:
bsd.own.mk: Respect USE_FORT even if defined after bsd.own.mk.
Using (a chain of logic that boils down to)
.if ${USE_FORT:Uno} != "no"
CPPFLAGS+= -D_FORTIFY_SOURCE=2
.endif
expands USE_FORT eagerly, so if USE_FORT was not already defined before
including <bsd.own.mk>, it's too late after.
Using (a chain of logic that boils down to)
CPPFLAGS+= ${${USE_FORT:Uno} != "no":?-D_FORTIFY_SOURCE=2:}
expands USE_FORT lazily, so it's only when CPPFLAGS itself is expanded
-- usually in a recipe, after all variable assignments, prerequisite
lists, and .directives have been processed -- that USE_FORT is
expanded.
This way, all of the Makefiles that do
.include <bsd.own.mk>
USE_FORT?= yes
will actually get fortify as intended!
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.1487 -r1.1488 src/share/mk/bsd.own.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src/lib/libc
Date: Wed, 7 Oct 2026 22:22:03 +0000
Module Name: src
Committed By: riastradh
Date: Wed Oct 7 22:22:03 UTC 2026
Modified Files:
src/lib/libc: shlib_version
Log Message:
libc: Link to relevant PR in note about nixing __ssp_protected_*.
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.302 -r1.303 src/lib/libc/shlib_version
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->needs-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Thu, 08 Oct 2026 15:20:59 +0000
State-Changed-Why:
1. `static inline' -> `extern inline' needs pullup-10
2. removal of __ssp_protected_* needs pullup-11 and pullup-10
3. bsd.own.mk USE_FORT fix needs pullup-11 and pullup-10
State-Changed-From-To: needs-pullups->open
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Thu, 08 Oct 2026 16:34:11 +0000
State-Changed-Why:
Not fixed yet -- the bsd.own.mk broke ssp in kernel builds. Symptom:
/home/riastradh/netbsd/current/src/../obj.amd64/tooldir/bin/x86_64--netbsd-ld: chacha_sse2.o: in function `chacha_stream_sse2':
/home/riastradh/netbsd/current/src/sys/crypto/chacha/arch/x86/chacha_sse2.c:198:(.text+0x2b5): undefined reference to `__stack_chk_guard'
/home/riastradh/netbsd/current/src/../obj.amd64/tooldir/bin/x86_64--netbsd-ld: /home/riastradh/netbsd/current/src/sys/crypto/chacha/arch/x86/chacha_sse2.c:346:(.text+0xf11): undefined reference to `__stack_chk_guard'
/home/riastradh/netbsd/current/src/../obj.amd64/tooldir/bin/x86_64--netbsd-ld: /home/riastradh/netbsd/current/src/sys/crypto/chacha/arch/x86/chacha_sse2.c:346:(.text+0x1021): undefined reference to `__stack_chk_fail'
...in an update build. Clean builds will just not get SSP! See the
empty kern_ssp.o.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src
Date: Thu, 8 Oct 2026 19:11:10 +0000
Module Name: src
Committed By: riastradh
Date: Thu Oct 8 19:11:10 UTC 2026
Modified Files:
src/share/mk: bsd.own.mk
src/sys/arch/amd64/conf: Makefile.amd64
src/sys/arch/amd64/include: Makefile.inc
src/sys/arch/i386/conf: Makefile.i386
src/sys/arch/i386/include: Makefile.inc
src/sys/arch/sparc64/conf: Makefile.sparc64
src/sys/arch/xen/conf: Makefile.xen
src/sys/conf: ssp.mk
Log Message:
sys: Fix USE_SSP?=yes settings in amd64, i386, and sparc64 makefiles.
This was recently broken by the change in bsd.own.mk rev. 1.1488 to
fix USE_FORT?=yes after bsd.own.mk in userland makefiles, which
worked by unconditionally adding a conditional definition of USE_SSP
based on lazy expansion of USE_FORT, instead of conditionally adding
a conditional definition of USE_SSP based on eager expansion of
USE_FORT (confused yet?):
-.if ... ${USE_FORT:Uno} != "no" ...
-USE_SSP?= yes
-.endif
+USE_SSP?= ${... ${USE_FORT:Uno} != "no" ...:?yes:no}
This isolated (ha) change to bsd.own.mk saved the trouble of editing
dozens of userland makefiles to ensure that USE_FORT is defined
before bsd.own.mk -- and the trouble of adding diagnostics to detect
the mistake should it rear its head again. And it solved the problem
systematically for userland.
Unfortunately, the ordering of includes and definitions in the kernel
and module makefiles is a little different. To save the trouble of
rearranging them, we just have the kernel makefiles where SSP is on
by default say so by defining USE_SSP_DEFAULT=yes, which is picked up
by the new:
+USE_SSP?= ${... ${USE_FORT:Uno} ...:?yes:no}
+USE_SSP?= ${... ${USE_FORT:Uno} ...:?yes:${USE_SSP_DEFAULT:Uno}}
This mechanism still allows kernel configs to specify
makeoptions USE_SSP="no"
to override the architecture default, e.g. in i386 GENERIC_TINY.
In sys/conf/ssp.mk, change ${USE_SSP:Uno} to ${USE_SSP} so that if,
somehow, we lose the definition of USE_SSP, make(1) will fail noisily
rather than silently.
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.1488 -r1.1489 src/share/mk/bsd.own.mk
cvs rdiff -u -r1.86 -r1.87 src/sys/arch/amd64/conf/Makefile.amd64
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/amd64/include/Makefile.inc
cvs rdiff -u -r1.197 -r1.198 src/sys/arch/i386/conf/Makefile.i386
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/i386/include/Makefile.inc
cvs rdiff -u -r1.86 -r1.87 src/sys/arch/sparc64/conf/Makefile.sparc64
cvs rdiff -u -r1.50 -r1.51 src/sys/arch/xen/conf/Makefile.xen
cvs rdiff -u -r1.5 -r1.6 src/sys/conf/ssp.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src
Date: Thu, 8 Oct 2026 19:20:20 +0000
Module Name: src
Committed By: riastradh
Date: Thu Oct 8 19:20:20 UTC 2026
Modified Files:
src: UPDATING
Log Message:
UPDATING: Note fortification changes.
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.392 -r1.393 src/UPDATING
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src/sys/conf
Date: Fri, 9 Oct 2026 13:52:57 +0000
Module Name: src
Committed By: riastradh
Date: Fri Oct 9 13:52:57 UTC 2026
Modified Files:
src/sys/conf: ssp.mk
Log Message:
sys/conf/ssp.mk: Conditionalize use of USE_SSP on HAVE_SSP=yes.
Fixes the following failure after my previous change from
${USE_SSP:Uno} to ${USE_SSP} here so that make(1) would detect
failure to define USE_SSP -- which it did, for alpha, hppa, and ia64:
nbmake: /home/riastradh/netbsd/current/src/sys/conf/ssp.mk:3: Variable "USE_SSP" is undefined
in /home/riastradh/netbsd/current/src/sys/conf/Makefile.kern.inc:397
in /home/riastradh/netbsd/current/obj.hppa/sys/arch/hppa/compile/GENERIC/Makefile:1333
nbmake: Fatal errors encountered -- cannot continue
nbmake: stopped making "depend" in /home/riastradh/netbsd/current/obj.hppa/sys/arch/hppa/compile/GENERIC
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/conf/ssp.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->needs-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Fri, 09 Oct 2026 22:08:06 +0000
State-Changed-Why:
Fallout appears to have been fixed now.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60858 CVS commit: src/share/mk
Date: Mon, 19 Oct 2026 18:33:40 +0000
Module Name: src
Committed By: riastradh
Date: Mon Oct 19 18:33:40 UTC 2026
Modified Files:
src/share/mk: bsd.own.mk
Log Message:
hppa: Enable fortify/ssp in userland for progs/libs that opt into it.
The `ssp' part doesn't actually do much (and really I'm not sure why
these options are mixed together) because hppa stack grows up, so
writing past the end of an array won't overwrite the return address,
so stack smashing in this way is extremely unlikely. But the
`fortify' part, which instruments functions like memcpy/read/getcwd
with bounds checks where statically known, is still useful to catch
buffer overruns.
ok `I guess' nick@
PR lib/60858: fortuitous embarrassment: fortify is all kinds of busted
To generate a diff of this commit:
cvs rdiff -u -r1.1490 -r1.1491 src/share/mk/bsd.own.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.