~ubuntu-branches/ubuntu/dapper/php5/dapper-security

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
Subject: Fixed bug #53574 (Integer overflow in SdnToJulian, sometimes leading to segfault).
Origin: http://svn.php.net/viewvc?view=revision&revision=306475

CVE-2011-1466

Patch differs from upstream commit in that the edit to the NEWS file was
dropped to reduce patch conflicts.

---
 ext/calendar/julian.c            |   26 ++++++++++++++++++++------
 ext/calendar/tests/bug53574.phpt |   35 +++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 6 deletions(-)

Index: b/ext/calendar/tests/bug53574.phpt
===================================================================
--- /dev/null
+++ b/ext/calendar/tests/bug53574.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #53574 (Integer overflow in SdnToJulian; leads to segfault)
+--SKIPIF--
+<?php include 'skipif.inc'; ?>
+--FILE--
+<?php
+if (PHP_INT_MAX == 0x7FFFFFFF) {
+	$x = 882858043;
+} else {
+	$x = 3315881921229094912;
+}
+
+var_dump(cal_from_jd($x, CAL_JULIAN));
+--EXPECT--
+array(9) {
+  ["date"]=>
+  string(5) "0/0/0"
+  ["month"]=>
+  int(0)
+  ["day"]=>
+  int(0)
+  ["year"]=>
+  int(0)
+  ["dow"]=>
+  int(3)
+  ["abbrevdayname"]=>
+  string(3) "Wed"
+  ["dayname"]=>
+  string(9) "Wednesday"
+  ["abbrevmonth"]=>
+  string(0) ""
+  ["monthname"]=>
+  string(0) ""
+}
+
Index: b/ext/calendar/julian.c
===================================================================
--- a/ext/calendar/julian.c
+++ b/ext/calendar/julian.c
@@ -146,6 +146,7 @@
  **************************************************************************/
 
 #include "sdncal.h"
+#include <limits.h>
 
 #define JULIAN_SDN_OFFSET         32083
 #define DAYS_PER_5_MONTHS  153
@@ -164,15 +165,22 @@ void SdnToJulian(
 	int dayOfYear;
 
 	if (sdn <= 0) {
-		*pYear = 0;
-		*pMonth = 0;
-		*pDay = 0;
-		return;
+		goto fail;
 	}
-	temp = (sdn + JULIAN_SDN_OFFSET) * 4 - 1;
+	/* Check for overflow */
+	if (sdn > (LONG_MAX - JULIAN_SDN_OFFSET * 4 + 1) / 4 || sdn < LONG_MIN / 4) {
+		goto fail;
+	}
+	temp = sdn * 4 + (JULIAN_SDN_OFFSET * 4 - 1);
 
 	/* Calculate the year and day of year (1 <= dayOfYear <= 366). */
-	year = temp / DAYS_PER_4_YEARS;
+	{
+		long yearl = temp / DAYS_PER_4_YEARS;
+		if (yearl > INT_MAX || yearl < INT_MIN) {
+			goto fail;
+		}
+		year = (int) yearl;
+	}
 	dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1;
 
 	/* Calculate the month and day of month. */
@@ -196,6 +204,12 @@ void SdnToJulian(
 	*pYear = year;
 	*pMonth = month;
 	*pDay = day;
+	return;
+
+fail:
+	*pYear = 0;
+	*pMonth = 0;
+	*pDay = 0;
 }
 
 long int JulianToSdn(