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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
From fbf2392644f0ae4282fa4583c9bb67260995d983 Mon Sep 17 00:00:00 2001
From: Shubham Agrawal <shuagr@microsoft.com>
Date: Mon, 23 Sep 2019 20:58:47 +0000
Subject: [PATCH] sqlite: fix for CVE-2019-8457
Upstream-Status: Backport
CVE: CVE-2019-8457
Signed-off-by: Shubham Agrawal <shuagr@microsoft.com>
---
sqlite3.c | 50 +++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/sqlite3.c b/sqlite3.c
index 00513d4..5c8c7f4 100644
--- a/sqlite3.c
+++ b/sqlite3.c
@@ -172325,6 +172325,33 @@
}
+/* Allocate and initialize a new dynamic string object */
+StrAccum *sqlite3_str_new(sqlite3 *db){
+ StrAccum *p = sqlite3DbMallocRaw(db, sizeof(*p));
+ if( p ){
+ sqlite3StrAccumInit(p, db, 0, 0, SQLITE_MAX_LENGTH);
+ }
+ return p;
+}
+
+/* Finalize a string created using sqlite3_str_new().
+*/
+
+char *sqlite3_str_finish(StrAccum *p){
+ char *z;
+ if( p ){
+ z = sqlite3StrAccumFinish(p);
+ sqlite3DbFree(p->db, p);
+ }else{
+ z = 0;
+ }
+ return z;
+}
+/* Return any error code associated with p */
+int sqlite3_str_errcode(StrAccum *p){
+ return p ? p->accError : SQLITE_NOMEM;
+}
+
/*
** Implementation of a scalar function that decodes r-tree nodes to
** human readable strings. This can be used for debugging and analysis.
@@ -172342,49 +172369,53 @@
** <num-dimension>*2 coordinates.
*/
static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
- char *zText = 0;
+
RtreeNode node;
Rtree tree;
int ii;
+ int nData;
+ int errCode;
+ StrAccum *pOut;
UNUSED_PARAMETER(nArg);
memset(&node, 0, sizeof(RtreeNode));
memset(&tree, 0, sizeof(Rtree));
tree.nDim = (u8)sqlite3_value_int(apArg[0]);
+ if( tree.nDim<1 || tree.nDim>5 ) return;
tree.nDim2 = tree.nDim*2;
tree.nBytesPerCell = 8 + 8 * tree.nDim;
node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
+ nData = sqlite3_value_bytes(apArg[1]);
+ if( nData<4 ) return;
+ if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
+ pOut = sqlite3_str_new(0);
for(ii=0; ii<NCELL(&node); ii++){
- char zCell[512];
- int nCell = 0;
+
+
RtreeCell cell;
int jj;
nodeGetCell(&tree, &node, ii, &cell);
- sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
- nCell = (int)strlen(zCell);
+ if( ii>0 ) sqlite3StrAccumAppend(pOut, " ", 1);
+ sqlite3XPrintf(pOut, "{%lld", cell.iRowid);
+
for(jj=0; jj<tree.nDim2; jj++){
#ifndef SQLITE_RTREE_INT_ONLY
- sqlite3_snprintf(512-nCell,&zCell[nCell], " %g",
- (double)cell.aCoord[jj].f);
+
+ sqlite3XPrintf(pOut, " %g", (double)cell.aCoord[jj].f);
#else
- sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
- cell.aCoord[jj].i);
+
+ sqlite3XPrintf(pOut, " %d", cell.aCoord[jj].i);
#endif
- nCell = (int)strlen(zCell);
- }
- if( zText ){
- char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
- sqlite3_free(zText);
- zText = zTextNew;
- }else{
- zText = sqlite3_mprintf("{%s}", zCell);
}
+ sqlite3StrAccumAppend(pOut, "}", 1);
}
-
- sqlite3_result_text(ctx, zText, -1, sqlite3_free);
+
+ errCode = sqlite3_str_errcode(pOut);
+ sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free);
+ sqlite3_result_error_code(ctx, errCode);
}
/* This routine implements an SQL function that returns the "depth" parameter
--
2.7.4
|