Compare commits

..

51 Commits

Author SHA1 Message Date
Matt Johnston
0ea2e3463d try fix coverity build
--HG--
branch : coverity
2020-06-26 21:20:57 +08:00
Matt Johnston
ddb6751ab4 merge coverity from main
--HG--
branch : coverity
2020-06-26 21:07:34 +08:00
Matt Johnston
6e3c3c8c51 try for coverity
--HG--
branch : coverity
2019-03-21 23:28:59 +08:00
Matt Johnston
ef080502f8 merge coverity
--HG--
branch : coverity
2019-03-21 00:14:38 +08:00
Matt Johnston
fdbdbe5703 merge coverity
--HG--
branch : coverity
2018-03-21 00:52:02 +08:00
Matt Johnston
921592d37e merge coverity
--HG--
branch : coverity
2018-03-04 15:07:09 +08:00
Matt Johnston
04a02730bc merge coverity
--HG--
branch : coverity
2018-02-26 22:43:12 +08:00
Matt Johnston
dcce2cfd8d merge coverity
--HG--
branch : coverity
2018-02-19 23:14:49 +08:00
Matt Johnston
00a1290173 merge coverity up to date
--HG--
branch : coverity
2018-02-17 11:29:17 +08:00
Matt Johnston
a3a0b26581 limit travis branches
--HG--
branch : coverity
2018-02-10 19:06:13 +08:00
Matt Johnston
276197b404 merge
--HG--
branch : coverity
2018-02-10 19:03:54 +08:00
Matt Johnston
484d1e9b81 merge
--HG--
branch : coverity
2018-02-10 08:27:30 +08:00
Matt Johnston
278a3e43e5 merge
--HG--
branch : coverity
2018-02-09 23:58:47 +08:00
Matt Johnston
2df2117388 update coverity
--HG--
branch : coverity
2018-02-09 23:49:22 +08:00
Matt Johnston
187fc95deb merge
--HG--
branch : coverity
2017-06-24 23:33:16 +08:00
Matt Johnston
b75a033787 merge
--HG--
branch : coverity
2017-06-03 00:10:58 +08:00
Matt Johnston
423be0d5e6 merge coverity
--HG--
branch : coverity
2017-05-18 23:02:39 +08:00
Matt Johnston
68b3ef0734 merge coverity
--HG--
branch : coverity
2016-07-22 00:08:02 +08:00
Matt Johnston
d58e0497cc merge
--HG--
branch : coverity
2016-03-18 22:47:33 +08:00
Matt Johnston
af10eb8346 merge
--HG--
branch : coverity
2016-03-15 23:20:40 +08:00
Matt Johnston
8e93ac9925 merge up to date
--HG--
branch : coverity
2016-03-15 22:45:43 +08:00
Matt Johnston
6d5b27715a merge
--HG--
branch : coverity
2015-12-15 22:24:34 +08:00
Matt Johnston
f295fbe0b2 merge
--HG--
branch : coverity
2015-12-02 22:37:51 +08:00
Matt Johnston
575f0e5f92 merge
--HG--
branch : coverity
2015-11-23 23:04:48 +08:00
Matt Johnston
85374c5ba2 merge
--HG--
branch : coverity
2015-08-07 21:26:03 +08:00
Matt Johnston
83f3f55280 merge
--HG--
branch : coverity
2015-06-23 21:49:04 +08:00
Matt Johnston
b2beb2c2da coverity shouldn't have a matrix
--HG--
branch : coverity
2015-06-13 23:39:55 +08:00
Matt Johnston
48ad370a19 fix travis coverity matrix?
--HG--
branch : coverity
2015-06-13 23:36:03 +08:00
Matt Johnston
c36f94a322 fiddle with coverity travis
--HG--
branch : coverity
2015-06-13 23:32:15 +08:00
Matt Johnston
6493bbb7e7 merge up to date, attempt to fix travis.yml
--HG--
branch : coverity
2015-06-12 23:02:15 +08:00
Matt Johnston
3ec2737d54 merge main
--HG--
branch : coverity
2015-04-14 20:44:30 +08:00
Matt Johnston
72ccfda5b2 merge
--HG--
branch : coverity
2015-03-02 21:17:41 +08:00
Matt Johnston
003ec5d356 merge
--HG--
branch : coverity
2015-02-28 23:25:16 +08:00
Matt Johnston
f91d66448a merge
--HG--
branch : coverity
2015-02-24 22:48:34 +08:00
Matt Johnston
ccfdf7e039 merge
--HG--
branch : coverity
2015-02-10 21:47:43 +08:00
Matt Johnston
95ce05da40 merge
--HG--
branch : coverity
2015-01-28 22:49:55 +08:00
Matt Johnston
c5d53cf81c merge
--HG--
branch : coverity
2015-01-28 21:40:34 +08:00
Matt Johnston
5574460d25 merge
--HG--
branch : coverity
2015-01-04 22:33:12 +08:00
Matt Johnston
233fd96994 merge to coverity
--HG--
branch : coverity
2014-10-21 22:34:20 +08:00
Matt Johnston
d1b29336b1 merge
--HG--
branch : coverity
2014-08-19 23:36:46 +08:00
Matt Johnston
fa5eb62464 merge
--HG--
branch : coverity
2014-08-08 21:26:07 +08:00
Matt Johnston
0b48a4f879 merge
--HG--
branch : coverity
2014-07-28 23:38:54 +08:00
Matt Johnston
00ef081fcf merge
--HG--
branch : coverity
2014-07-28 22:56:07 +08:00
Matt Johnston
dabeaec461 merge
--HG--
branch : coverity
2014-07-26 10:23:53 +08:00
Matt Johnston
d4ed2fffe4 merge
--HG--
branch : coverity
2014-07-25 22:23:50 +08:00
Matt Johnston
0533b87b1a merge
--HG--
branch : coverity
2014-03-08 21:02:02 +08:00
Matt Johnston
7504cd1a1a Don't 'make install' for coverity
--HG--
branch : coverity
2014-03-08 21:00:32 +08:00
Matt Johnston
482dc0eff4 Fix the right build line
--HG--
branch : coverity
2014-03-08 18:16:11 +08:00
Matt Johnston
fc34d02427 Fix quoting for coverity
--HG--
branch : coverity
2014-03-08 18:09:00 +08:00
Matt Johnston
5ce5fbcba0 More for coverity
--HG--
branch : coverity
2014-03-08 16:56:15 +08:00
Matt Johnston
31d2311537 Add coverity bits
--HG--
branch : coverity
2014-03-08 14:56:27 +08:00
34 changed files with 208 additions and 451 deletions

