Add EN-20:17, EN-20:18, and SA-20:24 to SA-20:26.

Approved by:	so
This commit is contained in:
Gordon Tetlow 2020-09-02 16:53:16 +00:00
parent 6e2ca911a9
commit 338214adbc
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=54452
21 changed files with 1868 additions and 0 deletions

View file

@ -0,0 +1,132 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-EN-20:17.linuxthread Errata Notice
The FreeBSD Project
Topic: FreeBSD Linux ABI kernel panic
Category: core
Module: kernel
Announced: 2020-09-02
Credits: Martin Filla
Henrique L. Amorim, Independent Security Researcher
Rodrigo Rubira Branco (BSDaemon), Amazon Web Services
Affects: All supported versions of FreeBSD.
Corrected: 2020-06-25 05:24:35 UTC (stable/12, 12.1-STABLE)
2020-09-02 16:21:27 UTC (releng/12.1, 12.1-RELEASE-p9)
2020-06-25 05:35:46 UTC (stable/11, 11.4-STABLE)
2020-09-02 16:21:27 UTC (releng/11.4, 11.4-RELEASE-p3)
2020-09-02 16:21:27 UTC (releng/11.3, 11.3-RELEASE-p13)
For general information regarding FreeBSD Errata Notices and Security
Advisories, including descriptions of the fields above, security
branches, and the following sections, please visit
<URL:https://security.FreeBSD.org/>.
I. Background
The Linux ABI layer (Linuxulator) allows Linux binaries to be executed on a
FreeBSD kernel.
II. Problem Description
The kernel function handling exec(3) of a Linux binary did not correctly
handle a calling process with multiple threads.
III. Impact
A multithread non-Linux process execing a Linux binary would fail a kernel
assertion, resuting in a kernel panic "thread_detach: emuldata not found."
IV. Workaround
No workaround is available. Systems not using the Linux ABI layer are not
affected.
V. Solution
Upgrade your system to a supported FreeBSD stable or release / security
branch (releng) dated after the correction date, and reboot.
Perform one of the following:
1) To update your system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
# shutdown -r +10min "Rebooting for an errata update"
2) To update your system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
# fetch https://security.FreeBSD.org/patches/EN-20:17/linuxthread.patch
# fetch https://security.FreeBSD.org/patches/EN-20:17/linuxthread.patch.asc
# gpg --verify linuxthread.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile your kernel as described in
<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
system.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/12/ r362605
releng/12.1/ r365253
stable/11/ r362606
releng/11.4/ r365253
releng/11.3/ r365253
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=247020>
The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-20:17.linuxthread.asc>
-----BEGIN PGP SIGNATURE-----
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9PzRZfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cIZEw//QwJJ3DX0k1PnOwRDdl5KSORAZq1Qfa0Rdo4N3QK31Ap/GiAmW+6wZRr1
Cb3dAywlfjw8F+Hnxc6za1V0W7Ckr/tbJHGt1XXsq8Pjpc6+GdNGRZi7eiAQHvU7
I9xkL1jnerBY0l5hq8A6ti1vhraNEFvA0/0lluhqCpgFPEtc/vbvKemyC0RAKVzF
wAz7P3/OyQqcd5qVHBIYfOziau/lfQ2/qD+6hLSZ5pgGX4e/tB1NrYVSd0vNevOl
d3P9LDQYxSIzQ5jHbfLSFOPkT471ItJ6+QW+pAIZQ0Sv4hTQPBRHOL4ZfXG/IDgr
+mVBa6L8lykeC+xh9Teih+dKqZRY5SzKuZVUqURCY2P6miq8C5A2eiTtGIIuwgFF
okqTJx0a+ECAEc7dmaEAM8snqKiPYgu1cCOXKrvAPpkB/Ss1w0Zr/YxLW6v3lMmO
nFOUGeXF9hLxDIINdKRNdaum8aqy1Vtg6xKNfP6z/H4V6saLSLrWk0M2HDKNOyts
MHc/P7zg7hMw1ft/VhiOEWgCk7Se3Q1D2IY53BsUNgtbs5ti29mEeOkNO09FkPYL
t9f3uIOZD9PLg1kDIDA97DulL95gXyX2K10wHciOnDgU+UitHCOqXAnkYGKbezfS
ID1JRdq4uHHIjPOTOiUkTYJDnR/Lgz2572KkTjM5d7YOviS8nS0=
=1pOR
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,124 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-EN-20:18.getfsstat Errata Notice
The FreeBSD Project
Topic: getfsstat compatibility system call panic
Category: core
Module: getfsstat
Announced: 2020-09-02
Credits: Rodrigo Rubira Branco (BSDaemon), Amazon Web Services
Affects: FreeBSD 11.3 and 11.4
Corrected: 2020-06-20 04:39:52 UTC (stable/11, 11.4-STABLE)
2020-09-02 16:22:14 UTC (releng/11.4, 11.4-RELEASE-p3)
2020-09-02 16:22:14 UTC (releng/11.3, 11.3-RELEASE-p13)
For general information regarding FreeBSD Errata Notices and Security
Advisories, including descriptions of the fields above, security
branches, and the following sections, please visit
<URL:https://security.FreeBSD.org/>.
I. Background
getfsstat(2) is a system call which provides information about mounted
filesystems. The kernel provides compatibility system calls for old
versions of the interface.
II. Problem Description
A bug in an internal interface used by getfsstat(2) compatibility system
calls could result in a free of an uninitialized pointer when getfsstat(2)
is called with an invalid argument.
III. Impact
A kernel panic can be triggered by an unprivileged user process.
IV. Workaround
No workaround is available.
V. Solution
Upgrade your system to a supported FreeBSD stable or release / security
branch (releng) dated after the correction date, and reboot.
Perform one of the following:
1) To update your system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
# shutdown -r +10min "Rebooting for an errata update"
2) To update your system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
# fetch https://security.FreeBSD.org/patches/EN-20:18/getfsstat.patch
# fetch https://security.FreeBSD.org/patches/EN-20:18/getfsstat.patch.asc
# gpg --verify getfsstat.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile your kernel as described in
<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
system.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/11/ r362426
releng/11.4/ r365254
releng/11.3/ r365254
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-20:18.getfsstat.asc>
-----BEGIN PGP SIGNATURE-----
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9PzSVfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cJrrw/9E3bKTN36F+FPrGdi6wWeAHUEZt3hoonrFqrn4SPUEVSRkk39HGpitgJ8
KU7HDr9U9B6zaIYnqE+1BWiIYYhqQQM5zb77TGr0fy/LVa8a+m/6o9wzib26lsAT
jrBS0hsZ0Swb8TlrQdaEpLp1wkEdhy5t10hJ/+/nezzo+q2C52m4Bs80J7gE9BCq
uxgCRlnld3fXJrKrOva8WfvMziE8nV9CzKF9luYlP7U9s1PS5H5U6r22Y8tvzZqS
IbH60i7vPhlqX8faxZfKGRIABsJhnee98JF0rDRBOmMwTnFBTmaot75eEjwZIc5p
0GtM27NOM6a/AaO9Yr8U4PI0PffTi8hVm/1t6dlhG5X3O7IUxKC0XT1vlh3jJ1j2
9i1iuuGU3zSzTSMyWMmzuxCz/YK0C/g4C86ehkdxOYtn6RV31rMSoKdPjxSbyhIJ
ef1eXHm6iBM8aofto24WjCSftPno0rx1peeOnKAqvpTpGH+n08H6iRFagaOt6kkQ
qhy+ZtrlzmjUeUqwLSnyuHJtK+QkP1WFTnT9QgMPnqpRB9e+OsQC2K1KgR9lkOG0
2kyTu+fJGkNvhiHxKuvIsh5OiNvNm/QHYwESaGPbFhierh+CHs00M00GyeeCjBSr
nMbA3DsD3OxrrxYqh/17x4XoiopY6gUSlDSG+RbsTFsTqTxi308=
=E4P4
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,124 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-20:24.ipv6 Security Advisory
The FreeBSD Project
Topic: IPv6 Hop-by-Hop options use-after-free bug
Category: core
Module: kernel
Announced: 2020-09-02
Affects: FreeBSD 11.3
Corrected: 2020-05-07 01:28:59 UTC (stable/11, 11.4-PRERELEASE)
2020-09-02 16:23:15 UTC (releng/11.3, 11.3-RELEASE-p13)
CVE Name: CVE-2020-7462
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:https://security.FreeBSD.org/>.
I. Background
IPv6 is a network layer supporting Hop-by-Hop options, which can be sent by
applications via the socket API. The memory management for packet handling
is done using mbufs.
II. Problem Description
Due to improper mbuf handling in the kernel, a use-after-free bug might be
triggered by sending IPv6 Hop-by-Hop options over the loopback interface.
III. Impact
Triggering the use-after-free situation may result in unintended kernel
behaviour including a kernel panic.
IV. Workaround
No workaround is available.
V. Solution
Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date,
and reboot.
Perform one of the following:
1) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
# shutdown -r +10min "Rebooting for a security update"
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
# fetch https://security.FreeBSD.org/patches/SA-20:24/ipv6.patch
# fetch https://security.FreeBSD.org/patches/SA-20:24/ipv6.patch.asc
# gpg --verify ipv6.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile your kernel as described in
<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
system.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/11/ r360733
releng/11.3/ r365255
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7462>
The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-20:24.ipv6.asc>
-----BEGIN PGP SIGNATURE-----
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9PzTNfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cLJYxAAotGAWrawa3gRK8gVpEIJiYknR9bODjDojm7KovlkuKeYAkyQ92/Ii23U
U6tMXSPDYQFyscOdrGq4yEjxRDLLkGQGynQpioinDn8POKX7BKpy+PFFdv1mmBef
h/WpgmlPdhymYisaImgVyGAxU81auzpFB6mArzFDCdHavTd7jVD2lJwcpdzeOk//
NHOsj8C4VYJs0XcYrNa4CEWfH/D/uNO8u2b3QUfKQSOdfIfaDv22k2b96YKm+zcr
xS7Q1jDv7QBTQou7KNOfoPi0Gclp8Q9VReP2nY/hB5TmJjR3irz+Z6UcGfiyDGrL
XRB7oP23jIUmBbsINUN06FIhAPGF9/7zcOOoV1YOdwvmbLM0/W4c+mERZ16gw6+N
MzCLDOeiyKAUr+pQzcl6lORxr31eB8400l6nRJwmCiWx4nHwyHPIl1RtfvsdNqfE
/OBVEalxsCrzStfW4ME5RziPo9Y8DrajPf7+JY/4CIV3v/dJAiGi3+qs9Zn8enar
WCR/8+o4xbT+d1sGTG1W3Qjh9a28jxqEusLjdehDy8PTk9OnIfPRuxj+kvot3Wo0
lWdeSIo8YZPYn7hG9N19k6aDlljM1fgkBmWj1uELtCeIE7WM5tHGMBuaS0cTt1jL
s2g01qgkgW2a6cChdm3oNfUKE5KpD3/hU63/jEA6QyJJQQqXlOs=
=kFlz
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,142 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-20:25.sctp Security Advisory
The FreeBSD Project
Topic: SCTP socket use-after-free bug
Category: core
Module: kernel
Announced: 2020-09-02
Credits: Megan2013678@protonmail.com
Affects: All supported versions of FreeBSD.
Corrected: 2020-08-24 09:19:05 UTC (stable/12, 12.1-STABLE)
2020-09-02 16:24:32 UTC (releng/12.1, 12.1-RELEASE-p9)
2020-08-24 09:46:36 UTC (stable/11, 11.4-STABLE)
2020-09-02 16:24:32 UTC (releng/11.4, 11.4-RELEASE-p3)
2020-09-02 16:24:32 UTC (releng/11.3, 11.3-RELEASE-p13)
CVE Name: CVE-2020-7463
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:https://security.FreeBSD.org/>.
I. Background
The Stream Control Transmission Protocol (SCTP) is a message oriented
transport protocol supporting arbitrary large user messages.
It can be accessed from applications by using the the socket API.
II. Problem Description
Due to improper handling in the kernel, a use-after-free bug can be triggered
by sending large user messages from multiple threads on the same socket.
III. Impact
Triggering the use-after-free situation may result in unintended kernel
behaviour including a kernel panic.
IV. Workaround
No workaround is available.
V. Solution
Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date,
and reboot.
Perform one of the following:
1) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
# shutdown -r +10min "Rebooting for a security update"
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
[FreeBSD 12.1]
# fetch https://security.FreeBSD.org/patches/SA-20:25/sctp.12.1.patch
# fetch https://security.FreeBSD.org/patches/SA-20:25/sctp.12.1.patch.asc
# gpg --verify sctp.12.1.patch.asc
[FreeBSD 11.4]
# fetch https://security.FreeBSD.org/patches/SA-20:25/sctp.11.4.patch
# fetch https://security.FreeBSD.org/patches/SA-20:25/sctp.11.4.patch.asc
# gpg --verify sctp.11.4.patch.asc
[FreeBSD 11.3]
# fetch https://security.FreeBSD.org/patches/SA-20:25/sctp.11.3.patch
# fetch https://security.FreeBSD.org/patches/SA-20:25/sctp.11.3.patch.asc
# gpg --verify sctp.11.3.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile your kernel as described in
<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
system.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/12/ r364644
releng/12.1/ r365256
stable/11/ r364651
releng/11.4/ r365256
releng/11.3/ r365256
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7463>
The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-20:25.sctp.asc>
-----BEGIN PGP SIGNATURE-----
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9PzTZfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cIMPw//ZOYh7TQdwvreQ/iZbJphPp7hBVJqFWPE9M72Yfo87/vkl+T5/GW9wiLT
MQlknQ7SDyzE7i8RpGvX0lmXLbr1e2rkvin1ZFdCbWkPzC7w0WVH7XX6+I+RJmkh
E4dtmHrYhLRwmVtW5WYZdfO+iYVTJl/h43eYbYvNgJZSuKkvl2Vk6DqyseHx7xR6
gc7/41AIpMiqRLQI9ZnRvZCEiLq4G+q5z499ACfAutT9o+1T9L6QLCPuyY+fziiq
cI2E/pQA5uxOY/z3ejKHeOzErjycY6GEhMiBKmsJqV6oU/cZd5hZ1qsmE9Xbi3/c
Ax+OZr+Ve2a78dD7jOrmCrpBtG1Pg39c6VuQqHD3UN3seBNEkn4kto9vDX9fLceD
GZbueV97boFxjnXu1B6C8ufqEZDqTaf/SU3+vCobBgydP+V8c1P5LbP6qcFHOUrk
k7ijiJv03aYyY1Z6XtqbRsudZzIaTt+jneUA1eA46iWQqVZQHKo2liw5kAtsGu0k
injGcazWRphV6xgOHIMCfrGcLLf0j+4UjiDUk30cansLGewuk/uEh6FlA4NzyRWA
4L3Q0l/XQWvO2sNMtF9LbBUUujDyy93Vy8BouSp59v7+bAYrRHfcIAmaQnE4jev2
BY7/JsrfQ9rG/Anzg49Hec8pw9VEvv4kA1STqXcpMt9Fq+0DslA=
=2ET6
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,145 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-20:26.dhclient Security Advisory
The FreeBSD Project
Topic: dhclient heap overflow
Category: core
Module: dhclient
Announced: 2020-09-02
Credits: Shlomi Oberman, JSOF
Affects: All supported versions of FreeBSD.
Corrected: 2020-08-31 21:28:09 UTC (stable/12, 12.1-STABLE)
2020-09-02 16:25:31 UTC (releng/12.1, 12.1-RELEASE-p9)
2020-08-31 21:28:57 UTC (stable/11, 11.4-STABLE)
2020-09-02 16:25:31 UTC (releng/11.4, 11.4-RELEASE-p3)
2020-09-02 16:25:31 UTC (releng/11.3, 11.3-RELEASE-p13)
CVE Name: CVE-2020-7461
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:https://security.FreeBSD.org/>.
I. Background
dhclient(8) is the default IPv4 DHCP client used on FreeBSD. It is
responsible for contacting DHCP servers on a network segment, and for
initializing and configuring network interfaces and configuring name
resolution based on received information.
dhclient(8) handles DHCP option 119, the Domain Search Option, which provides
a list of domains to search when resolving names using DNS. The option data
format uses a compression scheme to avoid transmitting duplicate domain name
labels.
II. Problem Description
When parsing option 119 data, dhclient(8) computes the uncompressed domain
list length so that it can allocate an appropriately sized buffer to store
the uncompressed list. The code to compute the length failed to handle
certain malformed input, resulting in a heap overflow when the uncompressed
list is copied into in inadequately sized buffer.
III. Impact
The heap overflow could in principle be exploited to achieve remote code
execution. The affected process runs with reduced privileges in a Capsicum
sandbox, limiting the immediate impact of an exploit. However, it is
possible the bug could be combined with other vulnerabilities to escape the
sandbox.
IV. Workaround
No workaround is available. To trigger the bug, a system must be running
dhclient(8) on the same network as a malicious DHCP server.
V. Solution
Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date, and
restart dhclient or reboot.
Perform one of the following:
1) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
# shutdown -r +10min "Rebooting for a security update"
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
# fetch https://security.FreeBSD.org/patches/SA-20:26/dhclient.patch
# fetch https://security.FreeBSD.org/patches/SA-20:26/dhclient.patch.asc
# gpg --verify dhclient.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile the operating system using buildworld and installworld as
described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
Restart the applicable daemons, or reboot the system.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/12/ r365010
releng/12.1/ r365257
stable/11/ r365011
releng/11.4/ r365257
releng/11.3/ r365257
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7461>
The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-20:26.dhclient.asc>
-----BEGIN PGP SIGNATURE-----
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9PzTtfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cLLPxAAhg/FSqWLykYAiQ8czoy98X00VIWAP1f4InfUKm8qOB8/7ptzv3A+2Hov
7lHlyN0D4OwhJFt7fw9oTwNe4UgxShso6QrezaTJZR7juFELy9WODbRFnNK4i8w9
NCBab+NIn1o7nFZnB0M5TMKfa4gc1jAV+Q/U/zi+ONvwZegmjXJxuop3Sq8wfBd2
Vp9VAvEJvvBlQKExR2xNRDKV/0LpW+VffIuzlWT2ex3WwGpFVeVSL0ZNJsPbzMYX
j0aqGo9B/mHfXtKSQ415kGxiaQctnu5FqjNgSc00byzOU0YTiLsPwPdUgIt+nuQd
WFSePoZsDYstkkJ8YaCA/LVzmZo0tNR8m+z7xmhCszUbMIV+iRSycUexEbCXoPx/
Ebg6ycyYMwguK7rL2dkjNWTkr3hP5CgLD7VnzVBYGiBY7ha0zOgbaYWl/33Az5Fb
0eaIyJRFCDmI32NZfri1WLc06K1gFcVcR6VO+BUqRHG6bkYnF/4xlla8ERhYgNeC
Y9cs4Y9TNRges79k7jovpu9B5nicTEqMRQBubcARX5+w9zLg8h2aKH6inuVy1srn
M9H/mjdCHMkySpSSrENw9Jk5I7RAgHHRgA1OTkB6Da02aMzPEh6fYHWeR7IpvxPc
2A/hxnZy0tTeZ4aKbds1GYZWUVDd3I8DlSVcT5Bq1g5kk6I+PN8=
=jfay
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,63 @@
--- sys/compat/linux/linux_emul.c.orig
+++ sys/compat/linux/linux_emul.c
@@ -261,22 +261,13 @@
void
linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
{
- struct thread *td = curthread;
+ struct thread *td;
struct thread *othertd;
#if defined(__amd64__)
struct linux_pemuldata *pem;
#endif
- /*
- * In a case of execing from Linux binary properly detach
- * other threads from the user space.
- */
- if (__predict_false(SV_PROC_ABI(p) == SV_ABI_LINUX)) {
- FOREACH_THREAD_IN_PROC(p, othertd) {
- if (td != othertd)
- (p->p_sysent->sv_thread_detach)(othertd);
- }
- }
+ td = curthread;
/*
* In a case of execing to Linux binary we create Linux
@@ -284,11 +275,32 @@
*/
if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) ==
SV_ABI_LINUX)) {
-
- if (SV_PROC_ABI(p) == SV_ABI_LINUX)
+ if (SV_PROC_ABI(p) == SV_ABI_LINUX) {
+ /*
+ * Process already was under Linuxolator
+ * before exec. Update emuldata to reflect
+ * single-threaded cleaned state after exec.
+ */
linux_proc_init(td, NULL, 0);
- else
+ } else {
+ /*
+ * We are switching the process to Linux emulator.
+ */
linux_proc_init(td, td, 0);
+
+ /*
+ * Create a transient td_emuldata for all suspended
+ * threads, so that p->p_sysent->sv_thread_detach() ==
+ * linux_thread_detach() can find expected but unused
+ * emuldata.
+ */
+ FOREACH_THREAD_IN_PROC(td->td_proc, othertd) {
+ if (othertd != td) {
+ linux_proc_init(td, othertd,
+ LINUX_CLONE_THREAD);
+ }
+ }
+ }
#if defined(__amd64__)
/*
* An IA32 executable which has executable stack will have the

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7tfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cLxQw/9HUXUeCz5XHIK6qL0yaGIDQh2QOlLXiHSf+5EvGOv+xFsP+IFFwWLNCud
D5LCquLDcFOAxb2PZOZ8Of2zUtmiFGi2rly+aw//pNMiRzbI/wGfwvcr2iwleP0P
DBn0PDJzOJO87FzjdPnm3p8GqlndCkb2YEDzVDCzA29uTyXbNSB38fj5W+Nqg/H3
ouxl9NEcN5q8cdUn2//F6DX/NKKoQ+KUR5ImAm5VPDDzs+i3U7uIGO/o1B1iZd1+
EvSLRDmaB58xmqbhudbb//gzJycD8OAv0djxjjfsYhR2yr1sKWi0+lM22QFvSPGY
2PC4692pzOySX2sDf9qdVk2ljv8ab498Kkeo1fUtSTNIjwei2OjYsRYq5nmRfb0Q
2pKHOb80NfQTMIZ6nQHNi6AQ9T/Jezp14VlCeMzkIWQ9o8Lez6W3fxy+59Ir+tQh
CsWXIoTPXO9RjHkqQ8jw2F0qjI77dFxpN1hixi/3Wn5KA+3BkLidcCoXiejkR9jy
FnmAAWjS97TIpLMMwScmA5X83wNpylX1Y+/69NNxw6IiJvNN4KhLWAj2V4l0OSrZ
IJlBReeEJk0wL5z6JQyJ4XB6zTDjBb3Cx9grmDH6CPssLsDlcrJGyICpawXPLOeg
aLg8h1bgD8YlMVxyxUgqpPGaCDwY1pRale8+mYbWFUWfGcCll5U=
=InXC
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,11 @@
--- sys/kern/vfs_syscalls.c.orig
+++ sys/kern/vfs_syscalls.c
@@ -409,6 +409,8 @@
case MNT_NOWAIT:
break;
default:
+ if (bufseg == UIO_SYSSPACE)
+ *buf = NULL;
return (EINVAL);
}
restart:

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7tfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cISgA/7Bc4uiJyULvRciFN5W7X1aNFKjFtBlP3LAsRVZFkAxxb5SEN9NIuMqru3
smZ3oIPswksChJYWdGuiegvzVRPo73YinMnFZu+i064wLttnlOEJXIePfEgpvu81
BaCtBI3iPrHroFA6LiSUPFlZUBYxl9sMucusRWOpORDPOeNVVoBm0jC282B2k6m0
h6dPQG++ARXdoH8hBnXrZt17Lu8kK6BOQFysru8G35UCLf9jAczrzStaq9DC6rdi
UHilIaeXKvEM10r7hos8d3wLQjpKRXcSEmcYAWgbCG8ewlSVDDhORftqZ2gv6I/P
dqDwnwznS1ArhYWjk+RHheekbgqP89nJpaYT3rvne3wuzjX6fIDtJBEg0/v5PbOX
VZu/5MG8M/l02j5NLghgGnqRmQjalpl4khsBBweQfht/w4eSURA219V497v6Dm0w
cwk/+R1Nql7NY83PK3PhSvVkmjLvlRYYm47yJphWtqxZ2forwT9KSPZgcEYByd0t
Fiw2rJCyUDXtgMPNmIYcqeX/5IUT921L1wr8VWCYdaS15qFEjU790M+moiK9j6En
IyCsoNN6WASORwcgJGqi6kiScYQEUR+I34feox4dkfavDMrG2ll7Spzz4RZJSar/
HF191J+feeHbMFcz7gqH6vumj8mMKrx/ARWD16OVSFIFaaF7QjA=
=yl10
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,37 @@
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -402,20 +402,22 @@ VNET_SYSUNINIT(inet6, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_destroy, NULL);
#endif
static int
-ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off,
+ip6_input_hbh(struct mbuf **mp, uint32_t *plen, uint32_t *rtalert, int *off,
int *nxt, int *ours)
{
+ struct mbuf *m;
struct ip6_hdr *ip6;
struct ip6_hbh *hbh;
- if (ip6_hopopts_input(plen, rtalert, &m, off)) {
+ if (ip6_hopopts_input(plen, rtalert, mp, off)) {
#if 0 /*touches NULL pointer*/
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
+ in6_ifstat_inc((*mp)->m_pkthdr.rcvif, ifs6_in_discard);
#endif
goto out; /* m have already been freed */
}
/* adjust pointer */
+ m = *mp;
ip6 = mtod(m, struct ip6_hdr *);
/*
@@ -855,7 +857,7 @@ ip6_input(struct mbuf *m)
*/
plen = (u_int32_t)ntohs(ip6->ip6_plen);
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
- if (ip6_input_hbh(m, &plen, &rtalert, &off, &nxt, &ours) != 0)
+ if (ip6_input_hbh(&m, &plen, &rtalert, &off, &nxt, &ours) != 0)
return;
} else
nxt = ip6->ip6_nxt;

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7tfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cIWLQ//f5XvBbodgJD5LiVh8RJwlPjdTI72UqY+YoFq2v3ELlaIL40Zpfr1WUE/
70lPdfeX8GgKDLzvV0RA05HFYyhMD8zOY2TOglS0dEcU6gQ7z0ncPm3pmS2G8JjS
/f8Lioqp1UbxROpW+vquj3Zls40Lkk5T2xOrhR6mNzOVSFHm3q8+ElPAEFsrfPy1
KZEM3CefIEgngED9m5bUsICnuIIdyiOZW+zx+3NnJEzwL4laS7KKzzplzibBtogq
2qx6tDnIatRUJLb7ZVzayW4FAT2aRhS02JqcnL5vljtkefr50f5a+yA8lflBJm5I
+3rCJcFG89c4OOjO6e7LtyorFk7OKtdWGkHFNLlXmN9C8a6Rap9r3SW3NC/6YJHB
7v7sZ0WHv8ECl65HnA/KCBvtdfCUEb6EqOCJW2CncmVFdBxMcCOAsAdC36Cc4yPl
3/7HFzhrO5LoM8xbGZdYKjb+T+LgsrIyeYgGr19RfoYNqVkzxxFX8Nz+OLwbPIC3
/MTSM0VYEelmAEsFiEV4oL6D42xYhafXSRRstQAMSijW8v4ao8KpJaz2dzbcQ2NO
U8S9NI3kwC7lvjO+hH1n7w2nJi25Z4fTBiz6vKCOYwEEN38tis6S2YOusfPiI39z
0C8VvWVXRHUJBqsjBZ6I74Bs5CSjRSL2YQbVyvLl82WctHrXk5Q=
=y2VF
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,305 @@
--- sys/netinet/sctp_input.c
+++ sys/netinet/sctp_input.c
@@ -839,7 +839,6 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -1989,7 +1988,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* send up all the data */
SCTP_TCB_SEND_LOCK(stcb);
- sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
+ sctp_report_all_outbound(stcb, 0, SCTP_SO_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].chunks_on_queues = 0;
#if defined(SCTP_DETAILED_STR_STATS)
--- sys/netinet/sctp_output.c
+++ sys/netinet/sctp_output.c
@@ -13159,11 +13159,10 @@ sctp_lower_sosend(struct socket *so,
error = EINVAL;
goto out;
}
- SCTP_TCB_SEND_UNLOCK(stcb);
-
strm = &stcb->asoc.strmout[srcv->sinfo_stream];
if (strm->last_msg_incomplete == 0) {
do_a_copy_in:
+ SCTP_TCB_SEND_UNLOCK(stcb);
sp = sctp_copy_it_in(stcb, asoc, srcv, uio, net, max_len, user_marks_eor, &error);
if (error) {
goto out;
@@ -13189,13 +13188,11 @@ sctp_lower_sosend(struct socket *so,
if (srcv->sinfo_flags & SCTP_UNORDERED) {
SCTP_STAT_INCR(sctps_sends_with_unord);
}
+ sp->processing = 1;
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, asoc, strm, sp, 1);
- SCTP_TCB_SEND_UNLOCK(stcb);
} else {
- SCTP_TCB_SEND_LOCK(stcb);
sp = TAILQ_LAST(&strm->outqueue, sctp_streamhead);
- SCTP_TCB_SEND_UNLOCK(stcb);
if (sp == NULL) {
/* ???? Huh ??? last msg is gone */
#ifdef INVARIANTS
@@ -13207,7 +13204,16 @@ sctp_lower_sosend(struct socket *so,
goto do_a_copy_in;
}
+ if (sp->processing) {
+ SCTP_TCB_SEND_UNLOCK(stcb);
+ SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ error = EINVAL;
+ goto out;
+ } else {
+ sp->processing = 1;
+ }
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
while (uio->uio_resid > 0) {
/* How much room do we have? */
struct mbuf *new_tail, *mm;
@@ -13232,20 +13238,29 @@ sctp_lower_sosend(struct socket *so,
if (mm) {
sctp_m_freem(mm);
}
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
/* Update the mbuf and count */
SCTP_TCB_SEND_LOCK(stcb);
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
+ (stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
/*
* we need to get out. Peer probably
* aborted.
*/
sctp_m_freem(mm);
- if (stcb->asoc.state & SCTP_PCB_FLAGS_WAS_ABORTED) {
+ if (stcb->asoc.state & SCTP_STATE_WAS_ABORTED) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
error = ECONNRESET;
}
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
@@ -13305,6 +13320,11 @@ sctp_lower_sosend(struct socket *so,
/* wait for space now */
if (non_blocking) {
/* Non-blocking io in place out */
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto skip_out_eof;
}
/* What about the INIT, send it maybe */
@@ -13428,6 +13448,11 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@@ -13437,12 +13462,19 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
+ SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
}
SCTP_TCB_SEND_LOCK(stcb);
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
+ (stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@@ -13458,6 +13490,7 @@ sctp_lower_sosend(struct socket *so,
strm->last_msg_incomplete = 0;
asoc->stream_locked = 0;
}
+ sp->processing = 0;
} else {
SCTP_PRINTF("Huh no sp TSNH?\n");
strm->last_msg_incomplete = 0;
--- sys/netinet/sctp_pcb.c
+++ sys/netinet/sctp_pcb.c
@@ -4722,6 +4722,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* there is no asoc, really TSNH :-0 */
return (1);
}
+ SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.alternate) {
sctp_free_remote_addr(stcb->asoc.alternate);
stcb->asoc.alternate = NULL;
@@ -4756,6 +4757,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* nope, reader or writer in the way */
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
/* no asoc destroyed */
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, stcb, 8);
@@ -4853,6 +4855,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
@@ -4886,10 +4889,12 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
if (from_inpcbfree == SCTP_NORMAL_PROC) {
atomic_add_int(&stcb->asoc.refcnt, 1);
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_INP_WLOCK(inp);
SCTP_TCB_LOCK(stcb);
+ SCTP_TCB_SEND_LOCK(stcb);
}
/* Double check the GONE flag */
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
@@ -4938,6 +4943,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_INP_INFO_WUNLOCK();
SCTP_INP_WUNLOCK(inp);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
return (0);
}
@@ -4981,7 +4987,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
* in case.
*/
/* anything on the wheel needs to be removed */
- SCTP_TCB_SEND_LOCK(stcb);
for (i = 0; i < asoc->streamoutcnt; i++) {
struct sctp_stream_out *outs;
@@ -5012,7 +5017,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
}
}
- SCTP_TCB_SEND_UNLOCK(stcb);
/* sa_ignore FREED_MEMORY */
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
@@ -5214,6 +5218,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* Insert new items here :> */
/* Get rid of LOCK */
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
--- sys/netinet/sctp_structs.h
+++ sys/netinet/sctp_structs.h
@@ -535,6 +535,7 @@ struct sctp_stream_queue_pending {
uint8_t sender_all_done;
uint8_t put_last_out;
uint8_t discard_rest;
+ uint8_t processing;
};
/*
--- sys/netinet/sctputil.c
+++ sys/netinet/sctputil.c
@@ -3858,7 +3858,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
}
void
-sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked
+sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
@@ -3884,9 +3884,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
return;
}
/* now through all the gunk freeing chunks */
- if (holds_lock == 0) {
- SCTP_TCB_SEND_LOCK(stcb);
- }
/* sent queue SHOULD be empty */
TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
@@ -3963,10 +3960,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
/* sa_ignore FREED_MEMORY */
}
}
-
- if (holds_lock == 0) {
- SCTP_TCB_SEND_UNLOCK(stcb);
- }
}
void
@@ -3990,8 +3983,11 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
return;
}
+ SCTP_TCB_SEND_LOCK(stcb);
+ SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
/* Tell them we lost the asoc */
- sctp_report_all_outbound(stcb, error, 0, so_locked);
+ sctp_report_all_outbound(stcb, error, so_locked);
+ SCTP_TCB_SEND_UNLOCK(stcb);
if (from_peer) {
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
} else {
@@ -4023,7 +4019,6 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (stcb != NULL) {
/* We have a TCB to abort, send notification too */
sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
/* Ok, now lets free it */
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
so = SCTP_INP_SO(inp);
@@ -4133,8 +4128,6 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
return;
- } else {
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
}
/* notify the peer */
sctp_send_abort_tcb(stcb, op_err, so_locked);
--- sys/netinet/sctputil.h
+++ sys/netinet/sctputil.h
@@ -163,7 +163,7 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
void
-sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int
+sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7xfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cL8YQ/+KvStckC4dSqfz2BxUPzv+edzvvNhQ/IqStJapNrkt77DvaOq9MorO08C
jSN4JopHrZBbehUscBxvNvRZ7B3arm3vy1WTaZOwazpjCAcLvTFKgIrZrTuM2Lu6
33AZme81aXcYmJFFqNteMt1qlTEUcH97H0r0wQ8xFszly0qCXCPxv79X81JIiAR2
DXA769OIOU+vmk6ki+pDZGBUlpDRa1FnMpnFU+Z4qJmYdeX2FAze4T8KWbrzL7d0
bob8LiskZxxGnn/a7tgJJH/bLoWwAXX1V35P23xLfj6jCfT3WdjcBqHFZv2W0RHk
hZsGD3MwcEP75woyjwJFb2aYT4nQjvcTI8ag+My4CPP5JaDbAw69aEYtNGJnulzO
38Jfn+VrEAuq678jWNZ2WsGpPsJANCw2eDsp8q9E4ClwdTw73OujqxLaufkcJAxh
OL4hrW1DADTFeKcni3o1ac7aaWSD0qFTNkH9dfD38h/oZPefW4vBxawbNkOOlB93
ZagP2d7j+iHE0vznt+1IisZ0O6zDaZ/9M9he1qVIKC81YRwizmcEc+BA+zGhbjkS
yQ5REgb5ib7kwIGa6ZluxSV3EhOa8PRcVHYGhCxRcmpCSR1tybChtnKcvvM2itKE
Hm7ZLPgWWEtXw0QTVUPnOAFnYF0Rg8IDAqdtfyFc/3YYYMxvYUI=
=yz8z
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,305 @@
--- sys/netinet/sctp_input.c
+++ sys/netinet/sctp_input.c
@@ -846,7 +846,6 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -1995,7 +1994,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* send up all the data */
SCTP_TCB_SEND_LOCK(stcb);
- sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
+ sctp_report_all_outbound(stcb, 0, SCTP_SO_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].chunks_on_queues = 0;
#if defined(SCTP_DETAILED_STR_STATS)
--- sys/netinet/sctp_output.c
+++ sys/netinet/sctp_output.c
@@ -13202,11 +13202,10 @@ sctp_lower_sosend(struct socket *so,
error = EINVAL;
goto out;
}
- SCTP_TCB_SEND_UNLOCK(stcb);
-
strm = &stcb->asoc.strmout[srcv->sinfo_stream];
if (strm->last_msg_incomplete == 0) {
do_a_copy_in:
+ SCTP_TCB_SEND_UNLOCK(stcb);
sp = sctp_copy_it_in(stcb, asoc, srcv, uio, net, max_len, user_marks_eor, &error);
if (error) {
goto out;
@@ -13232,13 +13231,11 @@ sctp_lower_sosend(struct socket *so,
if (sinfo_flags & SCTP_UNORDERED) {
SCTP_STAT_INCR(sctps_sends_with_unord);
}
+ sp->processing = 1;
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, asoc, strm, sp, 1);
- SCTP_TCB_SEND_UNLOCK(stcb);
} else {
- SCTP_TCB_SEND_LOCK(stcb);
sp = TAILQ_LAST(&strm->outqueue, sctp_streamhead);
- SCTP_TCB_SEND_UNLOCK(stcb);
if (sp == NULL) {
/* ???? Huh ??? last msg is gone */
#ifdef INVARIANTS
@@ -13250,7 +13247,16 @@ sctp_lower_sosend(struct socket *so,
goto do_a_copy_in;
}
+ if (sp->processing) {
+ SCTP_TCB_SEND_UNLOCK(stcb);
+ SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ error = EINVAL;
+ goto out;
+ } else {
+ sp->processing = 1;
+ }
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
while (uio->uio_resid > 0) {
/* How much room do we have? */
struct mbuf *new_tail, *mm;
@@ -13275,20 +13281,29 @@ sctp_lower_sosend(struct socket *so,
if (mm) {
sctp_m_freem(mm);
}
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
/* Update the mbuf and count */
SCTP_TCB_SEND_LOCK(stcb);
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
+ (stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
/*
* we need to get out. Peer probably
* aborted.
*/
sctp_m_freem(mm);
- if (stcb->asoc.state & SCTP_PCB_FLAGS_WAS_ABORTED) {
+ if (stcb->asoc.state & SCTP_STATE_WAS_ABORTED) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
error = ECONNRESET;
}
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
@@ -13348,6 +13363,11 @@ sctp_lower_sosend(struct socket *so,
/* wait for space now */
if (non_blocking) {
/* Non-blocking io in place out */
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto skip_out_eof;
}
/* What about the INIT, send it maybe */
@@ -13471,6 +13491,11 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@@ -13480,12 +13505,19 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
+ SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
}
SCTP_TCB_SEND_LOCK(stcb);
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
+ (stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@@ -13501,6 +13533,7 @@ sctp_lower_sosend(struct socket *so,
strm->last_msg_incomplete = 0;
asoc->stream_locked = 0;
}
+ sp->processing = 0;
} else {
SCTP_PRINTF("Huh no sp TSNH?\n");
strm->last_msg_incomplete = 0;
--- sys/netinet/sctp_pcb.c
+++ sys/netinet/sctp_pcb.c
@@ -4725,6 +4725,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* there is no asoc, really TSNH :-0 */
return (1);
}
+ SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.alternate) {
sctp_free_remote_addr(stcb->asoc.alternate);
stcb->asoc.alternate = NULL;
@@ -4759,6 +4760,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* nope, reader or writer in the way */
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
/* no asoc destroyed */
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, stcb, 8);
@@ -4827,6 +4829,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
@@ -4860,10 +4863,12 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
if (from_inpcbfree == SCTP_NORMAL_PROC) {
atomic_add_int(&stcb->asoc.refcnt, 1);
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_INP_WLOCK(inp);
SCTP_TCB_LOCK(stcb);
+ SCTP_TCB_SEND_LOCK(stcb);
}
/* Double check the GONE flag */
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
@@ -4911,6 +4916,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_INP_INFO_WUNLOCK();
SCTP_INP_WUNLOCK(inp);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
return (0);
}
@@ -4942,7 +4948,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
* in case.
*/
/* anything on the wheel needs to be removed */
- SCTP_TCB_SEND_LOCK(stcb);
for (i = 0; i < asoc->streamoutcnt; i++) {
struct sctp_stream_out *outs;
@@ -4973,7 +4978,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
}
}
- SCTP_TCB_SEND_UNLOCK(stcb);
/* sa_ignore FREED_MEMORY */
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
@@ -5175,6 +5179,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* Insert new items here :> */
/* Get rid of LOCK */
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
--- sys/netinet/sctp_structs.h
+++ sys/netinet/sctp_structs.h
@@ -535,6 +535,7 @@ struct sctp_stream_queue_pending {
uint8_t sender_all_done;
uint8_t put_last_out;
uint8_t discard_rest;
+ uint8_t processing;
};
/*
--- sys/netinet/sctputil.c
+++ sys/netinet/sctputil.c
@@ -3921,7 +3921,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
}
void
-sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked
+sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
@@ -3947,9 +3947,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
return;
}
/* now through all the gunk freeing chunks */
- if (holds_lock == 0) {
- SCTP_TCB_SEND_LOCK(stcb);
- }
/* sent queue SHOULD be empty */
TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
@@ -4026,10 +4023,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
/* sa_ignore FREED_MEMORY */
}
}
-
- if (holds_lock == 0) {
- SCTP_TCB_SEND_UNLOCK(stcb);
- }
}
void
@@ -4053,8 +4046,11 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
return;
}
+ SCTP_TCB_SEND_LOCK(stcb);
+ SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
/* Tell them we lost the asoc */
- sctp_report_all_outbound(stcb, error, 0, so_locked);
+ sctp_report_all_outbound(stcb, error, so_locked);
+ SCTP_TCB_SEND_UNLOCK(stcb);
if (from_peer) {
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
} else {
@@ -4086,7 +4082,6 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (stcb != NULL) {
/* We have a TCB to abort, send notification too */
sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
/* Ok, now lets free it */
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
so = SCTP_INP_SO(inp);
@@ -4196,8 +4191,6 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
return;
- } else {
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
}
/* notify the peer */
sctp_send_abort_tcb(stcb, op_err, so_locked);
--- sys/netinet/sctputil.h
+++ sys/netinet/sctputil.h
@@ -166,7 +166,7 @@ void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
void sctp_stop_association_timers(struct sctp_tcb *, bool);
void
-sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int
+sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7xfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cKUoxAAkOwk5xE4BbVqudkxT2sTPG9kUbqMAATpS+F31u7s6R55sodqEB5gMjBn
vEF9poL2VXX2S316kfndP3sWgSOXxty3TF9ZPDajsTK3x4NTpWN2BB8nabsiqXx/
9lB9nEo2pNM2Iohmomj9tQ0+Mw0L5wmNUD+QH8D0hALkUQgqgPHmhSAn+w4bskxQ
EWBAYT4b7W/W5Mq+mo2QaOjI4zKQObbqEIZOOhyIFtxp08CZBKAxxG1fUPUgebtx
NYbiMr9JVrkFP1dCAWdFSnnixO2GILOAZt2YL/XNjwfYFEKC4gaEJy4wOBcTHAyT
corlrnj2t59p8ylzpSkq9QJECFyzFwb5VQeXqm7lYSxr0Cc8m8zm8PUtl3XNUxYC
yTttQ04W8Aj7BSOgOXuQPUFIVsRkrYYi33DtKyZktsMYzuY3ETZsRNY6w+mtfTVZ
M54bXblPaLvRHLaj0XpDDJ0FA3V3FsEbckTAUSSMhHvLhWGe0NOqPzLRlNco73X5
WnFEFX+tlBvL9z+6ZE5zp7sKopi74vPXNPz3Yw+tkUGHtBE9lfutKDe3EREpimAa
ej6u5Lv/X4fB74BrcaWp2fKWoO76FdjDsYPMzi+soJXAbm0VlV6+Fu2ROz59qjkP
Kk1tFQDlZKWR8P9/FRfgwrFeDdwQgg2sYsj4iRpqt94HfgJhWe4=
=8c9z
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,305 @@
--- sys/netinet/sctp_input.c
+++ sys/netinet/sctp_input.c
@@ -841,7 +841,6 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -1987,7 +1986,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* send up all the data */
SCTP_TCB_SEND_LOCK(stcb);
- sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
+ sctp_report_all_outbound(stcb, 0, SCTP_SO_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].chunks_on_queues = 0;
#if defined(SCTP_DETAILED_STR_STATS)
--- sys/netinet/sctp_output.c
+++ sys/netinet/sctp_output.c
@@ -13207,11 +13207,10 @@ sctp_lower_sosend(struct socket *so,
error = EINVAL;
goto out;
}
- SCTP_TCB_SEND_UNLOCK(stcb);
-
strm = &stcb->asoc.strmout[srcv->sinfo_stream];
if (strm->last_msg_incomplete == 0) {
do_a_copy_in:
+ SCTP_TCB_SEND_UNLOCK(stcb);
sp = sctp_copy_it_in(stcb, asoc, srcv, uio, net, max_len, user_marks_eor, &error);
if (error) {
goto out;
@@ -13237,13 +13236,11 @@ sctp_lower_sosend(struct socket *so,
if (sinfo_flags & SCTP_UNORDERED) {
SCTP_STAT_INCR(sctps_sends_with_unord);
}
+ sp->processing = 1;
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, asoc, strm, sp, 1);
- SCTP_TCB_SEND_UNLOCK(stcb);
} else {
- SCTP_TCB_SEND_LOCK(stcb);
sp = TAILQ_LAST(&strm->outqueue, sctp_streamhead);
- SCTP_TCB_SEND_UNLOCK(stcb);
if (sp == NULL) {
/* ???? Huh ??? last msg is gone */
#ifdef INVARIANTS
@@ -13255,7 +13252,16 @@ sctp_lower_sosend(struct socket *so,
goto do_a_copy_in;
}
+ if (sp->processing) {
+ SCTP_TCB_SEND_UNLOCK(stcb);
+ SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ error = EINVAL;
+ goto out;
+ } else {
+ sp->processing = 1;
+ }
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
while (uio->uio_resid > 0) {
/* How much room do we have? */
struct mbuf *new_tail, *mm;
@@ -13280,20 +13286,29 @@ sctp_lower_sosend(struct socket *so,
if (mm) {
sctp_m_freem(mm);
}
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
/* Update the mbuf and count */
SCTP_TCB_SEND_LOCK(stcb);
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
+ (stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
/*
* we need to get out. Peer probably
* aborted.
*/
sctp_m_freem(mm);
- if (stcb->asoc.state & SCTP_PCB_FLAGS_WAS_ABORTED) {
+ if (stcb->asoc.state & SCTP_STATE_WAS_ABORTED) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
error = ECONNRESET;
}
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
@@ -13353,6 +13368,11 @@ sctp_lower_sosend(struct socket *so,
/* wait for space now */
if (non_blocking) {
/* Non-blocking io in place out */
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto skip_out_eof;
}
/* What about the INIT, send it maybe */
@@ -13476,6 +13496,11 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
+ SCTP_TCB_SEND_LOCK(stcb);
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@@ -13485,12 +13510,19 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
+ SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if (sp != NULL) {
+ sp->processing = 0;
+ }
+ SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
}
SCTP_TCB_SEND_LOCK(stcb);
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
+ (stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@@ -13506,6 +13538,7 @@ sctp_lower_sosend(struct socket *so,
strm->last_msg_incomplete = 0;
asoc->stream_locked = 0;
}
+ sp->processing = 0;
} else {
SCTP_PRINTF("Huh no sp TSNH?\n");
strm->last_msg_incomplete = 0;
--- sys/netinet/sctp_pcb.c
+++ sys/netinet/sctp_pcb.c
@@ -4726,6 +4726,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* there is no asoc, really TSNH :-0 */
return (1);
}
+ SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.alternate) {
sctp_free_remote_addr(stcb->asoc.alternate);
stcb->asoc.alternate = NULL;
@@ -4760,6 +4761,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* nope, reader or writer in the way */
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
/* no asoc destroyed */
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, stcb, 8);
@@ -4857,6 +4859,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
@@ -4890,10 +4893,12 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
if (from_inpcbfree == SCTP_NORMAL_PROC) {
atomic_add_int(&stcb->asoc.refcnt, 1);
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_INP_WLOCK(inp);
SCTP_TCB_LOCK(stcb);
+ SCTP_TCB_SEND_LOCK(stcb);
}
/* Double check the GONE flag */
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
@@ -4941,6 +4946,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_INP_INFO_WUNLOCK();
SCTP_INP_WUNLOCK(inp);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
return (0);
}
@@ -4984,7 +4990,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
* in case.
*/
/* anything on the wheel needs to be removed */
- SCTP_TCB_SEND_LOCK(stcb);
for (i = 0; i < asoc->streamoutcnt; i++) {
struct sctp_stream_out *outs;
@@ -5015,7 +5020,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
}
}
- SCTP_TCB_SEND_UNLOCK(stcb);
/* sa_ignore FREED_MEMORY */
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
@@ -5217,6 +5221,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* Insert new items here :> */
/* Get rid of LOCK */
+ SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_TCB_UNLOCK(stcb);
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
--- sys/netinet/sctp_structs.h
+++ sys/netinet/sctp_structs.h
@@ -537,6 +537,7 @@ struct sctp_stream_queue_pending {
uint8_t sender_all_done;
uint8_t put_last_out;
uint8_t discard_rest;
+ uint8_t processing;
};
/*
--- sys/netinet/sctputil.c
+++ sys/netinet/sctputil.c
@@ -3870,7 +3870,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
}
void
-sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked
+sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
@@ -3896,9 +3896,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
return;
}
/* now through all the gunk freeing chunks */
- if (holds_lock == 0) {
- SCTP_TCB_SEND_LOCK(stcb);
- }
/* sent queue SHOULD be empty */
TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
@@ -3975,10 +3972,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
/* sa_ignore FREED_MEMORY */
}
}
-
- if (holds_lock == 0) {
- SCTP_TCB_SEND_UNLOCK(stcb);
- }
}
void
@@ -4002,8 +3995,11 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
return;
}
+ SCTP_TCB_SEND_LOCK(stcb);
+ SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
/* Tell them we lost the asoc */
- sctp_report_all_outbound(stcb, error, 0, so_locked);
+ sctp_report_all_outbound(stcb, error, so_locked);
+ SCTP_TCB_SEND_UNLOCK(stcb);
if (from_peer) {
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
} else {
@@ -4035,7 +4031,6 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (stcb != NULL) {
/* We have a TCB to abort, send notification too */
sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
/* Ok, now lets free it */
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
so = SCTP_INP_SO(inp);
@@ -4145,8 +4140,6 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
return;
- } else {
- SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
}
/* notify the peer */
sctp_send_abort_tcb(stcb, op_err, so_locked);
--- sys/netinet/sctputil.h
+++ sys/netinet/sctputil.h
@@ -165,7 +165,7 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
void
-sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int
+sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7xfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cKavRAAiV9zA8vimzM6KyMVIFfknivLA6Djf7qRG5bXLIkCAmYf0gQhBQGgw6V5
Vv08+Qc5GV9ze0019B5Fa9QAuKUdlfFQBSZU4y2p8LHZVFrWughafngbmR99YfcW
QW+A8SaNRfNSy3xP4X0CEMl6y5ozcHgzfKxwvsVqgV12YYuh38GMLxGf/hlUvjOi
uszC5h07iHZGLdgvoYWd/aeXdtcDjrJRKNCUVwym0FqD2MRZCnnt7P9qY5/D6bRF
XF3RmXNqjkr2qdOP4B5NxCIv3cng9fzF32fcDz2HHE51G97GgBevIOhBpivQ1uw4
j1hhrB/TmegbSgIY+9wWbMFo1Ht/iEmeSbjR3avp/NZRor5oNPa06zDI3L3orvC5
zWzs/972KwI07OziQ0oyFw6VqPEbGKlCJO0uAiiEMbU6+rMy+o8riK2a4vw/1ghx
UaL1P4j0trOio7Rg7TrjN/1dnnlpOYbk+oNTqskS6VttpE+spYB5gQuJk0EM7wlp
U7Mlls5e1C9kL4qPamkoc+lmI8luURGVqj3rZMa4zI9JIR9G5aBaIViMNYN/xtTi
r1vw0jeWlKkIpCN1EsncR5n1PPkorfTgOEDFZ9Gn3YpVj5RtcAhqSBJV3nO40s8h
1jt0s5DbEl5Bw23uJ3HdHCYesmh7Vdlsr9OL6VUpjHqQB6gtjRA=
=xJcD
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,11 @@
--- sbin/dhclient/options.c.orig
+++ sbin/dhclient/options.c
@@ -298,6 +298,8 @@
pointed_len = find_search_domain_name_len(option,
&pointer);
+ if (pointed_len < 0)
+ return (-1);
domain_name_len += pointed_len;
*offset = i + 2;

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl9Py7xfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cIg5w/+LEbHcWU+OeVBAhzwQsZ7LI5IJ2eigcv32KHXnX4gfd1E+9obvR6Pi6AX
XPMlm4WJH5YoYm+TEkPsIzPp8iXh1KPNJdYk8W0m0U6QJVCR1eMMV7cyCo+rtk5L
HNqHqVJRakVxAm6AapNXZodWX/kkyVCl9UK6N/fq0lTef6yV0CUXfmpNehCzRUqo
88fcfaYZq8zzJJoU2iiuWlq07qjMDHsvazdpNMuWZqMaQl4JqRGRUAHnGG2OiJZC
RNzvwkGk/bG4M7fgNQtcRriJAhM63rVkV9DzKqExHFPtdL3TiBgsKt1G6PwaH/z0
iMwWRvjo+WljBK5cxkELLsZWsTVmc8QFBZlDTYPfuqsNLNHPN15o73J526+X0Pro
5ERaxGsyia4bfmLV3D1rmXSMOcvtFjVR2zIpyje/glNumQa/aDn47ECHKQ3hEndf
AM2QqT7SJDg/zgh71/Zmt5cfPX7ISlnn8fIryH4+zbY4p0STy9ZrzRsrihtI6lVK
w4AUk9zTziFbFcUoQWq18x3NHE2F0XkwLb2EduUbYa/gs4X4kmCqNTxQeFeoRILZ
Da21t68bLeXWfMIRKeJ1hsu0rXt0NJxjtnlfXvvA6L+arGS8RW7a+ta0AgM7aH7m
Y+X4d87ixkMnaKhdV7WtMyKSYTvs6EGEJQFbObkqZiv5HdC1X+k=
=BvcT
-----END PGP SIGNATURE-----

View file

@ -7,6 +7,27 @@
<year>
<name>2020</name>
<month>
<name>9</name>
<day>
<name>2</name>
<advisory>
<name>FreeBSD-SA-20:26.dhclient</name>
</advisory>
<advisory>
<name>FreeBSD-SA-20:25.sctp</name>
</advisory>
<advisory>
<name>FreeBSD-SA-20:24.ipv6</name>
</advisory>
</day>
</month>
<month>
<name>8</name>

View file

@ -7,6 +7,23 @@
<year>
<name>2020</name>
<month>
<name>9</name>
<day>
<name>2</name>
<notice>
<name>FreeBSD-EN-20:18.getfsstat</name>
</notice>
<notice>
<name>FreeBSD-EN-20:17.linuxthread</name>
</notice>
</day>
</month>
<month>
<name>8</name>