Hi,

TCP timers also shift undefined values.

kubsan: netinet/tcp_input.c:1027:4: shift: left shift of 67108864
by 5 places cannot be represented in type 'int'

The problem is hidden behind a bunch of macros:

                        TCP_SETUP_ACK(tp, tiflags, m);

#define TCP_SETUP_ACK(tp, tiflags, m) \
do { \
        struct ifnet *ifp = NULL; \
        if (m && (m->m_flags & M_PKTHDR)) \
                ifp = if_get(m->m_pkthdr.ph_ifidx); \
        if (TCP_TIMER_ISARMED(tp, TCPT_DELACK) || \
            (tcp_ack_on_push && (tiflags) & TH_PUSH) || \
            (ifp && (ifp->if_flags & IFF_LOOPBACK))) \
                tp->t_flags |= TF_ACKNOW; \
        else \
                TCP_TIMER_ARM_MSEC(tp, TCPT_DELACK, tcp_delack_msecs); \
        if_put(ifp); \
} while (0)

#define TCPT_REXMT      0               /* retransmit */
#define TCPT_PERSIST    1               /* retransmit persistence */
#define TCPT_KEEP       2               /* keep alive */
#define TCPT_2MSL       3               /* 2*msl quiet time timer */
#define TCPT_REAPER     4               /* delayed cleanup timeout */
#define TCPT_DELACK     5               /* delayed ack timeout */
#define TCPT_NTIMERS    6

#define TCP_TIMER_ISARMED(tp, timer)                                    \
        ISSET((tp)->t_flags, TF_TIMER << (timer))

#define TF_TMR_REXMT    0x04000000      /* retransmit timer armed */
#define TF_TMR_PERSIST  0x08000000      /* retransmit persistence timer armed */
#define TF_TMR_KEEP     0x10000000      /* keep alive timer armed */
#define TF_TMR_2MSL     0x20000000      /* 2*msl quiet time timer armed */
#define TF_TMR_REAPER   0x40000000      /* delayed cleanup timer armed, dead */
#define TF_TMR_DELACK   0x80000000      /* delayed ack timer armed */
#define TF_TIMER       TF_TMR_REXMT    /* used to shift with TCPT values */

To get the DELACK flag, shift the REXMT flag to the left by 5.
0x04000000 is converted to 0x80000000 by left shifting.  This affects
the sign bit and is undefined behavior.

An unsinged TF_TIMER does not create that problem.

ok?

bluhm

Index: netinet/tcp_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.136
diff -u -p -r1.136 tcp_var.h
--- netinet/tcp_var.h   28 Jan 2021 14:53:20 -0000      1.136
+++ netinet/tcp_var.h   20 Jan 2022 17:55:54 -0000
@@ -104,7 +104,7 @@ struct tcpcb {
 #define TF_TMR_2MSL    0x20000000      /* 2*msl quiet time timer armed */
 #define TF_TMR_REAPER  0x40000000      /* delayed cleanup timer armed, dead */
 #define TF_TMR_DELACK  0x80000000      /* delayed ack timer armed */
-#define TF_TIMER       TF_TMR_REXMT    /* used to shift with TCPT values */
+#define TF_TIMER ((unsigned)TF_TMR_REXMT) /* used to shift with TCPT values */
 
        struct  mbuf *t_template;       /* skeletal packet for transmit */
        struct  inpcb *t_inpcb;         /* back pointer to internet pcb */

Reply via email to