Module Name: src
Committed By: martin
Date: Sun Sep 7 11:50:23 UTC 2014
Modified Files:
src/sys/dev: clock_subr.c clock_subr.h
src/tools/compat/dev: clock_subr.h
Log Message:
Avoid overflowing the "year" value by making the field uint64_t. Adapt
arguments and local variables accordingly.
This now fixes PR 49144 for real.
To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/clock_subr.c src/sys/dev/clock_subr.h
cvs rdiff -u -r1.1 -r1.2 src/tools/compat/dev/clock_subr.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/clock_subr.c
diff -u src/sys/dev/clock_subr.c:1.21 src/sys/dev/clock_subr.c:1.22
--- src/sys/dev/clock_subr.c:1.21 Sat Sep 6 18:04:28 2014
+++ src/sys/dev/clock_subr.c Sun Sep 7 11:50:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: clock_subr.c,v 1.21 2014/09/06 18:04:28 martin Exp $ */
+/* $NetBSD: clock_subr.c,v 1.22 2014/09/07 11:50:23 martin Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -50,18 +50,20 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock_subr.c,v 1.21 2014/09/06 18:04:28 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock_subr.c,v 1.22 2014/09/07 11:50:23 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/errno.h>
#else /* ! _KERNEL */
#include <string.h>
#include <time.h>
+#include <errno.h>
#endif /* ! _KERNEL */
#include <dev/clock_subr.h>
-static inline int leapyear(int year);
+static inline int leapyear(uint64_t year);
#define FEBRUARY 2
#define days_in_year(a) (leapyear(a) ? 366 : 365)
#define days_in_month(a) (month_days[(a) - 1])
@@ -92,10 +94,13 @@ static const int month_days[12] = {
* It is otherwise equivalent.
*/
static inline int
-leapyear(int year)
+leapyear(uint64_t year)
{
int rv = 0;
+ if (year < 1969)
+ return EINVAL;
+
if ((year & 3) == 0) {
rv = 1;
if ((year % 100) == 0) {
@@ -110,8 +115,7 @@ leapyear(int year)
time_t
clock_ymdhms_to_secs(struct clock_ymdhms *dt)
{
- uint64_t secs;
- int i, year, days;
+ uint64_t secs, i, year, days;
year = dt->dt_year;
@@ -167,13 +171,17 @@ clock_ymdhms_to_secs(struct clock_ymdhms
return secs;
}
-void
+int
clock_secs_to_ymdhms(time_t secs, struct clock_ymdhms *dt)
{
- int i, leap;
+ int leap;
+ uint64_t i;
time_t days;
time_t rsec; /* remainder seconds */
+ if (secs < 0)
+ return EINVAL;
+
days = secs / SECDAY;
rsec = secs % SECDAY;
@@ -225,4 +233,6 @@ clock_secs_to_ymdhms(time_t secs, struct
dt->dt_min = rsec / 60;
rsec = rsec % 60;
dt->dt_sec = rsec;
+
+ return 0;
}
Index: src/sys/dev/clock_subr.h
diff -u src/sys/dev/clock_subr.h:1.21 src/sys/dev/clock_subr.h:1.22
--- src/sys/dev/clock_subr.h:1.21 Sat Dec 12 15:10:34 2009
+++ src/sys/dev/clock_subr.h Sun Sep 7 11:50:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: clock_subr.h,v 1.21 2009/12/12 15:10:34 tsutsui Exp $ */
+/* $NetBSD: clock_subr.h,v 1.22 2014/09/07 11:50:23 martin Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
* "POSIX time" to/from "YY/MM/DD/hh/mm/ss"
*/
struct clock_ymdhms {
- u_short dt_year;
+ uint64_t dt_year;
u_char dt_mon;
u_char dt_day;
u_char dt_wday; /* Day of week */
@@ -46,7 +46,7 @@ struct clock_ymdhms {
};
time_t clock_ymdhms_to_secs(struct clock_ymdhms *);
-void clock_secs_to_ymdhms(time_t, struct clock_ymdhms *);
+int clock_secs_to_ymdhms(time_t, struct clock_ymdhms *);
/*
* BCD to binary and binary to BCD.
Index: src/tools/compat/dev/clock_subr.h
diff -u src/tools/compat/dev/clock_subr.h:1.1 src/tools/compat/dev/clock_subr.h:1.2
--- src/tools/compat/dev/clock_subr.h:1.1 Mon Sep 1 07:48:16 2014
+++ src/tools/compat/dev/clock_subr.h Sun Sep 7 11:50:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: clock_subr.h,v 1.1 2014/09/01 07:48:16 martin Exp $ */
+/* $NetBSD: clock_subr.h,v 1.2 2014/09/07 11:50:23 martin Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
* "POSIX time" to/from "YY/MM/DD/hh/mm/ss"
*/
struct clock_ymdhms {
- u_short dt_year;
+ uint64_t dt_year;
u_char dt_mon;
u_char dt_day;
u_char dt_wday; /* Day of week */
@@ -50,7 +50,7 @@ struct clock_ymdhms {
};
time_t clock_ymdhms_to_secs(struct clock_ymdhms *);
-void clock_secs_to_ymdhms(time_t, struct clock_ymdhms *);
+int clock_secs_to_ymdhms(time_t, struct clock_ymdhms *);
/* Some handy constants. */
#define SECDAY (24 * 60 * 60)