View File

@@ -27,4 +27,3 @@ fd1981f41c626a969f07b4823848deaefef3c8aa 0 iQIcBAABCgAGBQJW4W2TAAoJEESTFJTynGdzu
07b0d56d186d7eeef4106137a3eba554959ba0e3 0 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

View File

@@ -59,4 +59,3 @@ c31276613181c5cff7854e7ef586ace03424e55e DROPBEAR_2017.75
6d1bbe7d5fa5827c7eae28bca044d691f7efa785 DROPBEAR_2019.77
009d52ae26d35f3381c801e02318fa9be34be93c DROPBEAR_2019.78
e2e4929d057b09422f2ea4556fb64209aff58161 DROPBEAR_2020.79
73646de50f1351735c868d4874f058ff9ad62c96 DROPBEAR_2020.80

View File

@@ -3,42 +3,17 @@ language: c
git:
depth: 3
# use focal which provides libtommath 1.20
dist: focal
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "F4rKQrHK/u58vPo3F9+x0WYXAeMFJvvtH9BIGZqx9yw8bUnL+gk0Ge9wnHHTXRcgCTqoc7B35uMS5njpH+Su/esVjrLAq85f/AmQctlRpmApwGK9LyxkIvx3UJN0nqfeeDXA90/8FUZ+n/qnCydXmYCEgqSaBCNydDxW1oqYUIc="
- BUNDLEDLIBTOM=--enable-bundled-libtom
- MULTI=1
matrix:
include:
- name: "plain linux"
compiler: gcc
env: WEXTRAFLAGS=-Werror
- name: "multi binary"
env: MULTI=1 WEXTRAFLAGS=-Werror
- name: "bundled libtom, xenial, no writev()"
# NOWRITEV is unrelated to libtom/xenial, test here to save a job
env: CONFIGURE_FLAGS=--enable-bundled-libtom WEXTRAFLAGS=-Werror NOWRITEV=1
# can use an older distro with bundled libtom
dist: xenial
- name: "linux clang"
os: linux
compiler: clang
env: WEXTRAFLAGS=-Werror
- name: "osx"
os: osx
compiler: clang
# OS X says daemon() and utmp are deprecated
env: WEXTRAFLAGS="-Wno-deprecated-declarations -Werror"
# Note: the fuzzing malloc wrapper doesn't replace free() in system libtomcrypt, so need bundled.
# Address sanitizer
- name: "fuzz-asan"
env: DO_FUZZ=1 CONFIGURE_FLAGS="--enable-fuzz --disable-harden --enable-bundled-libtom" WEXTRAFLAGS=-Werror LDFLAGS=-fsanitize=address EXTRACFLAGS=-fsanitize=address CXX=clang++
compiler: clang
# Undefined Behaviour sanitizer
- name: "fuzz-ubsan"
# don't fail with alignment due to https://github.com/libtom/libtomcrypt/issues/549
env: DO_FUZZ=1 CONFIGURE_FLAGS="--enable-fuzz --disable-harden --enable-bundled-libtom" WEXTRAFLAGS=-Werror LDFLAGS=-fsanitize=undefined EXTRACFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -fsanitize-recover=alignment" CXX=clang++
compiler: clang
before_install:
- echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
# container-based builds
addons:
apt:
packages:
@@ -46,33 +21,16 @@ addons:
- zlib1g-dev
- libtomcrypt-dev
- libtommath-dev
- mercurial
before_install:
- if [ "$CC" = "clang" ]; then WEXTRAFLAGS="$WEXTRAFLAGS -Wno-error=incompatible-library-redeclaration" ; fi # workaround
install:
- autoconf
- autoheader
- ./configure $CONFIGURE_FLAGS CFLAGS="-O2 -Wall -Wno-pointer-sign $WEXTRAFLAGS $EXTRACFLAGS" --prefix="$HOME/inst" || (cat config.log; exit 1)
- if [ "$NOWRITEV" = "1" ]; then sed -i -e s/HAVE_WRITEV/DONT_HAVE_WRITEV/ config.h ; fi
- make lint
- make -j3
- test -z $DO_FUZZ || make fuzzstandalone
# avoid concurrent install, osx/freebsd is racey (https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208093)
- make install
script:
- ~/inst/bin/dropbearkey -t rsa -f testrsa
- ~/inst/bin/dropbearkey -t dss -f testdss
- ~/inst/bin/dropbearkey -t ecdsa -f testec256 -s 256
- ~/inst/bin/dropbearkey -t ecdsa -f testec384 -s 384
- ~/inst/bin/dropbearkey -t ecdsa -f testec521 -s 521
- ~/inst/bin/dropbearkey -t ed25519 -f tested25519
- test -z $DO_FUZZ || ./fuzzers_test.sh
coverity_scan:
project:
name: "mkj/dropbear"
description: "Dropbear SSH"
notification_email: matt@ucc.asn.au
build_command_prepend: autoconf && autoheader && ./configure --enable-bundled-libtom CFLAGS='-O2 -Wall -Wno-pointer-sign' --prefix=$HOME/inst
build_command: make MULTI=1
branch_pattern: coverity
branches:
only:
- master
- coverity

41
CHANGES
View File

