NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/58636: npf(7): unnecessary time precision
>Number: 58636
>Category: kern
>Synopsis: npf(7): unnecessary time precision
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Aug 24 21:00:00 +0000 2024
>Originator: Taylor R Campbell
>Release: current, 10, 9, ...
>Organization:
The NpfBSD32 Foundation
>Environment:
>Description:
npf uses getnanouptime/.tv_sec to record a 32-bit timestamp:
274 static inline void
275 conn_update_atime(npf_conn_t *con)
276 {
277 struct timespec tsnow;
278
279 getnanouptime(&tsnow);
280 atomic_store_relaxed(&con->c_atime, tsnow.tv_sec);
281 }
https://nxr.netbsd.org/xref/src/sys/net/npf/npf_conn.c?r=1.35#274
It uses this to determine when connection state has expired:
709 /*
710 * npf_conn_expired: criterion to check if connection is expired.
711 */
712 bool
713 npf_conn_expired(npf_t *npf, const npf_conn_t *con, uint64_t tsnow)
714 {
715 const unsigned flags = atomic_load_relaxed(&con->c_flags);
716 const int etime = npf_state_etime(npf, &con->c_state, con->c_proto);
717 int elapsed;
718
719 if (__predict_false(flags & CONN_EXPIRE)) {
720 /* Explicitly marked to be expired. */
721 return true;
722 }
723
724 /*
725 * Note: another thread may update 'atime' and it might
726 * become greater than 'now'.
727 */
728 elapsed = (int64_t)tsnow - atomic_load_relaxed(&con->c_atime);
729 return elapsed > etime;
730 }
https://nxr.netbsd.org/xref/src/sys/net/npf/npf_conn.c?r=1.35#709
But the timeouts are all at most 31-bit, and these are all relative times. So there's no need to do any 64-bit arithmetic anywhere.
This confuses coverity into thinking there is a y2k38 safety bug:
*** CID 1597779: High impact quality (Y2K38_SAFETY)
/sys/net/npf/npf_conn.c: 280 in conn_update_atime()
274 static inline void
275 conn_update_atime(npf_conn_t *con)
276 {
277 struct timespec tsnow;
278
279 getnanouptime(&tsnow);
>>> CID 1597779: High impact quality (Y2K38_SAFETY)
>>> A "time_t" value is stored in an integer with too few bits to accommodate it. The expression "tsnow.tv_sec" is cast to "uint32_t".
280 atomic_store_relaxed(&con->c_atime, tsnow.tv_sec);
281 }
282
283 /*
284 * npf_conn_check: check that:
285 *
>How-To-Repeat:
code inspection
>Fix:
1. Use time_uptime32 instead of getnanouptime/.tv_sec.
2. Use uint32_t for everything here (and maybe assert the timeout is below INT32_MAX so wraparound is definitely not an issue).
3. Maybe file a PR at https://github.com/rmind/npf too.
Home |
Main Index |
Thread Index |
Old Index