SHA256
1
0
forked from pool/varnish
Jan Engelhardt 2015-03-27 10:35:30 +00:00 committed by Git OBS Bridge
parent b9dfe888ab
commit 2079fa56a4
5 changed files with 340 additions and 25 deletions

View File

@ -0,0 +1,290 @@
From 9d61ea4d722549a984d912603902fccfac473824 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Fri, 13 Mar 2015 15:23:15 +0100
Subject: [PATCH] Fail fetch on malformed Content-Length header
Add a common content length parser that is being used by both client
and backend side.
Original patch by: fgs
Fixes: #1691
---
bin/varnishd/cache/cache.h | 7 ++++---
bin/varnishd/cache/cache_http.c | 29 +++++++++++++++++++++++++++++
bin/varnishd/cache/cache_http1_fetch.c | 32 +++++---------------------------
bin/varnishd/cache/cache_http1_fsm.c | 20 ++++++++++----------
bin/varnishd/cache/cache_http1_proto.c | 5 +++--
bin/varnishd/cache/cache_rfc2616.c | 18 +++++++++++++++---
bin/varnishtest/tests/r01691.vtc | 21 +++++++++++++++++++++
7 files changed, 87 insertions(+), 45 deletions(-)
create mode 100644 bin/varnishtest/tests/r01691.vtc
Index: varnish-4.0.3/bin/varnishd/cache/cache.h
===================================================================
--- varnish-4.0.3.orig/bin/varnishd/cache/cache.h
+++ varnish-4.0.3/bin/varnishd/cache/cache.h
@@ -208,7 +208,7 @@ struct http {
*
*/
-typedef ssize_t htc_read(struct http_conn *, void *, size_t);
+typedef ssize_t htc_read(struct http_conn *, void *, ssize_t);
struct http_conn {
unsigned magic;
@@ -560,7 +560,7 @@ struct busyobj {
struct pool_task fetch_task;
- char *h_content_length;
+ ssize_t content_length;
#define BO_FLAG(l, r, w, d) unsigned l:1;
#include "tbl/bo_flags.h"
@@ -1014,6 +1014,7 @@ int http_GetHdrData(const struct http *h
int http_GetHdrField(const struct http *hp, const char *hdr,
const char *field, char **ptr);
double http_GetHdrQ(const struct http *hp, const char *hdr, const char *field);
+ssize_t http_GetContentLength(const struct http *hp);
uint16_t http_GetStatus(const struct http *hp);
void http_SetStatus(struct http *to, uint16_t status);
const char *http_GetReq(const struct http *hp);
@@ -1040,7 +1041,7 @@ void HTTP1_Init(struct http_conn *htc, s
unsigned maxbytes, unsigned maxhdr);
enum htc_status_e HTTP1_Reinit(struct http_conn *htc);
enum htc_status_e HTTP1_Rx(struct http_conn *htc);
-ssize_t HTTP1_Read(struct http_conn *htc, void *d, size_t len);
+ssize_t HTTP1_Read(struct http_conn *htc, void *d, ssize_t len);
enum htc_status_e HTTP1_Complete(struct http_conn *htc);
uint16_t HTTP1_DissectRequest(struct req *);
uint16_t HTTP1_DissectResponse(struct http *sp, const struct http_conn *htc);
Index: varnish-4.0.3/bin/varnishd/cache/cache_http.c
===================================================================
--- varnish-4.0.3.orig/bin/varnishd/cache/cache_http.c
+++ varnish-4.0.3/bin/varnishd/cache/cache_http.c
@@ -488,6 +488,35 @@ http_GetHdrField(const struct http *hp,
return (i);
}
+/*--------------------------------------------------------------------*/
+
+ssize_t
+http_GetContentLength(const struct http *hp)
+{
+ ssize_t cl, cll;
+ char *b;
+
+ CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+
+ if (!http_GetHdr(hp, H_Content_Length, &b))
+ return (-1);
+ cl = 0;
+ if (!vct_isdigit(*b))
+ return (-2);
+ for (;vct_isdigit(*b); b++) {
+ cll = cl;
+ cl *= 10;
+ cl += *b - '0';
+ if (cll != cl / 10)
+ return (-2);
+ }
+ while (vct_islws(*b))
+ b++;
+ if (*b != '\0')
+ return (-2);
+ return (cl);
+}
+
/*--------------------------------------------------------------------
* XXX: redo with http_GetHdrField() ?
*/
Index: varnish-4.0.3/bin/varnishd/cache/cache_http1_fetch.c
===================================================================
--- varnish-4.0.3.orig/bin/varnishd/cache/cache_http1_fetch.c
+++ varnish-4.0.3/bin/varnishd/cache/cache_http1_fetch.c
@@ -43,29 +43,6 @@
#include "vtcp.h"
#include "vtim.h"
-/*--------------------------------------------------------------------
- * Convert a string to a size_t safely
- */
-
-static ssize_t
-vbf_fetch_number(const char *nbr, int radix)
-{
- uintmax_t cll;
- ssize_t cl;
- char *q;
-
- if (*nbr == '\0')
- return (-1);
- cll = strtoumax(nbr, &q, radix);
- if (q == NULL || *q != '\0')
- return (-1);
-
- cl = (ssize_t)cll;
- if((uintmax_t)cl != cll) /* Protect against bogusly large values */
- return (-1);
- return (cl);
-}
-
/*--------------------------------------------------------------------*/
static enum vfp_status __match_proto__(vfp_pull_f)
@@ -167,7 +144,6 @@ ssize_t
V1F_Setup_Fetch(struct busyobj *bo)
{
struct http_conn *htc;
- ssize_t cl;
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
htc = &bo->htc;
@@ -176,13 +152,15 @@ V1F_Setup_Fetch(struct busyobj *bo)
switch(htc->body_status) {
case BS_EOF:
+ assert(bo->content_length == -1);
VFP_Push(bo, v1f_pull_eof, 0);
return(-1);
case BS_LENGTH:
- cl = vbf_fetch_number(bo->h_content_length, 10);
- VFP_Push(bo, v1f_pull_straight, cl);
- return (cl);
+ assert(bo->content_length > 0);
+ VFP_Push(bo, v1f_pull_straight, bo->content_length);
+ return (bo->content_length);
case BS_CHUNKED:
+ assert(bo->content_length == -1);
VFP_Push(bo, v1f_pull_chunked, -1);
return (-1);
default:
Index: varnish-4.0.3/bin/varnishd/cache/cache_http1_fsm.c
===================================================================
--- varnish-4.0.3.orig/bin/varnishd/cache/cache_http1_fsm.c
+++ varnish-4.0.3/bin/varnishd/cache/cache_http1_fsm.c
@@ -262,22 +262,22 @@ http1_cleanup(struct sess *sp, struct wo
static enum req_body_state_e
http1_req_body_status(struct req *req)
{
- char *ptr, *endp;
+ ssize_t cl;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- if (http_GetHdr(req->http, H_Content_Length, &ptr)) {
- AN(ptr);
- if (*ptr == '\0')
- return (REQ_BODY_FAIL);
- req->req_bodybytes = strtoul(ptr, &endp, 10);
- if (*endp != '\0' && !vct_islws(*endp))
- return (REQ_BODY_FAIL);
- if (req->req_bodybytes == 0)
- return (REQ_BODY_NONE);
+ req->req_bodybytes = 0;
+ cl = http_GetContentLength(req->http);
+ if (cl == -2)
+ return (REQ_BODY_FAIL);
+ else if (cl == 0)
+ return (REQ_BODY_NONE);
+ else if (cl > 0) {
+ req->req_bodybytes = cl;
req->h1.bytes_yet = req->req_bodybytes - req->h1.bytes_done;
return (REQ_BODY_PRESENT);
}
+ assert(cl == -1); /* No Content-Length header */
if (http_HdrIs(req->http, H_Transfer_Encoding, "chunked")) {
req->chunk_ctr = -1;
return (REQ_BODY_CHUNKED);
Index: varnish-4.0.3/bin/varnishd/cache/cache_http1_proto.c
===================================================================
--- varnish-4.0.3.orig/bin/varnishd/cache/cache_http1_proto.c
+++ varnish-4.0.3/bin/varnishd/cache/cache_http1_proto.c
@@ -191,14 +191,15 @@ HTTP1_Rx(struct http_conn *htc)
* Read up to len bytes, returning pipelined data first.
*/
-ssize_t
-HTTP1_Read(struct http_conn *htc, void *d, size_t len)
+ssize_t __match_proto__(htc_read)
+HTTP1_Read(struct http_conn *htc, void *d, ssize_t len)
{
size_t l;
unsigned char *p;
ssize_t i = 0;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+ assert(len > 0);
l = 0;
p = d;
if (htc->pipeline.b) {
Index: varnish-4.0.3/bin/varnishd/cache/cache_rfc2616.c
===================================================================
--- varnish-4.0.3.orig/bin/varnishd/cache/cache_rfc2616.c
+++ varnish-4.0.3/bin/varnishd/cache/cache_rfc2616.c
@@ -188,6 +188,7 @@ enum body_status
RFC2616_Body(struct busyobj *bo, struct dstat *stats)
{
struct http *hp;
+ ssize_t cl;
char *b;
hp = bo->beresp;
@@ -199,6 +200,8 @@ RFC2616_Body(struct busyobj *bo, struct
else
bo->should_close = 0;
+ bo->content_length = -1;
+
if (!strcasecmp(http_GetReq(bo->bereq), "head")) {
/*
* A HEAD request can never have a body in the reply,
@@ -246,9 +249,18 @@ RFC2616_Body(struct busyobj *bo, struct
return (BS_ERROR);
}
- if (http_GetHdr(hp, H_Content_Length, &bo->h_content_length)) {
- stats->fetch_length++;
- return (BS_LENGTH);
+ cl = http_GetContentLength(hp);
+ if (cl == -2)
+ return (BS_ERROR);
+ if (cl >= 0) {
+ bo->content_length = cl;
+ if (cl == 0) {
+ stats->fetch_zero++;
+ return (BS_NONE);
+ } else {
+ stats->fetch_length++;
+ return (BS_LENGTH);
+ }
}
if (http_HdrIs(hp, H_Connection, "keep-alive")) {
Index: varnish-4.0.3/bin/varnishtest/tests/r01691.vtc
===================================================================
--- /dev/null
+++ varnish-4.0.3/bin/varnishtest/tests/r01691.vtc
@@ -0,0 +1,21 @@
+varnishtest "Test bogus Content-Length header"
+
+server s1 {
+ rxreq
+ txresp -nolen -hdr "Content-Length: bogus"
+} -start
+
+varnish v1 -vcl+backend {
+
+} -start
+
+logexpect l1 -v v1 {
+ expect * 1002 VCL_Error "Body cannot be fetched"
+} -start
+
+client c1 {
+ txreq
+ rxresp
+} -run
+
+logexpect l1 -wait

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:302fd6afc771524ca3912f5d945ab197a55762385c012b2054df7d86bf7ae2b7
size 2116664

3
varnish-4.0.3.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:94b9a174097f47db2286acd2c35f235e49a2b7a9ddfdbd6eb7aa4da9ae8f8206
size 1866760

View File

@ -1,3 +1,19 @@
-------------------------------------------------------------------
Fri Mar 27 10:34:15 UTC 2015 - jengelh@inai.de
- Update to new upstream release 4.0.3
* Full support for streaming objects through from the backend on a
cache miss. Bytes will be sent to 1..n requesting clients as they
come in from the backend server.
* Background (re)fetch of expired objects. On a cache miss where a
stale copy is available, serve the client the stale copy while
fetching an updated copy from the backend in the background.
* New varnishlog query language, allowing automatic grouping of
requests when debugging ESI or a failed backend request.
* Comprehensive request timestamp and byte counters.
- Add 0001-Fail-fetch-on-malformed-Content-Length-header.patch
[bnc#921316]
------------------------------------------------------------------- -------------------------------------------------------------------
Fri Jan 3 10:57:19 UTC 2014 - danimo@owncloud.com Fri Jan 3 10:57:19 UTC 2014 - danimo@owncloud.com

View File

@ -1,7 +1,7 @@
# #
# spec file for package varnish # spec file for package varnish
# #
# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany. # Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
# #
# All modifications and additions to the file contributed by third parties # All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed # remain the property of their copyright owners, unless otherwise agreed
@ -15,19 +15,19 @@
# Please submit bugfixes or comments via http://bugs.opensuse.org/ # Please submit bugfixes or comments via http://bugs.opensuse.org/
# #
Name: varnish Name: varnish
%define library_name libvarnishapi1 %define library_name libvarnishapi1
Version: 3.0.5 Version: 4.0.3
Release: 0 Release: 0
Summary: Varnish is a high-performance HTTP accelerator Summary: Varnish is a high-performance HTTP accelerator
License: BSD-2-Clause License: BSD-2-Clause
Group: Productivity/Networking/Web/Proxy Group: Productivity/Networking/Web/Proxy
URL: http://varnish-cache.org/ Url: http://varnish-cache.org/
#Git-Clone: git://git.varnish-cache.org/varnish-cache #Git-Clone: git://git.varnish-cache.org/varnish-cache
#Git-Web: https://varnish-cache.org/trac/browser #Git-Web: https://varnish-cache.org/trac/browser
#DL-URL: http://downloads.sf.net/varnish/%name-%version.tar.bz2 Source: https://repo.varnish-cache.org/source/%name-%version.tar.gz
Source: %name-%version.tar.gz
Source2: varnish.init Source2: varnish.init
Source3: varnish.sysconfig Source3: varnish.sysconfig
Source4: vcl.conf Source4: vcl.conf
@ -35,17 +35,22 @@ Source5: varnish.logrotate
Source6: varnishlog.init Source6: varnishlog.init
Source7: varnish.service Source7: varnish.service
Source8: varnishlog.service Source8: varnishlog.service
Patch1: 0001-Fail-fetch-on-malformed-Content-Length-header.patch
BuildRoot: %_tmppath/%name-%version-build BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: libxslt, ncurses-devel, pcre-devel, readline-devel BuildRequires: libxslt
BuildRequires: pkgconfig, xz BuildRequires: ncurses-devel
BuildRequires: pcre-devel
BuildRequires: pkgconfig
BuildRequires: readline-devel
BuildRequires: python-docutils
BuildRequires: xz
Prereq(post): %_sbindir/useradd %_sbindir/groupadd Prereq(post): %_sbindir/useradd %_sbindir/groupadd
%if 0%{?suse_version} >= 1010 %if 0%{?suse_version} >= 1010
Recommends: logrotate Recommends: logrotate
%endif %endif
%if 0%{?suse_version} >= 1210 %if 0%{?suse_version} >= 1210
BuildRequires: systemd BuildRequires: systemd-rpm-macros
%{?systemd_requires}
%endif %endif
%define pkg_home %_localstatedir/lib/%name %define pkg_home %_localstatedir/lib/%name
%define pkg_logdir %_localstatedir/log/%name %define pkg_logdir %_localstatedir/log/%name
@ -63,8 +68,8 @@ server. The purpose of this is to minimize the requests going to the backend
server(s) by serving the same document to potentially many users. server(s) by serving the same document to potentially many users.
%package -n %library_name %package -n %library_name
Group: Productivity/Networking/Web/Proxy
Summary: Shared libraries for Varnish Summary: Shared libraries for Varnish
Group: Productivity/Networking/Web/Proxy
%description -n %library_name %description -n %library_name
Varnish is an HTTP accelerator. An HTTP accelerator (often called Reverse Varnish is an HTTP accelerator. An HTTP accelerator (often called Reverse
@ -79,9 +84,9 @@ server(s) by serving the same document to potentially many users.
This package holds the shared libraries for varnish. This package holds the shared libraries for varnish.
%package devel %package devel
Group: Development/Libraries/C and C++
Requires: %name = %version Requires: %name = %version
Summary: Development files for Varnish Summary: Development files for Varnish
Group: Development/Libraries/C and C++
%description devel %description devel
Varnish is an HTTP accelerator. An HTTP accelerator (often called Reverse Varnish is an HTTP accelerator. An HTTP accelerator (often called Reverse
@ -97,10 +102,11 @@ This package holds the development files for varnish.
%prep %prep
%setup -q %setup -q
%patch -P 1 -p1
%build %build
export CFLAGS="%optflags -fstack-protector" export CFLAGS="%optflags -fstack-protector"
%configure --disable-static \ %configure --disable-static --docdir="%_docdir/%name" \
--localstatedir=%_localstatedir/cache/ \ --localstatedir=%_localstatedir/cache/ \
--enable-developer-warnings --enable-developer-warnings
make %{?_smp_mflags} make %{?_smp_mflags}
@ -133,6 +139,8 @@ install -Dpm 0644 %{S:4} "$b/%_sysconfdir/%name/vcl.conf.example";
find "$b" -type f -name "*.la" -delete find "$b" -type f -name "*.la" -delete
mkdir -p "$b/%pkg_logdir" mkdir -p "$b/%pkg_logdir"
mkdir -p "$b/%_docdir/%name"
cp -a ChangeLog LICENSE README "$b/%_docdir/%name/"
%pre %pre
%_bindir/getent group varnish >/dev/null || \ %_bindir/getent group varnish >/dev/null || \
@ -185,12 +193,12 @@ mkdir -p "$b/%pkg_logdir"
%dir %attr(0750,root,varnish) %_sysconfdir/%name/ %dir %attr(0750,root,varnish) %_sysconfdir/%name/
%config(noreplace) %attr(0640,root,varnish) %_sysconfdir/%name/vcl.conf %config(noreplace) %attr(0640,root,varnish) %_sysconfdir/%name/vcl.conf
%config %attr(0640,root,varnish) %_sysconfdir/%name/vcl.conf.example %config %attr(0640,root,varnish) %_sysconfdir/%name/vcl.conf.example
%config(noreplace) %attr(0640,root,varnish) %_sysconfdir/%name/default.vcl
%_libdir/varnish %_libdir/varnish
%_sbindir/varnish* %_sbindir/varnish*
%_sbindir/rcvarnish* %_sbindir/rcvarnish*
%_mandir/man*/* %_mandir/man*/*
%doc ChangeLog LICENSE README %_docdir/%name/
%_datadir/%name/
%dir %attr(0750,varnish,varnish) %pkg_home %dir %attr(0750,varnish,varnish) %pkg_home
%dir %attr(0750,varnish,varnish) %pkg_cachedir %dir %attr(0750,varnish,varnish) %pkg_cachedir
%dir %attr(0750,varnish,varnish) %pkg_logdir %dir %attr(0750,varnish,varnish) %pkg_logdir
@ -209,6 +217,7 @@ mkdir -p "$b/%pkg_logdir"
%files devel %files devel
%defattr(-,root,root,-) %defattr(-,root,root,-)
%_includedir/varnish %_includedir/varnish
%_datadir/aclocal/
%_libdir/pkgconfig/* %_libdir/pkgconfig/*
%_libdir/libvarnishapi.so %_libdir/libvarnishapi.so