@@ -1,22 +1,3 @@
2020.81 - 29 October 2020
- Fix regression in 2020.79 which prevented connecting with some SSH
implementations. Increase MAX_PROPOSED_ALGO to 50, and print a log
message if the limit is hit. This fixes interoperability with sshj
library (used by PyCharm), and GoAnywhere.
Reported by Pirmin Walthert and Piotr Jurkiewicz
- Fix building with non-GCC compilers, reported by Kazuo Kuroi
- Fix potential long delay in dbclient, found by OSS Fuzz
- Fix null pointer dereference crash, found by OSS Fuzz
- libtommath now uses the same random source as Dropbear (in 2020.79
and 2020.80 used getrandom() separately)
- Some fuzzing improvements, start of a dbclient fuzzer
2020.80 - 26 June 2020
- Don't block authorized_keys logins with no-X11-forwarding or no-agent-forwarding
@@ -234,7 +215,7 @@
dropbear is running with -a (Allow connections to forwarded ports from any host)
This could potentially allow arbitrary code execution as root by an authenticated user.
Affects versions 2013.56 to 2016.74. Thanks to Mark Shepard for reporting the crash.
CVE-2017-9078 https://hg.ucc.asn.au/dropbear/rev/c8114a48837c
CVE-2017-9078 https://secure.ucc.asn.au/hg/dropbear/rev/c8114a48837c
- Security: Fix information disclosure with ~/.ssh/authorized_keys symlink.
Dropbear parsed authorized_keys as root, even if it were a symlink. The fix
@@ -246,7 +227,7 @@
contents of that file.
This information disclosure is to an already authenticated user.
Thanks to Jann Horn of Google Project Zero for reporting this.
CVE-2017-9079 https://hg.ucc.asn.au/dropbear/rev/0d889b068123
CVE-2017-9079 https://secure.ucc.asn.au/hg/dropbear/rev/0d889b068123
- Generate hostkeys with dropbearkey atomically and flush to disk with fsync
Thanks to Andrei Gherzan for a patch
@@ -266,23 +247,23 @@
run arbitrary code as the dbclient user. This could be a problem if scripts
or webpages pass untrusted input to the dbclient program.
CVE-2016-7406
https://hg.ucc.asn.au/dropbear/rev/b66a483f3dcb
https://secure.ucc.asn.au/hg/dropbear/rev/b66a483f3dcb
- Security: dropbearconvert import of OpenSSH keys could run arbitrary code as
the local dropbearconvert user when parsing malicious key files
CVE-2016-7407
https://hg.ucc.asn.au/dropbear/rev/34e6127ef02e
https://secure.ucc.asn.au/hg/dropbear/rev/34e6127ef02e
- Security: dbclient could run arbitrary code as the local dbclient user if
particular -m or -c arguments are provided. This could be an issue where
dbclient is used in scripts.
CVE-2016-7408
https://hg.ucc.asn.au/dropbear/rev/eed9376a4ad6
https://secure.ucc.asn.au/hg/dropbear/rev/eed9376a4ad6
- Security: dbclient or dropbear server could expose process memory to the
running user if compiled with DEBUG_TRACE and running with -v
CVE-2016-7409
https://hg.ucc.asn.au/dropbear/rev/6a14b1f6dc04
https://secure.ucc.asn.au/hg/dropbear/rev/6a14b1f6dc04
The security issues were reported by an anonymous researcher working with
Beyond Security's SecuriTeam Secure Disclosure www.beyondsecurity.com/ssd.html
@@ -328,7 +309,7 @@
- Validate X11 forwarding input. Could allow bypass of authorized_keys command= restrictions,
found by github.com/tintinweb. Thanks for Damien Miller for a patch. CVE-2016-3116
https://hg.ucc.asn.au/dropbear/rev/a3e8389e01ff
https://secure.ucc.asn.au/hg/dropbear/rev/a3e8389e01ff
2015.71 - 3 December 2015
@@ -609,11 +590,11 @@ kernels, from Steve Dover
- Limit the size of decompressed payloads, avoids memory exhaustion denial
of service
Thanks to Logan Lamb for reporting and investigating it. CVE-2013-4421
https://hg.ucc.asn.au/dropbear/rev/0bf76f54de6f
https://secure.ucc.asn.au/hg/dropbear/rev/0bf76f54de6f
- Avoid disclosing existence of valid users through inconsistent delays
Thanks to Logan Lamb for reporting. CVE-2013-4434
https://hg.ucc.asn.au/dropbear/rev/d7784616409a
https://secure.ucc.asn.au/hg/dropbear/rev/d7784616409a
- Update config.guess and config.sub for newer architectures
@@ -716,7 +697,7 @@ though probably will be soon
This bug affects releases 0.52 onwards. Ref CVE-2012-0920.
Thanks to Danny Fullerton of Mantor Organization for reporting
the bug.
https://hg.ucc.asn.au/dropbear/rev/818108bf7749
https://secure.ucc.asn.au/hg/dropbear/rev/818108bf7749
- Compile fix, only apply IPV6 socket options if they are available in headers
Thanks to Gustavo Zacarias for the patch
@@ -760,7 +741,7 @@ though probably will be soon
- New version numbering scheme.
Source repository has now migrated to Mercurial at
https://hg.ucc.asn.au/dropbear/graph/default
https://secure.ucc.asn.au/hg/dropbear/graph/default
0.53.1 - Wednesday 2 March 2011

View File

@@ -65,6 +65,7 @@ ifeq (@DROPBEAR_FUZZ@, 1)
allobjs = $(COMMONOBJS) fuzz-common.o fuzz-wrapfd.o $(CLISVROBJS) $(CLIOBJS) $(SVROBJS) @CRYPTLIB@
allobjs:=$(subst svr-main.o, ,$(allobjs))
allobjs:=$(subst cli-main.o, ,$(allobjs))
allobjs:=$(sort $(allobjs))
dropbearobjs=$(allobjs) svr-main.o
dbclientobjs=$(allobjs) cli-main.o
@@ -267,8 +268,7 @@ lint:
## Fuzzing targets
# list of fuzz targets
FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths \
fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths
FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519
FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS))
@@ -279,7 +279,10 @@ list-fuzz-targets:
fuzzstandalone: FUZZLIB=fuzz-harness.o
fuzzstandalone: fuzz-harness.o fuzz-targets
fuzz-harness.o: $(HEADERS) $(LIBTOM_DEPS) Makefile $(allobjs) fuzz-common.o
# exclude svr-main.o to avoid duplicate main
svrfuzzobjs=$(subst svr-main.o, ,$(dropbearobjs))
fuzz-harness.o: $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) fuzz-common.o
# build all the fuzzers. This will require fail to link unless built with
# make fuzz-targets FUZZLIB=-lFuzzer.a
@@ -287,31 +290,25 @@ fuzz-harness.o: $(HEADERS) $(LIBTOM_DEPS) Makefile $(allobjs) fuzz-common.o
fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS)
fuzzer-preauth: fuzzer-preauth.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-preauth_nomaths: fuzzer-preauth_nomaths.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-pubkey: fuzzer-pubkey.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-verify: fuzzer-verify.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-kexdh: fuzzer-kexdh.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-kexecdh: fuzzer-kexecdh.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-kexcurve25519: fuzzer-kexcurve25519.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-client: fuzzer-client.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-client_nomaths: fuzzer-client_nomaths.o fuzz-harness.o
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
fuzzer-%.options: Makefile
echo "[libfuzzer]" > $@
@@ -329,3 +326,8 @@ fuzz-hostkeys:
/usr/bin/xxd -i -a keye >> hostkeys.c
/usr/bin/xxd -i -a keyd >> hostkeys.c
/usr/bin/xxd -i -a keyed25519 >> hostkeys.c
# to make coverity happy?
test:
true

