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
108
109
110
| | Fix CVE-2017-0898:
https://www.ruby-lang.org/en/news/2017/09/14/sprintf-buffer-underrun-cve-2017-0898/
https://bugs.ruby-lang.org/issues/13499
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0898
https://security-tracker.debian.org/tracker/CVE-2017-0898
Patch copied from snapshot.debian.org:
https://snapshot.debian.org/archive/debian-security/20180423T104456Z/pool/updates/main/r/ruby1.8/ruby1.8_1.8.7.358-7.1%2Bdeb7u6.debian.tar.gz
Description: security fix for CVE-2017-0898
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=875936
Reviewed-By: anarcat
Last-Update: 2017-09-26
Origin: OpenBSD, https://raw.githubusercontent.com/openbsd/ports/master/lang/ruby/1.8/patches/patch-sprintf_c
$OpenBSD: patch-sprintf_c,v 1.1 2017/09/16 22:54:58 jeremy Exp $
--- a/sprintf.c
+++ b/sprintf.c
@@ -728,6 +728,8 @@ rb_str_format(argc, argv, fmt)
#if defined(_WIN32) && !defined(__BORLANDC__)
if (isnan(fval) || isinf(fval)) {
const char *expr;
+ int elen;
+ char sign = '\0';
if (isnan(fval)) {
expr = "NaN";
@@ -736,51 +738,40 @@ rb_str_format(argc, argv, fmt)
expr = "Inf";
}
need = strlen(expr);
- if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
- need++;
- else if (flags & FSPACE)
- need++;
+ elen = need;
+ i = 0;
+ if (!isnan(fval) && fval < 0.0)
+ sign = '-';
+ else if (flags & (FPLUS|FSPACE))
+ sign = (flags & FPLUS) ? '+' : ' ';
+ if (sign)
+ ++need;
if ((flags & FWIDTH) && need < width)
need = width;
- CHECK(need);
- sprintf(&buf[blen], "%*s", need, "");
+#define FILL(c, l) do { \
+ if ((l) <= 0) break;\
+ CHECK(l);\
+ FILL_(c, l);\
+} while (0)
+
+#define FILL_(c, l) do { \
+ memset(&buf[blen], (c), (l));\
+ blen += (l);\
+} while (0)
+
+
+ FILL(' ', need);
if (flags & FMINUS) {
- if (!isnan(fval) && fval < 0.0)
- buf[blen++] = '-';
- else if (flags & FPLUS)
- buf[blen++] = '+';
- else if (flags & FSPACE)
- blen++;
- strncpy(&buf[blen], expr, strlen(expr));
- }
- else if (flags & FZERO) {
- if (!isnan(fval) && fval < 0.0) {
- buf[blen++] = '-';
- need--;
- }
- else if (flags & FPLUS) {
- buf[blen++] = '+';
- need--;
- }
- else if (flags & FSPACE) {
- blen++;
- need--;
- }
- while (need-- - strlen(expr) > 0) {
- buf[blen++] = '0';
- }
- strncpy(&buf[blen], expr, strlen(expr));
+ if (sign)
+ buf[blen - need--] = sign;
+ memcpy(&buf[blen - need], expr, elen);
}
else {
- if (!isnan(fval) && fval < 0.0)
- buf[blen + need - strlen(expr) - 1] = '-';
- else if (flags & FPLUS)
- buf[blen + need - strlen(expr) - 1] = '+';
- strncpy(&buf[blen + need - strlen(expr)], expr,
- strlen(expr));
+ if (sign)
+ buf[blen - elen - 1] = sign;
+ memcpy(&buf[blen - elen], expr, elen);
}
- blen += strlen(&buf[blen]);
break;
}
#endif /* defined(_WIN32) && !defined(__BORLANDC__) */
|