Commit 03c77793 authored by HardenedBSD Sync Service's avatar HardenedBSD Sync Service
Browse files

Merge branch 'freebsd/current/main' into hardened/current/master

parents 231b4486 9a669553
......@@ -10,16 +10,16 @@ newline. Entries should be separated by a newline.
Changes to this file should not be MFCed.
d410b585b6f:
d410b585b6f0:
sh(1) is now the default shell for the root user.
396851c20ae:
396851c20aeb:
libncursesw has been split into libtinfow and libncursesw, linker
scripts should make it transparent for consumers. pkg-config files
are also now installed to ease ports detecting the ncurses setup from
base.
422084abbda:
a422084abbda:
LLVM's MemorySanitizer can now be used in amd64 kernels. See the
kmsan(9) manual page for more information.
......
News for the tz database
Release 2021e - 2021-10-21 18:41:00 -0700
Changes to future timestamps
Palestine will fall back 10-29 (not 10-30) at 01:00.
(Thanks to P Chan and Heba Hemad.)
Release 2021d - 2021-10-15 13:48:18 -0700
Briefly:
......
......@@ -3386,11 +3386,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# shall [end] on Oct 24th 2020 at 01:00AM by delaying the clock by 60 minutes.
# http://www.palestinecabinet.gov.ps/portal/Meeting/Details/51584
# From Tim Parenti (2020-10-20):
# Predict future fall transitions at 01:00 on the Saturday preceding October's
# last Sunday (i.e., Sat>=24). This is consistent with our predictions since
# 2016, although the time of the change differed slightly in 2019.
# From Pierre Cashon (2020-10-20):
# The summer time this year started on March 28 at 00:00.
# https://wafa.ps/ar_page.aspx?id=GveQNZa872839351758aGveQNZ
......@@ -3403,6 +3398,17 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# For now, guess spring-ahead transitions are at 00:00 on the Saturday
# preceding March's last Sunday (i.e., Sat>=24).
# From P Chan (2021-10-18):
# http://wafa.ps/Pages/Details/34701
# Palestine winter time will start from midnight 2021-10-29 (Thursday-Friday).
#
# From Heba Hemad, Palestine Ministry of Telecom & IT (2021-10-20):
# ... winter time will begin in Palestine from Friday 10-29, 01:00 AM
# by 60 minutes backwards.
#
# From Paul Eggert (2021-10-20):
# Guess future fall transitions on October's last Friday at 01:00.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 -
......@@ -3438,7 +3444,8 @@ Rule Palestine 2016 2018 - Oct Sat>=24 1:00 0 -
Rule Palestine 2019 only - Mar 29 0:00 1:00 S
Rule Palestine 2019 only - Oct Sat>=24 0:00 0 -
Rule Palestine 2020 max - Mar Sat>=24 0:00 1:00 S
Rule Palestine 2020 max - Oct Sat>=24 1:00 0 -
Rule Palestine 2020 only - Oct 24 1:00 0 -
Rule Palestine 2021 max - Oct lastFri 1:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
......
......@@ -3303,12 +3303,15 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
*/
bzero(&rxs, sizeof(rxs));
rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
rxs.r_flags |= IEEE80211_R_BAND;
rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
rxs.c_ieee = le16toh(phy_info->channel);
if (le16toh(phy_info->phy_flags & IWM_RX_RES_PHY_FLAGS_BAND_24)) {
rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, IEEE80211_CHAN_2GHZ);
rxs.c_band = IEEE80211_CHAN_2GHZ;
} else {
rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, IEEE80211_CHAN_5GHZ);
rxs.c_band = IEEE80211_CHAN_5GHZ;
}
/* rssi is in 1/2db units */
......@@ -3414,10 +3417,12 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
*/
bzero(&rxs, sizeof(rxs));
rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
rxs.r_flags |= IEEE80211_R_BAND;
rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
rxs.c_ieee = channel;
rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee,
channel <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
rxs.c_band = channel <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ;
/* rssi is in 1/2db units */
rxs.c_rssi = rssi * 2;
......
......@@ -240,8 +240,10 @@ r88e_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
if (!sc->sc_ht40) { /* XXX center channel */
rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
rxs->r_flags |= IEEE80211_R_BAND;
rxs->c_ieee = physt->chan;
rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
IEEE80211_CHAN_2GHZ);
rxs->c_band = IEEE80211_CHAN_2GHZ;
}
}
......@@ -321,8 +321,10 @@ r12a_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
*/
#if 0
rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
rxs->r_flags |= IEEE80211_R_BAND;
rxs->c_ieee = MS(le16toh(physt->phyw1), R12A_PHYW1_CHAN);
rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
(rxs->c_ieee < 36) ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
rxs->c_band = (rxs->c_ieee < 36) ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ;
#endif
}
......@@ -2081,9 +2081,11 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
/* Set channel flags for input path */
bzero(&rxs, sizeof(rxs));
rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
rxs.r_flags |= IEEE80211_R_BAND;
rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
rxs.c_ieee = le32toh(bss->config.dsconfig);
rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, IEEE80211_CHAN_2GHZ);
rxs.c_band = IEEE80211_CHAN_2GHZ;
/* This is a number from 0..100; so let's just divide it down a bit */
rxs.c_rssi = le32toh(bss->rssi) / 2;
rxs.c_nf = -96;
......
......@@ -612,6 +612,9 @@ struct ieee80211_rx_stats {
uint8_t c_ieee; /* Channel */
uint8_t c_width; /* channel width, FW flags above */
/* 32 bits */
uint32_t c_band; /* Band; XXX we do not have a real band. */
/* Force alignment to DWORD */
union {
uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
......
......@@ -1818,6 +1818,8 @@ ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
return (NULL);
if ((rxs->r_flags & IEEE80211_R_IEEE) == 0)
return (NULL);
if ((rxs->r_flags & IEEE80211_R_BAND) == 0)
return (NULL);
/*
* If the rx status contains a valid ieee/freq, then
......@@ -1828,11 +1830,20 @@ ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
*/
/* Determine a band */
/* XXX should be done by the driver? */
if (rxs->c_freq < 3000) {
switch (rxs->c_band) {
case IEEE80211_CHAN_2GHZ:
flags = IEEE80211_CHAN_G;
} else {
break;
case IEEE80211_CHAN_5GHZ:
flags = IEEE80211_CHAN_A;
break;
default:
if (rxs->c_freq < 3000) {
flags = IEEE80211_CHAN_G;
} else {
flags = IEEE80211_CHAN_A;
}
break;
}
/* Channel lookup */
......
......@@ -320,6 +320,8 @@ static u_int pf_purge_expired_states(u_int, int);
static void pf_purge_unlinked_rules(void);
static int pf_mtag_uminit(void *, int, int);
static void pf_mtag_free(struct m_tag *);
static void pf_packet_rework_nat(struct mbuf *, struct pf_pdesc *,
int, struct pf_state_key *);
#ifdef INET
static void pf_route(struct mbuf **, struct pf_krule *, int,
struct ifnet *, struct pf_kstate *,
......@@ -341,6 +343,16 @@ extern struct proc *pf_purge_proc;
VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]);
#define PACKET_UNDO_NAT(_m, _pd, _off, _s, _dir) \
do { \
struct pf_state_key *nk; \
if ((_dir) == PF_OUT) \
nk = (_s)->key[PF_SK_STACK]; \
else \
nk = (_s)->key[PF_SK_WIRE]; \
pf_packet_rework_nat(_m, _pd, _off, nk); \
} while (0)
#define PACKET_LOOPED(pd) ((pd)->pf_mtag && \
(pd)->pf_mtag->flags & PF_PACKET_LOOPED)
......@@ -446,6 +458,83 @@ pf_addr_cmp(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
return (0);
}
static void
pf_packet_rework_nat(struct mbuf *m, struct pf_pdesc *pd, int off,
struct pf_state_key *nk)
{
switch (pd->proto) {
case IPPROTO_TCP: {
struct tcphdr *th = &pd->hdr.tcp;
if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af))
pf_change_ap(m, pd->src, &th->th_sport, pd->ip_sum,
&th->th_sum, &nk->addr[pd->sidx],
nk->port[pd->sidx], 0, pd->af);
if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af))
pf_change_ap(m, pd->dst, &th->th_dport, pd->ip_sum,
&th->th_sum, &nk->addr[pd->didx],
nk->port[pd->didx], 0, pd->af);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
break;
}
case IPPROTO_UDP: {
struct udphdr *uh = &pd->hdr.udp;
if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af))
pf_change_ap(m, pd->src, &uh->uh_sport, pd->ip_sum,
&uh->uh_sum, &nk->addr[pd->sidx],
nk->port[pd->sidx], 1, pd->af);
if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af))
pf_change_ap(m, pd->dst, &uh->uh_dport, pd->ip_sum,
&uh->uh_sum, &nk->addr[pd->didx],
nk->port[pd->didx], 1, pd->af);
m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
break;
}
case IPPROTO_ICMP: {
struct icmp *ih = &pd->hdr.icmp;
if (nk->port[pd->sidx] != ih->icmp_id) {
pd->hdr.icmp.icmp_cksum = pf_cksum_fixup(
ih->icmp_cksum, ih->icmp_id,
nk->port[pd->sidx], 0);
ih->icmp_id = nk->port[pd->sidx];
pd->sport = &ih->icmp_id;
m_copyback(m, off, ICMP_MINLEN, (caddr_t)ih);
}
/* FALLTHROUGH */
}
default:
if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af)) {
switch (pd->af) {
case AF_INET:
pf_change_a(&pd->src->v4.s_addr,
pd->ip_sum, nk->addr[pd->sidx].v4.s_addr,
0);
break;
case AF_INET6:
PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af);
break;
}
}
if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af)) {
switch (pd->af) {
case AF_INET:
pf_change_a(&pd->dst->v4.s_addr,
pd->ip_sum, nk->addr[pd->didx].v4.s_addr,
0);
break;
case AF_INET6:
PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af);
break;
}
}
break;
}
}
static __inline uint32_t
pf_hashkey(struct pf_state_key *sk)
{
......@@ -5937,6 +6026,11 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
error = EMSGSIZE;
KMOD_IPSTAT_INC(ips_cantfrag);
if (r->rt != PF_DUPTO) {
if (s && pd->nat_rule != NULL)
PACKET_UNDO_NAT(m0, pd,
(ip->ip_hl << 2) + (ip_off & IP_OFFMASK),
s, dir);
icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
ifp->if_mtu);
goto done;
......@@ -6104,9 +6198,14 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
nd6_output_ifp(ifp, ifp, m0, &dst, NULL);
else {
in6_ifstat_inc(ifp, ifs6_in_toobig);
if (r->rt != PF_DUPTO)
if (r->rt != PF_DUPTO) {
if (s && pd->nat_rule != NULL)
PACKET_UNDO_NAT(m0, pd,
((caddr_t)ip6 - m0->m_data) +
sizeof(struct ip6_hdr), s, dir);
icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
else
} else
goto bad;
}
......
......@@ -16,10 +16,12 @@ ATF_TESTS_SH+= \
${PACKAGE}FILES+= \
utils.subr \
runner.subr \
pft_icmp_check.py \
pft_ping.py \
pft_synflood.py \
sniffer.py
${PACKAGE}FILESMODE_pft_icmp_check.py= 0555
${PACKAGE}FILESMODE_pft_ping.py= 0555
${PACKAGE}FILESMODE_pft_synflood.py= 0555
......
#!/usr/bin/env python3
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Rubicon Communications, LLC (Netgate)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
import argparse
import logging
logging.getLogger("scapy").setLevel(logging.CRITICAL)
import random
import scapy.all as sp
import socket
import sys
from sniffer import Sniffer
PAYLOAD_MAGIC = bytes.fromhex('42c0ffee')
def ping(send_if, dst_ip, args):
ether = sp.Ether()
ip = sp.IP(dst=dst_ip, src=args.fromaddr[0])
icmp = sp.ICMP(type='echo-request')
raw = sp.raw(PAYLOAD_MAGIC * 250) # We want 1000 bytes payload, -ish
ip.flags = 2 # Don't fragment
icmp.seq = random.randint(0, 65535)
args.icmp_seq = icmp.seq
req = ether / ip / icmp / raw
sp.sendp(req, iface=send_if, verbose=False)
def check_icmp_too_big(args, packet):
"""
Verify that this is an ICMP packet too big error, and that the IP addresses
in the payload packet match expectations.
"""
icmp = packet.getlayer(sp.ICMP)
if not icmp:
return False
if not icmp.type == 3:
return False
ip = packet.getlayer(sp.IPerror)
if not ip:
return False
if ip.src != args.fromaddr[0]:
print("Incorrect src addr %s" % ip.src)
return False
if ip.dst != args.to[0]:
print("Incorrect dst addr %s" % ip.dst)
return False
icmp2 = packet.getlayer(sp.ICMPerror)
if not icmp2:
print("IPerror doesn't contain ICMP")
return False
if icmp2.seq != args.icmp_seq:
print("Incorrect icmp seq %d != %d" % (icmp2.seq, args.icmp_seq))
return False
return True
def main():
parser = argparse.ArgumentParser("pft_icmp_check.py",
description="ICMP error validation tool")
parser.add_argument('--to', nargs=1, required=True,
help='The destination IP address')
parser.add_argument('--fromaddr', nargs=1, required=True,
help='The source IP address')
parser.add_argument('--sendif', nargs=1, required=True,
help='The interface through which the packet(s) will be sent')
parser.add_argument('--recvif', nargs=1,
help='The interface on which to expect the ICMP error')
args = parser.parse_args()
sniffer = None
if not args.recvif is None:
sniffer = Sniffer(args, check_icmp_too_big)
ping(args.sendif[0], args.to[0], args)
if sniffer:
sniffer.join()
if sniffer.foundCorrectPacket:
sys.exit(0)
else:
sys.exit(1)
if __name__ == '__main__':
main()
......@@ -27,6 +27,8 @@
. $(atf_get_srcdir)/utils.subr
common_dir=$(atf_get_srcdir)/../common
atf_test_case "v4" "cleanup"
v4_head()
{
......@@ -250,10 +252,67 @@ multiwanlocal_cleanup()
pft_cleanup
}
atf_test_case "icmp_nat" "cleanup"
icmp_nat_head()
{
atf_set descr 'Test that ICMP packets are correct for route-to + NAT'
atf_set require.user root
}
icmp_nat_body()
{
pft_init
epair_one=$(vnet_mkepair)
epair_two=$(vnet_mkepair)
epair_three=$(vnet_mkepair)
vnet_mkjail gw ${epair_one}b ${epair_two}a ${epair_three}a
vnet_mkjail srv ${epair_two}b
vnet_mkjail srv2 ${epair_three}b
ifconfig ${epair_one}a 192.0.2.2/24 up
route add -net 198.51.100.0/24 192.0.2.1
jexec gw sysctl net.inet.ip.forwarding=1
jexec gw ifconfig ${epair_one}b 192.0.2.1/24 up
jexec gw ifconfig ${epair_two}a 198.51.100.1/24 up
jexec gw ifconfig ${epair_three}a 203.0.113.1/24 up mtu 500
jexec srv ifconfig ${epair_two}b 198.51.100.2/24 up
jexec srv route add default 198.51.100.1
jexec srv2 ifconfig ${epair_three}b 203.0.113.2/24 up mtu 500
jexec srv2 route add default 203.0.113.1
# Sanity check
atf_check -s exit:0 -o ignore ping -c 1 198.51.100.2
jexec gw pfctl -e
pft_set_rules gw \
"nat on ${epair_two}a inet from 192.0.2.0/24 to any -> (${epair_two}a)" \
"nat on ${epair_three}a inet from 192.0.2.0/24 to any -> (${epair_three}a)" \
"pass out route-to (${epair_three}a 203.0.113.2) proto icmp icmp-type echoreq"
# Now ensure that we get an ICMP error with the correct IP addresses in it.
atf_check -s exit:0 ${common_dir}/pft_icmp_check.py \
--to 198.51.100.2 \
--fromaddr 192.0.2.2 \
--recvif ${epair_one}a \
--sendif ${epair_one}a
# ping reports the ICMP error, so check of that too.
atf_check -s exit:2 -o match:'frag needed and DF set' \
ping -D -c 1 -s 1000 198.51.100.2
}
icmp_nat_cleanup()
{
pft_cleanup
}
atf_init_test_cases()
{
atf_add_test_case "v4"
atf_add_test_case "v6"
atf_add_test_case "multiwan"
atf_add_test_case "multiwanlocal"
atf_add_test_case "icmp_nat"
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment