NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/60486: tcp syncache leaks 4-byte kernel stack content
>Number: 60486
>Category: kern
>Synopsis: tcp syncache leaks 4-byte kernel stack content
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jul 23 17:40:00 +0000 2026
>Originator: Taylor R Campbell
>Release: current, 11, 10, 9, ...
>Organization:
The NetTCP Leakstacktion, Inc.
>Environment:
>Description:
The tcp syncache logic can leak a four-byte section of kernel
stack memory to the network.
877 syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
878 unsigned int toff, struct socket *so, struct mbuf *m, u_char *optp,
879 int optlen, struct tcp_opt_info *oi)
880 {
881 struct tcpcb tb, *tp;
...
897 #ifdef TCP_SIGNATURE
898 if (optp || (tp->t_flags & TF_SIGNATURE))
899 #else
900 if (optp)
901 #endif
902 {
903 tb.t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
904 #ifdef TCP_SIGNATURE
905 tb.t_flags |= (tp->t_flags & TF_SIGNATURE);
906 #endif
907 tb.t_state = TCPS_LISTEN;
908 if (tcp_dooptions(&tb, optp, optlen, th, m, toff, oi) < 0)
909 return 0;
910 } else
911 tb.t_flags = 0;
...
938 sc->sc_timestamp = tb.ts_recent;
...
940 if (syn_cache_respond(sc) == 0) {
https://nxr.netbsd.org/xref/src/sys/netinet/tcp_syncache.c#863
Not all paths to
938 sc->sc_timestamp = tb.ts_recent;
initialize tb.ts_recent, so it may be uninitialized data from
the kernel stack. This may be then sent out on the wire in
syn_cache_respond:
1075 syn_cache_respond(struct syn_cache *sc)
1076 {
...
1115 /*
1116 * Create the IP+TCP header from scratch.
1117 */
1118 MGETHDR(m, M_DONTWAIT, MT_DATA);
...
1172 optp = (u_int8_t *)(th + 1);
...
1138 case AF_INET:
1139 ip = mtod(m, struct ip *);
...
1144 th = (struct tcphdr *)(ip + 1);
...
1149 case AF_INET6:
1150 ip6 = mtod(m, struct ip6_hdr *);
...
1156 th = (struct tcphdr *)(ip6 + 1);
...
1172 optp = (u_int8_t *)(th + 1);
...
1195 if (sc->sc_flags & SCF_TIMESTAMP) {
...
1202 u_int32_t *lp = (u_int32_t *)(optp);
...
=> 1205 *lp = htonl(sc->sc_timestamp);
...
1208 }
...
1337 case AF_INET:
1338 error = ip_output(m, sc->sc_ipopts, ro,
...
1348 error = ip6_output(m, NULL /*XXX*/, ro, 0, NULL,
https://nxr.netbsd.org/xref/src/sys/netinet/tcp_syncache.c#1068
Forwarded to us by Chris Jarrett-Davies <chrisjd%openai.com@localhost>.
>How-To-Repeat:
do a retransmitted SYN/ACK dance with syncache
>Fix:
memset(&tb, 0, sizeof(tb)) will rule it out, at some cost to
performance under load, since this is a ~800-byte structure.
Could try to be more selective about initialization, or about
when we set sc->sc_timestamp = tb.ts_recent.n
Home |
Main Index |
Thread Index |
Old Index