View File

@@ -39,30 +39,44 @@
/* Create (malloc) a new buffer of size */
buffer* buf_new(unsigned int size) {
buffer* buf;
if (size > BUF_MAX_SIZE) {
dropbear_exit("buf->size too big");
}
buf = (buffer*)m_malloc(sizeof(buffer)+size);
buf->data = (unsigned char*)buf + sizeof(buffer);
if (size > 0) {
buf->data = (unsigned char*)buf + sizeof(buffer);
} else {
buf->data = NULL;
}
buf->size = size;
return buf;
}
/* free the buffer's data and the buffer itself */
void buf_free(buffer* buf) {
m_free(buf);
}
/* overwrite the contents of the buffer to clear it */
void buf_burn(const buffer* buf) {
m_burn(buf->data, buf->size);
}
/* resize a buffer, pos and len will be repositioned if required when
* downsizing */
buffer* buf_resize(buffer *buf, unsigned int newsize) {
if (newsize > BUF_MAX_SIZE) {
dropbear_exit("buf->size too big");
}
@@ -125,23 +139,18 @@ void buf_incrwritepos(buffer* buf, unsigned int incr) {
}
}
/* increment the position by incr */
void buf_incrpos(buffer* buf, unsigned int incr) {
/* increment the position by incr, negative values are allowed, to
* decrement the pos*/
void buf_incrpos(buffer* buf, int incr) {
if (incr > BUF_MAX_INCR
|| (buf->pos + incr) > buf->len) {
|| incr < -BUF_MAX_INCR
|| (unsigned int)((int)buf->pos + incr) > buf->len
|| ((int)buf->pos + incr) < 0) {
dropbear_exit("Bad buf_incrpos");
}
buf->pos += incr;
}
/* decrement the position by decr */
void buf_decrpos(buffer* buf, unsigned int decr) {
if (decr > buf->pos) {
dropbear_exit("Bad buf_decrpos");
}
buf->pos -= decr;
}
/* Get a byte from the buffer and increment the pos */
unsigned char buf_getbyte(buffer* buf) {

View File

@@ -49,8 +49,7 @@ buffer* buf_newcopy(const buffer* buf);
void buf_setlen(buffer* buf, unsigned int len);
void buf_incrlen(buffer* buf, unsigned int incr);
void buf_setpos(buffer* buf, unsigned int pos);
void buf_incrpos(buffer* buf, unsigned int incr);
void buf_decrpos(buffer* buf, unsigned int decr);
void buf_incrpos(buffer* buf, int incr); /* -ve is ok, to go backwards */
void buf_incrwritepos(buffer* buf, unsigned int incr);
unsigned char buf_getbyte(buffer* buf);
unsigned char buf_getbool(buffer* buf);

View File

@@ -46,13 +46,6 @@ void send_msg_kexdh_init() {
TRACE(("send_msg_kexdh_init()"))
CHECKCLEARTOWRITE();
#if DROPBEAR_FUZZ
if (fuzz.fuzzing && fuzz.skip_kexmaths) {
return;
}
#endif
buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
switch (ses.newkeys->algo_kex->mode) {
#if DROPBEAR_NORMAL_DH
@@ -105,12 +98,6 @@ void recv_msg_kexdh_reply() {
unsigned char* keyblob = NULL;
TRACE(("enter recv_msg_kexdh_reply"))
#if DROPBEAR_FUZZ
if (fuzz.fuzzing && fuzz.skip_kexmaths) {
return;
}
#endif
if (cli_ses.kex_state != KEXDH_INIT_SENT) {
dropbear_exit("Received out-of-order kexdhreply");

View File

@@ -31,7 +31,9 @@
#include "dbrandom.h"
#include "crypto_desc.h"
#include "netio.h"
#include "fuzz.h"
static void cli_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN;
static void cli_dropbear_log(int priority, const char* format, va_list param);
#if DROPBEAR_CLI_PROXYCMD
static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out);
@@ -96,6 +98,58 @@ int main(int argc, char ** argv) {
}
#endif /* DBMULTI stuff */
static void cli_dropbear_exit(int exitcode, const char* format, va_list param) {
char exitmsg[150];
char fullmsg[300];
/* Note that exit message must be rendered before session cleanup */
/* Render the formatted exit message */
vsnprintf(exitmsg, sizeof(exitmsg), format, param);
TRACE(("Exited, cleaning up: %s", exitmsg))
/* Add the prefix depending on session/auth state */
if (!ses.init_done) {
snprintf(fullmsg, sizeof(fullmsg), "Exited: %s", exitmsg);
} else {
snprintf(fullmsg, sizeof(fullmsg),
"Connection to %s@%s:%s exited: %s",
cli_opts.username, cli_opts.remotehost,
cli_opts.remoteport, exitmsg);
}
/* Do the cleanup first, since then the terminal will be reset */
session_cleanup();
/* Avoid printing onwards from terminal cruft */
fprintf(stderr, "\n");
dropbear_log(LOG_INFO, "%s", fullmsg);
exit(exitcode);
}
static void cli_dropbear_log(int priority,
const char* format, va_list param) {
char printbuf[1024];
const char *name;
name = cli_opts.progname;
if (!name) {
name = "dbclient";
}
vsnprintf(printbuf, sizeof(printbuf), format, param);
#ifndef DISABLE_SYSLOG
if (opts.usingsyslog) {
syslog(priority, "%s", printbuf);
}
#endif
fprintf(stderr, "%s: %s\n", name, printbuf);
fflush(stderr);
}
static void exec_proxy_cmd(const void *user_data_cmd) {
const char *cmd = user_data_cmd;
char *usershell;
@@ -145,5 +199,4 @@ static void kill_proxy_sighandler(int UNUSED(signo)) {
kill_proxy_command();
_exit(1);
}
#endif /* DROPBEAR_CLI_PROXYCMD */

View File

@@ -352,11 +352,6 @@ static void cli_session_cleanup(void) {
(void)fcntl(cli_ses.stdoutcopy, F_SETFL, cli_ses.stdoutflags);
(void)fcntl(cli_ses.stderrcopy, F_SETFL, cli_ses.stderrflags);
/* Don't leak */
m_close(cli_ses.stdincopy);
m_close(cli_ses.stdoutcopy);
m_close(cli_ses.stderrcopy);
cli_tty_cleanup();
if (cli_ses.server_sig_algs) {
buf_free(cli_ses.server_sig_algs);
@@ -412,63 +407,3 @@ static void recv_msg_global_request_cli(void) {
/* Send a proper rejection */
send_msg_request_failure();
}
void cli_dropbear_exit(int exitcode, const char* format, va_list param) {
char exitmsg[150];
char fullmsg[300];
/* Note that exit message must be rendered before session cleanup */
/* Render the formatted exit message */
vsnprintf(exitmsg, sizeof(exitmsg), format, param);
TRACE(("Exited, cleaning up: %s", exitmsg))
/* Add the prefix depending on session/auth state */
if (!ses.init_done) {
snprintf(fullmsg, sizeof(fullmsg), "Exited: %s", exitmsg);
} else {
snprintf(fullmsg, sizeof(fullmsg),
"Connection to %s@%s:%s exited: %s",
cli_opts.username, cli_opts.remotehost,
cli_opts.remoteport, exitmsg);
}
/* Do the cleanup first, since then the terminal will be reset */
session_cleanup();
#if DROPBEAR_FUZZ
if (fuzz.do_jmp) {
longjmp(fuzz.jmp, 1);
}
#endif
/* Avoid printing onwards from terminal cruft */
fprintf(stderr, "\n");
dropbear_log(LOG_INFO, "%s", fullmsg);
exit(exitcode);
}
void cli_dropbear_log(int priority, const char* format, va_list param) {
char printbuf[1024];
const char *name;
name = cli_opts.progname;
if (!name) {
name = "dbclient";
}
vsnprintf(printbuf, sizeof(printbuf), format, param);
#ifndef DISABLE_SYSLOG
if (opts.usingsyslog) {
syslog(priority, "%s", printbuf);
}
#endif
fprintf(stderr, "%s: %s\n", name, printbuf);
fflush(stderr);
}

View File

@@ -381,7 +381,7 @@ static void get_algolist(char* algolist, unsigned int algolist_len,
}
if (algolist_len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
*ret_count = 0;
}
}
/* ret_list will contain a list of the strings parsed out.
We will have at least one string (even if it's just "") */
@@ -392,11 +392,11 @@ static void get_algolist(char* algolist, unsigned int algolist_len,
/* someone is trying something strange */
*ret_count = 0;
return;
}
}
if (algolist[i] == ',') {
if (*ret_count >= max_count) {
dropbear_exit("Too many remote algorithms");
/* Too many */
*ret_count = 0;
return;
}

View File

@@ -487,12 +487,6 @@ void recv_msg_kexinit() {
TRACE(("continue recv_msg_kexinit: sent kexinit"))
}
/* "Once a party has sent a SSH_MSG_KEXINIT message ...
further SSH_MSG_KEXINIT messages MUST NOT be sent" */
if (ses.kexstate.recvkexinit) {
dropbear_exit("Unexpected KEXINIT");
}
/* start the kex hash */
local_ident_len = strlen(LOCAL_IDENT);
remote_ident_len = strlen(ses.remoteident);

View File

@@ -465,11 +465,6 @@ static int ident_readln(int fd, char* buf, int count) {
TRACE(("leave ident_readln: EOF"))
return -1;
}
#if DROPBEAR_FUZZ
fuzz_dump(&in, 1);
#endif
if (in == '\n') {
/* end of ident string */
break;

View File

@@ -3,18 +3,11 @@
#include "crypto_desc.h"
#include "ltc_prng.h"
#include "ecc.h"
#include "dbrandom.h"
#if DROPBEAR_LTC_PRNG
int dropbear_ltc_prng = -1;
#endif
/* Wrapper for libtommath */
static mp_err dropbear_rand_source(void* out, size_t size) {
genrandom((unsigned char*)out, (unsigned int)size);
return MP_OKAY;
}
/* Register the compiled in ciphers.
* This should be run before using any of the ciphers/hashes */
@@ -74,8 +67,6 @@ void crypto_init() {
}
#endif
mp_rand_source(dropbear_rand_source);
#if DROPBEAR_ECC
ltc_mp = ltm_desc;
dropbear_ecc_fill_dp();

View File

@@ -121,6 +121,7 @@ static void generic_dropbear_exit(int exitcode, const char* format,
_dropbear_log(LOG_INFO, fmtbuf, param);
#if DROPBEAR_FUZZ
/* longjmp before cleaning up svr_opts */
if (fuzz.do_jmp) {
longjmp(fuzz.jmp, 1);
}
@@ -257,12 +258,6 @@ int spawn_command(void(*exec_fn)(const void *user_data), const void *exec_data,
const int FDIN = 0;
const int FDOUT = 1;
#if DROPBEAR_FUZZ
if (fuzz.fuzzing) {
return fuzz_spawn_command(ret_writefd, ret_readfd, ret_errfd, ret_pid);
}
#endif
/* redirect stdin/stdout/stderr */
if (pipe(infds) != 0) {
return DROPBEAR_FAILURE;

12
debian/changelog vendored
View File

@@ -1,15 +1,3 @@
dropbear (2020.81-0.1) unstable; urgency=low
* New upstream release.
-- Matt Johnston <matt@ucc.asn.au> Thu, 29 Oct 2020 22:51:57 +0800
dropbear (2020.80-0.1) unstable; urgency=low
* New upstream release.
-- Matt Johnston <matt@ucc.asn.au> Fri, 26 Jun 2020 22:51:57 +0800
dropbear (2020.79-0.1) unstable; urgency=low
* New upstream release.

View File

@@ -8,17 +8,14 @@
#include "session.h"
#include "dbrandom.h"
#include "bignum.h"
#include "atomicio.h"
#include "fuzz-wrapfd.h"
struct dropbear_fuzz_options fuzz;
static void fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list param);
static void load_fixed_hostkeys(void);
static void load_fixed_client_key(void);
void fuzz_common_setup(void) {
disallow_core();
fuzz.fuzzing = 1;
fuzz.wrapfds = 1;
fuzz.do_jmp = 1;
@@ -39,8 +36,7 @@ int fuzz_set_input(const uint8_t *Data, size_t Size) {
memset(&ses, 0x0, sizeof(ses));
memset(&svr_ses, 0x0, sizeof(svr_ses));
memset(&cli_ses, 0x0, sizeof(cli_ses));
wrapfd_setup(fuzz.input);
wrapfd_setup();
fuzz_seed();
@@ -67,58 +63,23 @@ void fuzz_svr_setup(void) {
_dropbear_exit = svr_dropbear_exit;
char *argv[] = {
"dropbear",
"-E",
};
int argc = sizeof(argv) / sizeof(*argv);
svr_getopts(argc, argv);
/* user lookups might be slow, cache it */
fuzz.pw_name = m_strdup("person");
fuzz.pw_dir = m_strdup("/tmp");
fuzz.pw_shell = m_strdup("/bin/zsh");
fuzz.pw_passwd = m_strdup("!!zzznope");
load_fixed_hostkeys();
}
void fuzz_cli_setup(void) {
fuzz_common_setup();
_dropbear_exit = cli_dropbear_exit;
_dropbear_log = cli_dropbear_log;
char *argv[] = {
"dbclient",
"-y",
"localhost",
"uptime"
};
int argc = sizeof(argv) / sizeof(*argv);
cli_getopts(argc, argv);
load_fixed_client_key();
/* Avoid password prompt */
setenv(DROPBEAR_PASSWORD_ENV, "password", 1);
}
#include "fuzz-hostkeys.c"
static void load_fixed_client_key(void) {
buffer *b = buf_new(3000);
sign_key *key;
enum signkey_type keytype;
key = new_sign_key();
keytype = DROPBEAR_SIGNKEY_ANY;
buf_putbytes(b, keyed25519, keyed25519_len);
buf_setpos(b, 0);
if (buf_get_priv_key(b, key, &keytype) == DROPBEAR_FAILURE) {
dropbear_exit("failed fixed ed25519 hostkey");
}
list_append(cli_opts.privkeys, key);
buf_free(b);
}
static void load_fixed_hostkeys(void) {
#include "fuzz-hostkeys.c"
buffer *b = buf_new(3000);
enum signkey_type type;
@@ -190,17 +151,6 @@ void fuzz_fake_send_kexdh_reply(void) {
finish_kexhashbuf();
}
/* fake version of spawn_command() */
int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) {
*ret_writefd = wrapfd_new();
*ret_readfd = wrapfd_new();
if (ret_errfd) {
*ret_errfd = wrapfd_new();
}
*ret_pid = 999;
return DROPBEAR_SUCCESS;
}
int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
static int once = 0;
if (!once) {
@@ -214,7 +164,7 @@ int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
}
/*
get prefix, allowing for future extensibility. input format is
get prefix. input format is
string prefix
uint32 wrapfd seed
... to be extended later
@@ -232,7 +182,8 @@ int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
uint32_t wrapseed = buf_getint(fuzz.input);
wrapfd_setseed(wrapseed);
int fakesock = wrapfd_new();
int fakesock = 20;
wrapfd_add(fakesock, fuzz.input, PLAIN);
m_malloc_set_epoch(1);
if (setjmp(fuzz.jmp) == 0) {
@@ -247,52 +198,6 @@ int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
return 0;
}
int fuzz_run_client(const uint8_t *Data, size_t Size, int skip_kexmaths) {
static int once = 0;
if (!once) {
fuzz_cli_setup();
fuzz.skip_kexmaths = skip_kexmaths;
once = 1;
}
if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
return 0;
}
/*
get prefix, allowing for future extensibility. input format is
string prefix
uint32 wrapfd seed
... to be extended later
[bytes] ssh input stream
*/
/* be careful to avoid triggering buffer.c assertions */
if (fuzz.input->len < 8) {
return 0;
}
size_t prefix_size = buf_getint(fuzz.input);
if (prefix_size != 4) {
return 0;
}
uint32_t wrapseed = buf_getint(fuzz.input);
wrapfd_setseed(wrapseed);
int fakesock = wrapfd_new();
m_malloc_set_epoch(1);
if (setjmp(fuzz.jmp) == 0) {
cli_session(fakesock, fakesock, NULL, 0);
m_malloc_free_epoch(1, 0);
} else {
m_malloc_free_epoch(1, 1);
TRACE(("dropbear_exit longjmped"))
/* dropbear_exit jumped here */
}
return 0;
}
const void* fuzz_get_algo(const algo_type *algos, const char* name) {
const algo_type *t;
for (t = algos; t->name; t++) {
@@ -302,10 +207,3 @@ const void* fuzz_get_algo(const algo_type *algos, const char* name) {
}
assert(0);
}
void fuzz_dump(const unsigned char* data, size_t len) {
TRACE(("dump %zu", len))
if (fuzz.dumping) {
assert(atomicio(vwrite, fuzz.recv_dumpfd, (void*)data, len) == len);
}
}

View File

@@ -9,6 +9,7 @@ int main(int argc, char ** argv) {
buffer *input = buf_new(100000);
for (i = 1; i < argc; i++) {
printf("arg %s\n", argv[i]);
#if DEBUG_TRACE
if (strcmp(argv[i], "-v") == 0) {
debug_trace = 1;
@@ -29,7 +30,6 @@ int main(int argc, char ** argv) {
buf_readfile(input, fn);
buf_setpos(input, 0);
/* Run twice to catch problems with statefulness */
fuzz.wrapfds = old_fuzz_wrapfds;
printf("Running %s once \n", fn);
LLVMFuzzerTestOneInput(input->data, input->len);

View File

@@ -1,6 +1,5 @@
/* To be included in fuzz-common.c */
static unsigned char keyr[] = {
unsigned char keyr[] = {
0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00,
0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0xb1,
0x06, 0x95, 0xc9, 0xa8, 0x38, 0xb9, 0x99, 0x91, 0xb5, 0x17, 0x39, 0xb9,
@@ -70,8 +69,8 @@ static unsigned char keyr[] = {
0xb0, 0x9b, 0xea, 0x18, 0x77, 0xf6, 0x25, 0x02, 0xb4, 0x5e, 0x71, 0xea,
0xa3
};
static unsigned int keyr_len = 805;
static unsigned char keye[] = {
unsigned int keyr_len = 805;
unsigned char keye[] = {
0x00, 0x00, 0x00, 0x13, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2d, 0x73, 0x68,
0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35, 0x36, 0x00,
0x00, 0x00, 0x08, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35, 0x36, 0x00,
@@ -85,8 +84,8 @@ static unsigned char keye[] = {
0x3c, 0x58, 0x28, 0x70, 0x9b, 0x23, 0x39, 0x51, 0xd7, 0xbc, 0xa7, 0x1a,
0xf5, 0xb4, 0x23, 0xd3, 0xf6, 0x17, 0xa6, 0x9c, 0x02
};
static unsigned int keye_len = 141;
static unsigned char keyd[] = {
unsigned int keye_len = 141;
unsigned char keyd[] = {
0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x64, 0x73, 0x73, 0x00,
0x00, 0x00, 0x81, 0x00, 0xb0, 0x02, 0x19, 0x8b, 0xf3, 0x46, 0xf9, 0xc5,
0x47, 0x78, 0x3d, 0x7f, 0x04, 0x10, 0x0a, 0x43, 0x8e, 0x00, 0x9e, 0xa4,
@@ -127,8 +126,8 @@ static unsigned char keyd[] = {
0x7b, 0xac, 0xaa, 0x0c, 0xa2, 0xca, 0x7b, 0xa8, 0xd4, 0xdf, 0x68, 0x56,
0xf9, 0x39
};
static unsigned int keyd_len = 458;
static unsigned char keyed25519[] = {
unsigned int keyd_len = 458;
unsigned char keyed25519[] = {
0x00, 0x00, 0x00, 0x0b, 0x73, 0x73, 0x68, 0x2d, 0x65, 0x64, 0x32, 0x35,
0x35, 0x31, 0x39, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb3, 0x79, 0x06, 0xe5,
0x9b, 0xe7, 0xe4, 0x6e, 0xec, 0xfe, 0xa5, 0x39, 0x21, 0x7c, 0xf6, 0x66,
@@ -137,4 +136,4 @@ static unsigned char keyed25519[] = {
0xa4, 0xd5, 0xe9, 0x23, 0xfe, 0x8e, 0xd6, 0xd4, 0xf9, 0xb1, 0x11, 0x69,
0x7c, 0x57, 0x52, 0x0e, 0x41, 0xdb, 0x1b, 0x12, 0x87, 0xfa, 0xc9
};
static unsigned int keyed25519_len = 83;
unsigned int keyed25519_len = 83;

View File

@@ -17,33 +17,25 @@ static const double CHANCE_WRITE2 = 0.5;
struct fdwrap {
enum wrapfd_mode mode;
buffer *buf;
int closein;
int closeout;
};
static struct fdwrap wrap_fds[IOWRAP_MAXFD+1] = {{UNUSED, 0, 0}};
static int wrapfd_maxfd = -1;
static struct fdwrap wrap_fds[IOWRAP_MAXFD+1];
/* for quick selection of in-use descriptors */
static int wrap_used[IOWRAP_MAXFD+1];
static unsigned int nused;
static unsigned short rand_state[3];
static buffer *input_buf;
static int devnull_fd = -1;
static void wrapfd_remove(int fd);
void wrapfd_setup(buffer *buf) {
void wrapfd_setup(void) {
TRACE(("wrapfd_setup"))
// clean old ones
int i;
for (i = 0; i <= wrapfd_maxfd; i++) {
if (wrap_fds[i].mode == COMMONBUF) {
wrapfd_remove(i);
}
}
wrapfd_maxfd = -1;
nused = 0;
memset(wrap_fds, 0x0, sizeof(wrap_fds));
memset(wrap_used, 0x0, sizeof(wrap_used));
memset(rand_state, 0x0, sizeof(rand_state));
wrapfd_setseed(50);
input_buf = buf;
}
void wrapfd_setseed(uint32_t seed) {
@@ -51,30 +43,39 @@ void wrapfd_setseed(uint32_t seed) {
nrand48(rand_state);
}
int wrapfd_new() {
if (devnull_fd == -1) {
devnull_fd = open("/dev/null", O_RDONLY);
assert(devnull_fd != -1);
}
int fd = dup(devnull_fd);
assert(fd != -1);
void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) {
TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode))
assert(fd >= 0);
assert(fd <= IOWRAP_MAXFD);
assert(wrap_fds[fd].mode == UNUSED);
wrap_fds[fd].mode = COMMONBUF;
assert(buf || mode == RANDOMIN);
wrap_fds[fd].mode = mode;
wrap_fds[fd].buf = buf;
wrap_fds[fd].closein = 0;
wrap_fds[fd].closeout = 0;
wrapfd_maxfd = MAX(fd, wrapfd_maxfd);
wrap_used[nused] = fd;
return fd;
nused++;
}
static void wrapfd_remove(int fd) {
void wrapfd_remove(int fd) {
unsigned int i, j;
TRACE(("wrapfd_remove %d", fd))
assert(fd >= 0);
assert(fd <= IOWRAP_MAXFD);
assert(wrap_fds[fd].mode != UNUSED);
wrap_fds[fd].mode = UNUSED;
m_close(fd);
/* remove from used list */
for (i = 0, j = 0; i < nused; i++) {
if (wrap_used[i] != fd) {
wrap_used[j] = wrap_used[i];
j++;
}
}
nused--;
}
int wrapfd_close(int fd) {
@@ -88,6 +89,7 @@ int wrapfd_close(int fd) {
int wrapfd_read(int fd, void *out, size_t count) {
size_t maxread;
buffer *buf;
if (!fuzz.wrapfds) {
return read(fd, out, count);
@@ -113,14 +115,15 @@ int wrapfd_read(int fd, void *out, size_t count) {
return -1;
}
if (input_buf) {
maxread = MIN(input_buf->len - input_buf->pos, count);
buf = wrap_fds[fd].buf;
if (buf) {
maxread = MIN(buf->len - buf->pos, count);
/* returns 0 if buf is EOF, as intended */
if (maxread > 0) {
maxread = nrand48(rand_state) % maxread + 1;
}
memcpy(out, buf_getptr(input_buf, maxread), maxread);
buf_incrpos(input_buf, maxread);
memcpy(out, buf_getptr(buf, maxread), maxread);
buf_incrpos(buf, maxread);
return maxread;
}
@@ -172,6 +175,8 @@ int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds,
int ret = 0;
int fdlist[IOWRAP_MAXFD+1];
memset(fdlist, 0x0, sizeof(fdlist));
if (!fuzz.wrapfds) {
return select(nfds, readfds, writefds, exceptfds, timeout);
}

View File

@@ -5,13 +5,15 @@
enum wrapfd_mode {
UNUSED = 0,
COMMONBUF, // using the common buffer
PLAIN,
INPROGRESS,
RANDOMIN
};
// buf is a common buffer read by all wrapped FDs. doesn't take ownership of buf
void wrapfd_setup(buffer *buf);
void wrapfd_setup(void);
void wrapfd_setseed(uint32_t seed);
int wrapfd_new();
// doesn't take ownership of buf. buf is optional.
void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode);
// called via #defines for read/write/select
int wrapfd_read(int fd, void *out, size_t count);

17
fuzz.h
View File

@@ -13,14 +13,12 @@
// once per process
void fuzz_common_setup(void);
void fuzz_svr_setup(void);
void fuzz_cli_setup(void);
// must be called once per fuzz iteration.
// returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE
int fuzz_set_input(const uint8_t *Data, size_t Size);
int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths);
int fuzz_run_client(const uint8_t *Data, size_t Size, int skip_kexmaths);
const void* fuzz_get_algo(const algo_type *algos, const char* name);
// fuzzer functions that intrude into general code
@@ -30,13 +28,9 @@ int fuzz_checkpubkey_line(buffer* line, int line_num, char* filename,
const unsigned char* keyblob, unsigned int keybloblen);
extern const char * const * fuzz_signkey_names;
void fuzz_seed(void);
// helpers
void fuzz_get_socket_address(int fd, char **local_host, char **local_port,
char **remote_host, char **remote_port, int host_lookup);
void fuzz_fake_send_kexdh_reply(void);
int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid);
void fuzz_dump(const unsigned char* data, size_t len);
// fake IO wrappers
#ifndef FUZZ_SKIP_WRAP
@@ -63,11 +57,12 @@ struct dropbear_fuzz_options {
int do_jmp;
sigjmp_buf jmp;
// write out decrypted session data to this FD if it's set
// flag - this needs to be set manually in cli-main.c etc
int dumping;
// the file descriptor
int recv_dumpfd;
uid_t pw_uid;
gid_t pw_gid;
char* pw_name;
char* pw_dir;
char* pw_shell;
char* pw_passwd;
};
extern struct dropbear_fuzz_options fuzz;

View File

@@ -1,6 +0,0 @@
#include "fuzz.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return fuzz_run_client(Data, Size, 0);
}

View File

@@ -1,6 +0,0 @@
#include "fuzz.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return fuzz_run_client(Data, Size, 1);
}

View File

@@ -4,7 +4,7 @@
result=0
test -d fuzzcorpus && hg --repository fuzzcorpus/ pull || hg clone https://hg.ucc.asn.au/dropbear-fuzzcorpus fuzzcorpus || exit 1
test -d fuzzcorpus && hg --repository fuzzcorpus/ pull || hg clone https://secure.ucc.asn.au/hg/dropbear-fuzzcorpus fuzzcorpus || exit 1
for f in `make list-fuzz-targets`; do
./$f fuzzcorpus/$f/* || result=1
done

View File

@@ -637,7 +637,7 @@ static sign_key *openssh_read(const char *filename, const char * UNUSED(passphra
buf_incrpos(blobbuf, 8);
buf_eatstring(blobbuf);
buf_eatstring(blobbuf);
buf_decrpos(blobbuf, SSH_SIGNKEY_ED25519_LEN+4);
buf_incrpos(blobbuf, -SSH_SIGNKEY_ED25519_LEN-4);
if (buf_get_ed25519_priv_key(blobbuf, retkey->ed25519key)
== DROPBEAR_SUCCESS) {
errmsg = NULL;

View File

@@ -3,13 +3,11 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* Dropbear sets this separately, avoid platform code */
mp_err(*s_mp_rand_source)(void *out, size_t size) = NULL;
mp_err(*s_mp_rand_source)(void *out, size_t size) = s_mp_rand_platform;
void mp_rand_source(mp_err(*source)(void *out, size_t size))
{
/* Dropbear, don't reset to platform if source==NULL */
s_mp_rand_source = source;
s_mp_rand_source = (source == NULL) ? s_mp_rand_platform : source;
}
mp_err mp_rand(mp_int *a, int digits)

View File

@@ -1316,8 +1316,6 @@
#undef BN_S_MP_KARATSUBA_SQR_C
#undef BN_S_MP_TOOM_MUL_C
#undef BN_S_MP_TOOM_SQR_C
/* Dropbear uses its own random source */
#undef BN_S_MP_RAND_PLATFORM_C
#include "dbmalloc.h"
#define MP_MALLOC m_malloc

View File

@@ -344,12 +344,7 @@ void decrypt_packet() {
if (checkmac() != DROPBEAR_SUCCESS) {
dropbear_exit("Integrity error");
}
}
#if DROPBEAR_FUZZ
fuzz_dump(ses.readbuf->data, ses.readbuf->len);
#endif
/* get padding length */
buf_setpos(ses.readbuf, PACKET_PADDING_OFF);

View File

@@ -64,8 +64,6 @@ void svr_dropbear_log(int priority, const char* format, va_list param);
/* Client */
void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection *progress, pid_t proxy_cmd_pid) ATTRIB_NORETURN;
void cli_connected(int result, int sock, void* userdata, const char *errstring);
void cli_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN;
void cli_dropbear_log(int priority, const char* format, va_list param);
void cleantext(char* dirtytext);
void kill_proxy_command(void);

View File

@@ -235,7 +235,7 @@ int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
*type = keytype;
/* Rewind the buffer back before "ssh-rsa" etc */
buf_decrpos(buf, len + 4);
buf_incrpos(buf, -len - 4);
#if DROPBEAR_DSS
if (keytype == DROPBEAR_SIGNKEY_DSS) {
@@ -316,7 +316,7 @@ int buf_get_priv_key(buffer *buf, sign_key *key, enum signkey_type *type) {
*type = keytype;
/* Rewind the buffer back before "ssh-rsa" etc */
buf_decrpos(buf, len + 4);
buf_incrpos(buf, -len - 4);
#if DROPBEAR_DSS
if (keytype == DROPBEAR_SIGNKEY_DSS) {

View File

@@ -294,7 +294,7 @@ static int checkpubkey_line(buffer* line, int line_num, const char* filename,
is_comment = 1;
break;
}
buf_decrpos(line, 1);
buf_incrpos(line, -1);
break;
}
if (is_comment) {

View File

@@ -693,11 +693,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
/* take global command into account */
if (svr_opts.forced_command) {
if (chansess->cmd) {
chansess->original_command = chansess->cmd;
} else {
chansess->original_command = m_strdup("");
}
chansess->original_command = chansess->cmd ? : m_strdup("");
chansess->cmd = m_strdup(svr_opts.forced_command);
} else {
/* take public key option 'command' into account */

View File

@@ -4,7 +4,7 @@
*******************************************************************/
#ifndef DROPBEAR_VERSION
#define DROPBEAR_VERSION "2020.81"
#define DROPBEAR_VERSION "2020.79"
#endif
#define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION
@@ -176,7 +176,7 @@ If you test it please contact the Dropbear author */
explicitly specified for all protocols (just
for algos) but seems valid */
#define MAX_PROPOSED_ALGO 50
#define MAX_PROPOSED_ALGO 20
/* size/count limits */
/* From transport rfc */