A sockaddr with invalid length could be passed to the network stack resulting in
a kernel panic like this:
panic: sockaddr_copy: source too long, 28 < 128 bytes
fatal breakpoint trap in supervisor mode
trap type 1 code 0 rip 0xffffffff80216c35 cs 0x8 rflags 0x246 cr2 0x7f7ff7ef3000 ilevel 0x4 rsp 0xffff80003308b690
curlwp 0xfffffe803e11ca40 pid 48.1 lowest kstack 0xffff8000330852c0
Stopped in pid 48.1 (a.out) at netbsd:breakpoint+0x5: leave
db{1}> bt
breakpoint() at netbsd:breakpoint+0x5
vpanic() at netbsd:vpanic+0x140
panic() at netbsd:panic+0x3c
sockaddr_copy() at netbsd:sockaddr_copy+0x95
rtcache_setdst() at netbsd:rtcache_setdst+0x73
rtcache_lookup2() at netbsd:rtcache_lookup2+0x56
in6_selectroute() at netbsd:in6_selectroute+0x184
in6_selectsrc() at netbsd:in6_selectsrc+0x119
udp6_output() at netbsd:udp6_output+0x25e
udp6_send_wrapper() at netbsd:udp6_send_wrapper+0x8a
sosend() at netbsd:sosend+0x7bf
do_sys_sendmsg_so() at netbsd:do_sys_sendmsg_so+0x28e
do_sys_sendmsg() at netbsd:do_sys_sendmsg+0x89
sys_sendto() at netbsd:sys_sendto+0x5c
syscall() at netbsd:syscall+0x1ed
--- syscall (number 133) ---
7f7ff790173a:
Reported by Paul Ripke
in6_selectsrc previously returned a pointer to an ipv6 address,
the pointer was NULL in case of an error and is checked later
instead of the also returned error code. When in6_selectsrc was
changed to store the address into a buffer, the error code
was still ignored, but the buffer pointer was never set to NULL.
As a result send() to an ipv6 address on a system that isn't
configured for ipv6 no longer returns the expected EADDRAVAIL
but fails later in ip6_output with EOPNOTSUPP when trying to
send from an unspecified address. The wrong error code caused
BIND to log the unexpected errors.
Some callers of rtrequest1(RTM_ADD) adjust rt_ifa of an rtentry created by
rtrequest1 that may change rt_ifa (in ifa_rtrequest) with another ifa that is
different from requested one. It's wasteful and even worse introduces a race
condition. rtrequest1 should just use a passed ifa as is if a caller hopes so.
The 4th argument for in[46]_cksum() should be length of L4 header +
L4 payload. The previous revisions are wrong
- for IPv4 when hdrlen != 0
- for IPv6 always
These functions are used only in net/if_loop.c and
arch/powerpc/booke/dev/pq3etsec.c under some special circumferences.
This should be why the bugs have not been found until today.
OK maxv
These functions are defined on unsigned int. The generic name
min/max should not silently truncate to 32 bits on 64-bit systems.
This is purely a name change -- no functional change intended.
HOWEVER! Some subsystems have
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
even though our standard name for that is MIN/MAX. Although these
may invite multiple evaluation bugs, these do _not_ cause integer
truncation.
To avoid `fixing' these cases, I first changed the name in libkern,
and then compile-tested every file where min/max occurred in order to
confirm that it failed -- and thus confirm that nothing shadowed
min/max -- before changing it.
I have left a handful of bootloaders that are too annoying to
compile-test, and some dead code:
cobalt ews4800mips hp300 hppa ia64 luna68k vax
acorn32/if_ie.c (not included in any kernels)
macppc/if_gm.c (superseded by gem(4))
It should be easy to fix the fallout once identified -- this way of
doing things fails safe, and the goal here, after all, is to _avoid_
silent integer truncations, not introduce them.
Maybe one day we can reintroduce min/max as type-generic things that
never silently truncate. But we should avoid doing that for a while,
so that existing code has a chance to be detected by the compiler for
conversion to uimin/uimax without changing the semantics until we can
properly audit it all. (Who knows, maybe in some cases integer
truncation is actually intended!)
When the following operations are done after established session, the l2tp0
cannot receive packets until done deletetunnel && tunnel "src" "dst".
====================
ifconfig l2tp0 deletesession
ifconfig l2tp0 deletecookie
ifconfig l2tp0 session 200 100
====================
XXX pullup-8
- Remove unused *_NAMES macros for sysctl.
- Remove unused *_MAXID for sysctls.
- Move CTL_MACHDEP sysctl definitions for m68k into m68k/include/cpu.h and
use them on all m68k machines.
ip6_undefer_csum -> in6_undefer_cksum
in6_delayed_cksum -> in6_undefer_cksum_tcpudp
The two previous names were inconsistent and misleading.
Put the two functions into in6_offload.c. Add comments to explain what
we're doing.
Same as IPv4.
Replace calculation of maxexpire (TIME_MAX) with a construct that triggers
UB with a one that uses implementation defined semantics.
No functional change intended.
An attempt to appease KUBSAn.
Detected with Kernel Undefined Behavior Sanitizer.
Reported by <Harry Pantazis>
When rip_input() is called as inetsw[].pr_input, rip_iput() is always called
with holding softnet_lock, that is, in case of !defined(NET_MPSAFE) it is
acquired in ipintr(), otherwise(defined(NET_MPSAFE)) it is acquire in
PR_WRAP_INPUT macro.
However, some function calls rip_input() directly without holding softnet_lock.
That causes assertion failure in sbappendaddr().
rip6_input() and icmp6_rip6_input() are also required softnet_lock for the same
reason.
M_CSUM_DATA_IPv6_HL -> M_CSUM_DATA_IPv6_IPHL
M_CSUM_DATA_IPv6_HL_SET -> M_CSUM_DATA_IPv6_SET
Reduces the diff against IPv4. Also, clarify the definitions.
A rt_timer handler is passed a rtentry with an extra reference that avoids the
rtentry is accidentally released. So rt_timer handers must release the reference
of a passed rtentry by themselves (but they didn't).
in6m_refcount of an in6m can be incremented if the in6m is on the list
(if_multiaddrs) in in6_addmulti or mld_input. So we must avoid such an
increment when we try to destroy an in6m. To this end we must make
an in6m_refcount decrement and a removal of an in6m from if_multiaddrs
atomic.
to the same IPsec processing. That is to say, that all fragments are ESP,
or AH, or AH+ESP, or none.
The reassembly mechanism can be used both on the wire and inside an IPsec
tunnel, so we need to make sure all fragments of a packet were received
on only one side.
Even though I haven't tried, I believe there are configurations where it
would be possible for an attacker to inject an unencrypted fragment into a
legitimate stream of already-decrypted-and-authenticated fragments.
Typically on IPsec gateways with ESP tunnels, where we can encapsulate
fragments (as opposed to the general case, where we fragment encapsulated
data).
Note, for the record: a funnier thing, under IPv4, would be to send a
zero-sized !MFF fragment at the head of the packet, and manage to trigger
an ICMP error; M_DECRYPTED gets lost by the reassembly, and ICMP will reply
with the packet in clear (not encrypted).
a bool for clarity. Optimize the function: if M_CANFASTFWD is not there
(because already removed by the firewall) leave now.
Makes it easier to see that M_CANFASTFWD is not removed on IPv6.
m_copym(m, 0, M_COPYALL, M_DONTWAIT)
by
m_copypacket(m, M_DONTWAIT)
when it is clear that we are copying a packet (that has M_PKTHDR) and not
a raw mbuf chain.