File: CVE-2024-24795-regression.patch

package info (click to toggle)
fossil 1%3A2.21-1%2Bdeb12u1
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 26,916 kB
  • sloc: ansic: 309,417; tcl: 12,660; javascript: 9,603; sh: 6,071; makefile: 4,249; pascal: 1,139; cpp: 1,001; cs: 879; sql: 376; asm: 281; perl: 270; xml: 95
file content (139 lines) | stat: -rw-r--r-- 5,765 bytes parent folder | download
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
127
128
129
130
131
132
133
134
135
136
137
138
139
Origin: https://fossil-scm.org/home/info/a8e33fb161f45b65
Origin: https://fossil-scm.org/home/info/71919ad1b542832c
Origin: https://fossil-scm.org/home/info/f4ffefe708793b03
Origin: https://fossil-scm.org/home/info/5f47bb59a7846aeb
Reviewed-by: Sylvain Beucler <beuc@debian.org>
Last-Update: 2025-05-04

Only backported parts relevant to the fossil HTTP client fix,
discarded debugging improvements.

Commit:   a8e33fb161f45b65167f0dfe39b6fcbad21f5844ee469131fd8fa8fc09cd5e99
Date:     2024-04-17 12:58:08
Author:   drh
Comment:  Fix the HTTP-reply parser so that it is able to deal with replies that lack a Content-Length header field.  This resolves the issue reported by [forum:/forumpost/12ac403fd29cfc89|forum post 12ac403fd29cfc89].  Also in this merge: (1) Add the --xverbose option to "fossil clone".  (2) Improved error messages when web servers misbehave.  See also my misguided and incorrect [https://bz.apache.org/bugzilla/show_bug.cgi?id=68905|Apache bug 68905]. Special thanks to Apache devs for setting me straight.
Branch:   trunk
Tags:     trunk
Phase:    *MERGE* 

Commit:   71919ad1b542832c615df0af08999c9624ade133f48d0f39448cf87d71fa1142
Date:     2024-04-17 13:27:34
Author:   drh
Comment:  Only process HTTP replies that lack a Content-Length header if the connection is set to be closed.  Suggested by [https://bz.apache.org/bugzilla/show_bug.cgi?id=68905].
Branch:   trunk
Tags:     trunk
Phase:    

Commit:   f4ffefe708793b036dc1d4a3c3806cdb24de73362df532779d1a80375a6347ad
Date:     2024-04-17 14:02:19
Author:   drh
Comment:  Output a warning if a client sync or clone gets back a keep-alive HTTP reply that lacks a content-length header.
Branch:   trunk
Tags:     trunk
Phase:    

Commit:   5f47bb59a7846aeb3e073ffe24629bb87809b86358c7124d9b4596817c3599d5
Date:     2024-04-21 16:20:19
Author:   drh
Comment:  Fix parsing of the argument to the "Connection:" header of HTTP reply messages to deal with unusual arguments added by Apache mod_cgi.  See [forum:/forumpost/ca6fc85c80f4704f|forum thread ca6fc85c80f4704f].
Branch:   trunk
Tags:     trunk
Phase:    *MERGE* 

Index: fossil-2.21/src/http.c
===================================================================
--- fossil-2.21.orig/src/http.c
+++ fossil-2.21/src/http.c
@@ -294,7 +294,6 @@ int http_exchange(
   Blob hdr;             /* The HTTP request header */
   int closeConnection;  /* True to close the connection when done */
   int iLength;          /* Expected length of the reply payload */
-  int iRecvLen;         /* Received length of the reply payload */
   int rc = 0;           /* Result code */
   int iHttpVersion;     /* Which version of HTTP protocol server uses */
   char *zLine;          /* A single line of the reply header */
@@ -374,6 +373,7 @@ int http_exchange(
   */
   closeConnection = 1;
   iLength = -1;
+  iHttpVersion = -1;
   while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){
     if( mHttpFlags & HTTP_VERBOSE ){
       fossil_print("Read: [%s]\n", zLine);
@@ -412,17 +412,15 @@ int http_exchange(
         fossil_warning("server says: %s", &zLine[ii]);
         goto write_err;
       }
+      if( iHttpVersion<0 ) iHttpVersion = 1;
       closeConnection = 0;
     }else if( fossil_strnicmp(zLine, "content-length:", 15)==0 ){
       for(i=15; fossil_isspace(zLine[i]); i++){}
       iLength = atoi(&zLine[i]);
     }else if( fossil_strnicmp(zLine, "connection:", 11)==0 ){
-      char c;
-      for(i=11; fossil_isspace(zLine[i]); i++){}
-      c = zLine[i];
-      if( c=='c' || c=='C' ){
+      if( sqlite3_strlike("%close%", &zLine[11], 0)==0 ){
         closeConnection = 1;
-      }else if( c=='k' || c=='K' ){
+      }else if( sqlite3_strlike("%keep-alive%", &zLine[11], 0)==0 ){
         closeConnection = 0;
       }
     }else if( ( rc==301 || rc==302 || rc==307 || rc==308 ) &&
@@ -485,7 +483,7 @@ int http_exchange(
       }
     }
   }
-  if( iLength<0 ){
+  if( iHttpVersion<0 ){
     fossil_warning("server did not reply");
     goto write_err;
   }
@@ -498,13 +496,40 @@ int http_exchange(
   ** Extract the reply payload that follows the header
   */
   blob_zero(pReply);
-  blob_resize(pReply, iLength);
-  iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength);
-  if( iRecvLen != iLength ){
-    fossil_warning("response truncated: got %d bytes of %d", iRecvLen, iLength);
-    goto write_err;
+  if( iLength==0 ){
+    /* No content to read */
+  }else if( iLength>0 ){
+    /* Read content of a known length */
+    int iRecvLen;         /* Received length of the reply payload */
+    blob_resize(pReply, iLength);
+    iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength);
+    if( mHttpFlags & HTTP_VERBOSE ){
+      fossil_print("Reply received: %d of %d bytes\n", iRecvLen, iLength);
+    }
+    if( iRecvLen != iLength ){
+      fossil_warning("response truncated: got %d bytes of %d",
+                     iRecvLen, iLength);
+      goto write_err;
+    }
+  }else if( closeConnection ){
+    /* Read content until end-of-file */
+    int iRecvLen;         /* Received length of the reply payload */
+    unsigned int nReq = 1000;
+    unsigned int nPrior = 0;
+    do{
+      nReq *= 2;
+      blob_resize(pReply, nPrior+nReq);
+      iRecvLen = transport_receive(&g.url, &pReply->aData[nPrior], (int)nReq);
+      nPrior += iRecvLen;
+      pReply->nUsed = nPrior;
+    }while( iRecvLen==nReq && nReq<0x20000000 );
+    if( mHttpFlags & HTTP_VERBOSE ){
+      fossil_print("Reply received: %u bytes (w/o content-length)\n", nPrior);
+    }
+  }else{
+    assert( iLength<0 && !closeConnection );
+    fossil_warning("\"content-length\" missing from %d keep-alive reply", rc);
   }
-  blob_resize(pReply, iLength);
   if( isError ){
     char *z;
     int i, j;