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)

Reply via email to