* [PATCH 00/21][Fido v3] pull request
@ 2016-02-06 23:14 Armin Kuster
2016-02-06 23:14 ` [PATCH 01/21] glibc: CVE-2015-8777 Armin Kuster
` (21 more replies)
0 siblings, 22 replies; 23+ messages in thread
From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw)
To: openembedded-core, joshua.g.lock, akuster808
From: Armin Kuster <akuster@mvista.com>
forgot to append a change to bind recipe.
This includes a miss fire on the glibc request plus many others.
This supersedes the last tow fido pull request
The following changes since commit 9845a542a76156adb5aef6fd33ad5bc5777acf64:
openssh: CVE-2016-077x (2016-01-20 17:08:30 +0000)
are available in the git repository at:
git://git.yoctoproject.org/poky-contrib akuster/fido_cve_fixes
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=akuster/fido_cve_fixes
Armin Kuster (18):
glibc: CVE-2015-8777
glibc: CVE-2015-8779
glibc: CVE-2015-9761
glibc: CVE-2015-8776
openssl: Security fix CVE-2015-3197
openssl: Security fix CVE-2016-0701
qemu: Security fix CVE-2015-8504
qemu: Security fix CVE-2015-7504
qemu: Security fix CVE-2015-7512
qemu: Security fix CVE-2015-8345
qemu: Security fix CVE-2016-1568
qemu: Security fix CVE-2015-7295
tzcode: update to 2016a
tzdata: update to 2016a
dpkg: Security fix CVE-2015-0860
libxml2: Security fix CVE-2015-8241
libxml2: Security fix CVE-2015-8710
bind: Security fix CVE-2015-8704
Paul Eggleton (1):
tzdata: reinstate changes reverted in 2014c upgrade
Wenzong Fan (2):
subversion: fix CVE-2015-3184
subversion: fix CVE-2015-3187
.../bind/bind/CVE-2015-8704.patch | 29 +
meta/recipes-connectivity/bind/bind_9.9.5.bb | 1 +
.../openssl/openssl/CVE-2015-3197.patch | 63 +
.../openssl/openssl/CVE-2016-0701_1.patch | 102 +
.../openssl/openssl/CVE-2016-0701_2.patch | 156 ++
.../recipes-connectivity/openssl/openssl_1.0.2d.bb | 3 +
meta/recipes-core/glibc/glibc/CVE-2015-8776.patch | 155 ++
meta/recipes-core/glibc/glibc/CVE-2015-8777.patch | 122 ++
meta/recipes-core/glibc/glibc/CVE-2015-8779.patch | 262 +++
.../recipes-core/glibc/glibc/CVE-2015-9761_1.patch | 1039 ++++++++++
.../recipes-core/glibc/glibc/CVE-2015-9761_2.patch | 388 ++++
meta/recipes-core/glibc/glibc_2.21.bb | 5 +
meta/recipes-core/libxml/libxml2.inc | 2 +
.../libxml/libxml2/CVE-2015-8241.patch | 40 +
.../libxml/libxml2/CVE-2015-8710.patch | 71 +
.../recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch | 53 +
meta/recipes-devtools/dpkg/dpkg_1.17.21.bb | 1 +
.../qemu/qemu/CVE-2015-7295_1.patch | 63 +
.../qemu/qemu/CVE-2015-7295_2.patch | 58 +
.../qemu/qemu/CVE-2015-7295_3.patch | 52 +
.../recipes-devtools/qemu/qemu/CVE-2015-7504.patch | 56 +
.../recipes-devtools/qemu/qemu/CVE-2015-7512.patch | 44 +
.../recipes-devtools/qemu/qemu/CVE-2015-8345.patch | 73 +
.../recipes-devtools/qemu/qemu/CVE-2015-8504.patch | 51 +
.../recipes-devtools/qemu/qemu/CVE-2016-1568.patch | 46 +
meta/recipes-devtools/qemu/qemu_2.2.0.bb | 8 +
.../subversion-CVE-2015-3184.patch | 2082 ++++++++++++++++++++
.../subversion-CVE-2015-3187.patch | 346 ++++
.../subversion/subversion_1.8.11.bb | 2 +
...code-native_2015g.bb => tzcode-native_2016a.bb} | 16 +-
meta/recipes-extended/tzdata/tzdata.inc | 5 +-
.../tzdata/{tzdata_2015g.bb => tzdata_2016a.bb} | 10 +-
32 files changed, 5389 insertions(+), 15 deletions(-)
create mode 100644 meta/recipes-connectivity/bind/bind/CVE-2015-8704.patch
create mode 100644 meta/recipes-connectivity/openssl/openssl/CVE-2015-3197.patch
create mode 100644 meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_1.patch
create mode 100644 meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_2.patch
create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-8776.patch
create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-8777.patch
create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-8779.patch
create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch
create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch
create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2015-8241.patch
create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2015-8710.patch
create mode 100644 meta/recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7295_1.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7295_2.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7295_3.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7504.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7512.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-8345.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-8504.patch
create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2016-1568.patch
create mode 100644 meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3184.patch
create mode 100644 meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3187.patch
rename meta/recipes-extended/tzcode/{tzcode-native_2015g.bb => tzcode-native_2016a.bb} (40%)
rename meta/recipes-extended/tzdata/{tzdata_2015g.bb => tzdata_2016a.bb} (96%)
--
2.3.5
^ permalink raw reply [flat|nested] 23+ messages in thread* [PATCH 01/21] glibc: CVE-2015-8777 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 02/21] glibc: CVE-2015-8779 Armin Kuster ` (20 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> The process_envvars function in elf/rtld.c in the GNU C Library (aka glibc or libc6) before 2.23 allows local users to bypass a pointer-guarding protection mechanism via a zero value of the LD_POINTER_GUARD environment variable. (From OE-Core rev: 22570ba08d7c6157aec58764c73b1134405b0252) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- meta/recipes-core/glibc/glibc/CVE-2015-8777.patch | 122 ++++++++++++++++++++++ meta/recipes-core/glibc/glibc_2.21.bb | 1 + 2 files changed, 123 insertions(+) create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-8777.patch diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-8777.patch b/meta/recipes-core/glibc/glibc/CVE-2015-8777.patch new file mode 100644 index 0000000..9b9ab3b --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2015-8777.patch @@ -0,0 +1,122 @@ +From a014cecd82b71b70a6a843e250e06b541ad524f7 Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Thu, 15 Oct 2015 09:23:07 +0200 +Subject: [PATCH] Always enable pointer guard [BZ #18928] + +Honoring the LD_POINTER_GUARD environment variable in AT_SECURE mode +has security implications. This commit enables pointer guard +unconditionally, and the environment variable is now ignored. + + [BZ #18928] + * sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove + _dl_pointer_guard member. + * elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard + initializer. + (security_init): Always set up pointer guard. + (process_envvars): Do not process LD_POINTER_GUARD. + +Upstream-Status: Backport +CVE: CVE-2015-8777 +[Yocto # 8980] + +https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=a014cecd82b71b70a6a843e250e06b541ad524f7 + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ChangeLog | 10 ++++++++++ + NEWS | 13 ++++++++----- + elf/rtld.c | 15 ++++----------- + sysdeps/generic/ldsodefs.h | 3 --- + 4 files changed, 22 insertions(+), 19 deletions(-) + +Index: git/elf/rtld.c +=================================================================== +--- git.orig/elf/rtld.c ++++ git/elf/rtld.c +@@ -163,7 +163,6 @@ struct rtld_global_ro _rtld_global_ro at + ._dl_hwcap_mask = HWCAP_IMPORTANT, + ._dl_lazy = 1, + ._dl_fpu_control = _FPU_DEFAULT, +- ._dl_pointer_guard = 1, + ._dl_pagesize = EXEC_PAGESIZE, + ._dl_inhibit_cache = 0, + +@@ -710,15 +709,12 @@ security_init (void) + #endif + + /* Set up the pointer guard as well, if necessary. */ +- if (GLRO(dl_pointer_guard)) +- { +- uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random, +- stack_chk_guard); ++ uintptr_t pointer_chk_guard ++ = _dl_setup_pointer_guard (_dl_random, stack_chk_guard); + #ifdef THREAD_SET_POINTER_GUARD +- THREAD_SET_POINTER_GUARD (pointer_chk_guard); ++ THREAD_SET_POINTER_GUARD (pointer_chk_guard); + #endif +- __pointer_chk_guard_local = pointer_chk_guard; +- } ++ __pointer_chk_guard_local = pointer_chk_guard; + + /* We do not need the _dl_random value anymore. The less + information we leave behind, the better, so clear the +@@ -2478,9 +2474,6 @@ process_envvars (enum mode *modep) + GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0; + break; + } +- +- if (memcmp (envline, "POINTER_GUARD", 13) == 0) +- GLRO(dl_pointer_guard) = envline[14] != '0'; + break; + + case 14: +Index: git/sysdeps/generic/ldsodefs.h +=================================================================== +--- git.orig/sysdeps/generic/ldsodefs.h ++++ git/sysdeps/generic/ldsodefs.h +@@ -590,9 +590,6 @@ struct rtld_global_ro + /* List of auditing interfaces. */ + struct audit_ifaces *_dl_audit; + unsigned int _dl_naudit; +- +- /* 0 if internal pointer values should not be guarded, 1 if they should. */ +- EXTERN int _dl_pointer_guard; + }; + # define __rtld_global_attribute__ + # if IS_IN (rtld) +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog ++++ git/ChangeLog +@@ -1,3 +1,13 @@ ++2015-10-15 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #18928] ++ * sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove ++ _dl_pointer_guard member. ++ * elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard ++ initializer. ++ (security_init): Always set up pointer guard. ++ (process_envvars): Do not process LD_POINTER_GUARD. ++ + 2015-02-06 Carlos O'Donell <carlos@systemhalted.org> + + * version.h (RELEASE): Set to "stable". +Index: git/NEWS +=================================================================== +--- git.orig/NEWS ++++ git/NEWS +@@ -19,7 +19,10 @@ Version 2.21 + 17722, 17723, 17724, 17725, 17732, 17733, 17744, 17745, 17746, 17747, + 17748, 17775, 17777, 17780, 17781, 17782, 17791, 17793, 17796, 17797, + 17801, 17803, 17806, 17834, 17844, 17848, 17868, 17869, 17870, 17885, +- 17892. ++ 17892, 18928. ++ ++* The LD_POINTER_GUARD environment variable can no longer be used to ++ disable the pointer guard feature. It is always enabled. + + * CVE-2015-1472 Under certain conditions wscanf can allocate too little + memory for the to-be-scanned arguments and overflow the allocated diff --git a/meta/recipes-core/glibc/glibc_2.21.bb b/meta/recipes-core/glibc/glibc_2.21.bb index 3bba734..efbcc9c 100644 --- a/meta/recipes-core/glibc/glibc_2.21.bb +++ b/meta/recipes-core/glibc/glibc_2.21.bb @@ -48,6 +48,7 @@ EGLIBCPATCHES = "\ # CVEPATCHES = "\ file://CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch \ + file://CVE-2015-8777.patch \ " LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \ -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 02/21] glibc: CVE-2015-8779 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster 2016-02-06 23:14 ` [PATCH 01/21] glibc: CVE-2015-8777 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 03/21] glibc: CVE-2015-9761 Armin Kuster ` (19 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> A stack overflow vulnerability in the catopen function was found, causing applications which pass long strings to the catopen function to crash or, potentially execute arbitrary code. (From OE-Core rev: af20e323932caba8883c91dac610e1ba2b3d4ab5) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- meta/recipes-core/glibc/glibc/CVE-2015-8779.patch | 262 ++++++++++++++++++++++ meta/recipes-core/glibc/glibc_2.21.bb | 1 + 2 files changed, 263 insertions(+) create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-8779.patch diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-8779.patch b/meta/recipes-core/glibc/glibc/CVE-2015-8779.patch new file mode 100644 index 0000000..ddc0742 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2015-8779.patch @@ -0,0 +1,262 @@ +From 0f58539030e436449f79189b6edab17d7479796e Mon Sep 17 00:00:00 2001 +From: Paul Pluzhnikov <ppluzhnikov@google.com> +Date: Sat, 8 Aug 2015 15:53:03 -0700 +Subject: [PATCH] Fix BZ #17905 + +Upstream-Status: Backport +CVE: CVE-2015-8779 +[Yocto # 8980] + +https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0f58539030e436449f79189b6edab17d7479796e + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ChangeLog | 8 ++++++++ + NEWS | 2 +- + catgets/Makefile | 9 ++++++++- + catgets/catgets.c | 19 ++++++++++++------- + catgets/open_catalog.c | 23 ++++++++++++++--------- + catgets/tst-catgets.c | 31 +++++++++++++++++++++++++++++++ + 6 files changed, 74 insertions(+), 18 deletions(-) + +Index: git/catgets/Makefile +=================================================================== +--- git.orig/catgets/Makefile ++++ git/catgets/Makefile +@@ -37,6 +37,7 @@ ifeq (y,$(OPTION_EGLIBC_CATGETS)) + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \ + $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out ++tests-special += $(objpfx)tst-catgets-mem.out + endif + endif + gencat-modules = xmalloc +@@ -53,9 +54,11 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcat + + generated += de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \ + test-gencat.h ++generated += tst-catgets.mtrace tst-catgets-mem.out ++ + generated-dirs += de + +-tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de ++tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace + + ifeq ($(run-built-tests),yes) + # This test just checks whether the program produces any error or not. +@@ -89,4 +92,8 @@ $(objpfx)test-gencat.out: test-gencat.sh + $(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat + $(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \ ++ $(evaluate-test) + endif +Index: git/catgets/catgets.c +=================================================================== +--- git.orig/catgets/catgets.c ++++ git/catgets/catgets.c +@@ -16,7 +16,6 @@ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +-#include <alloca.h> + #include <errno.h> + #include <locale.h> + #include <nl_types.h> +@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag) + __nl_catd result; + const char *env_var = NULL; + const char *nlspath = NULL; ++ char *tmp = NULL; + + if (strchr (cat_name, '/') == NULL) + { +@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag) + { + /* Append the system dependent directory. */ + size_t len = strlen (nlspath) + 1 + sizeof NLSPATH; +- char *tmp = alloca (len); ++ tmp = malloc (len); ++ ++ if (__glibc_unlikely (tmp == NULL)) ++ return (nl_catd) -1; + + __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH); + nlspath = tmp; +@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag) + + result = (__nl_catd) malloc (sizeof (*result)); + if (result == NULL) +- /* We cannot get enough memory. */ +- return (nl_catd) -1; +- +- if (__open_catalog (cat_name, nlspath, env_var, result) != 0) ++ { ++ /* We cannot get enough memory. */ ++ result = (nl_catd) -1; ++ } ++ else if (__open_catalog (cat_name, nlspath, env_var, result) != 0) + { + /* Couldn't open the file. */ + free ((void *) result); +- return (nl_catd) -1; ++ result = (nl_catd) -1; + } + ++ free (tmp); + return (nl_catd) result; + } + +Index: git/catgets/open_catalog.c +=================================================================== +--- git.orig/catgets/open_catalog.c ++++ git/catgets/open_catalog.c +@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, co + size_t tab_size; + const char *lastp; + int result = -1; ++ char *buf = NULL; + + if (strchr (cat_name, '/') != NULL || nlspath == NULL) + fd = open_not_cancel_2 (cat_name, O_RDONLY); +@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, co + if (__glibc_unlikely (bufact + (n) >= bufmax)) \ + { \ + char *old_buf = buf; \ +- bufmax += 256 + (n); \ +- buf = (char *) alloca (bufmax); \ +- memcpy (buf, old_buf, bufact); \ ++ bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax; \ ++ buf = realloc (buf, bufmax); \ ++ if (__glibc_unlikely (buf == NULL)) \ ++ { \ ++ free (old_buf); \ ++ return -1; \ ++ } \ + } + + /* The RUN_NLSPATH variable contains a colon separated list of + descriptions where we expect to find catalogs. We have to + recognize certain % substitutions and stop when we found the + first existing file. */ +- char *buf; + size_t bufact; +- size_t bufmax; ++ size_t bufmax = 0; + size_t len; + +- buf = NULL; +- bufmax = 0; +- + fd = -1; + while (*run_nlspath != '\0') + { +@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, co + + /* Avoid dealing with directories and block devices */ + if (__builtin_expect (fd, 0) < 0) +- return -1; ++ { ++ free (buf); ++ return -1; ++ } + + if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0) + goto close_unlock_return; +@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, co + /* Release the lock again. */ + close_unlock_return: + close_not_cancel_no_status (fd); ++ free (buf); + + return result; + } +Index: git/catgets/tst-catgets.c +=================================================================== +--- git.orig/catgets/tst-catgets.c ++++ git/catgets/tst-catgets.c +@@ -1,7 +1,10 @@ ++#include <assert.h> + #include <mcheck.h> + #include <nl_types.h> + #include <stdio.h> ++#include <stdlib.h> + #include <string.h> ++#include <sys/resource.h> + + + static const char *msgs[] = +@@ -12,6 +15,33 @@ static const char *msgs[] = + }; + #define nmsgs (sizeof (msgs) / sizeof (msgs[0])) + ++ ++/* Test for unbounded alloca. */ ++static int ++do_bz17905 (void) ++{ ++ char *buf; ++ struct rlimit rl; ++ nl_catd result; ++ ++ const int sz = 1024 * 1024; ++ ++ getrlimit (RLIMIT_STACK, &rl); ++ rl.rlim_cur = sz; ++ setrlimit (RLIMIT_STACK, &rl); ++ ++ buf = malloc (sz + 1); ++ memset (buf, 'A', sz); ++ buf[sz] = '\0'; ++ setenv ("NLSPATH", buf, 1); ++ ++ result = catopen (buf, NL_CAT_LOCALE); ++ assert (result == (nl_catd) -1); ++ ++ free (buf); ++ return 0; ++} ++ + #define ROUNDS 5 + + static int +@@ -62,6 +92,7 @@ do_test (void) + } + } + ++ result += do_bz17905 (); + return result; + } + +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog ++++ git/ChangeLog +@@ -1,3 +1,11 @@ ++2015-08-08 Paul Pluzhnikov <ppluzhnikov@google.com> ++ ++ [BZ #17905] ++ * catgets/Makefile (tst-catgets-mem): New test. ++ * catgets/catgets.c (catopen): Don't use unbounded alloca. ++ * catgets/open_catalog.c (__open_catalog): Likewise. ++ * catgets/tst-catgets.c (do_bz17905): Test unbounded alloca. ++ + 2015-10-15 Florian Weimer <fweimer@redhat.com> + + [BZ #18928] +Index: git/NEWS +=================================================================== +--- git.orig/NEWS ++++ git/NEWS +@@ -19,7 +19,7 @@ Version 2.21 + 17722, 17723, 17724, 17725, 17732, 17733, 17744, 17745, 17746, 17747, + 17748, 17775, 17777, 17780, 17781, 17782, 17791, 17793, 17796, 17797, + 17801, 17803, 17806, 17834, 17844, 17848, 17868, 17869, 17870, 17885, +- 17892, 18928. ++ 17892, 18928, 17905. + + * The LD_POINTER_GUARD environment variable can no longer be used to + disable the pointer guard feature. It is always enabled. diff --git a/meta/recipes-core/glibc/glibc_2.21.bb b/meta/recipes-core/glibc/glibc_2.21.bb index efbcc9c..afe32d5 100644 --- a/meta/recipes-core/glibc/glibc_2.21.bb +++ b/meta/recipes-core/glibc/glibc_2.21.bb @@ -49,6 +49,7 @@ EGLIBCPATCHES = "\ CVEPATCHES = "\ file://CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch \ file://CVE-2015-8777.patch \ + file://CVE-2015-8779.patch \ " LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \ -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 03/21] glibc: CVE-2015-9761 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster 2016-02-06 23:14 ` [PATCH 01/21] glibc: CVE-2015-8777 Armin Kuster 2016-02-06 23:14 ` [PATCH 02/21] glibc: CVE-2015-8779 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 04/21] glibc: CVE-2015-8776 Armin Kuster ` (18 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> A stack overflow vulnerability was found in nan* functions that could cause applications which process long strings with the nan function to crash or, potentially, execute arbitrary code. (From OE-Core rev: fd3da8178c8c06b549dbc19ecec40e98ab934d49) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../recipes-core/glibc/glibc/CVE-2015-9761_1.patch | 1039 ++++++++++++++++++++ .../recipes-core/glibc/glibc/CVE-2015-9761_2.patch | 388 ++++++++ meta/recipes-core/glibc/glibc_2.21.bb | 2 + 3 files changed, 1429 insertions(+) create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch b/meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch new file mode 100644 index 0000000..3aca913 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch @@ -0,0 +1,1039 @@ +From e02cabecf0d025ec4f4ddee290bdf7aadb873bb3 Mon Sep 17 00:00:00 2001 +From: Joseph Myers <joseph@codesourcery.com> +Date: Tue, 24 Nov 2015 22:24:52 +0000 +Subject: [PATCH] Refactor strtod parsing of NaN payloads. + +The nan* functions handle their string argument by constructing a +NAN(...) string on the stack as a VLA and passing it to strtod +functions. + +This approach has problems discussed in bug 16961 and bug 16962: the +stack usage is unbounded, and it gives incorrect results in certain +cases where the argument is not a valid n-char-sequence. + +The natural fix for both issues is to refactor the NaN payload parsing +out of strtod into a separate function that the nan* functions can +call directly, so that no temporary string needs constructing on the +stack at all. This patch does that refactoring in preparation for +fixing those bugs (but without actually using the new functions from +nan* - which will also require exporting them from libc at version +GLIBC_PRIVATE). This patch is not intended to change any user-visible +behavior, so no tests are added (fixes for the above bugs will of +course add tests for them). + +This patch builds on my recent fixes for strtol and strtod issues in +Turkish locales. Given those fixes, the parsing of NaN payloads is +locale-independent; thus, the new functions do not need to take a +locale_t argument. + +Tested for x86_64, x86, mips64 and powerpc. + + * stdlib/strtod_nan.c: New file. + * stdlib/strtod_nan_double.h: Likewise. + * stdlib/strtod_nan_float.h: Likewise. + * stdlib/strtod_nan_main.c: Likewise. + * stdlib/strtod_nan_narrow.h: Likewise. + * stdlib/strtod_nan_wide.h: Likewise. + * stdlib/strtof_nan.c: Likewise. + * stdlib/strtold_nan.c: Likewise. + * sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise. + * sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise. + * sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise. + * wcsmbs/wcstod_nan.c: Likewise. + * wcsmbs/wcstof_nan.c: Likewise. + * wcsmbs/wcstold_nan.c: Likewise. + * stdlib/Makefile (routines): Add strtof_nan, strtod_nan and + strtold_nan. + * wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and + wcstof_nan. + * include/stdlib.h (__strtof_nan): Declare and use + libc_hidden_proto. + (__strtod_nan): Likewise. + (__strtold_nan): Likewise. + (__wcstof_nan): Likewise. + (__wcstod_nan): Likewise. + (__wcstold_nan): Likewise. + * include/wchar.h (____wcstoull_l_internal): Declare. + * stdlib/strtod_l.c: Do not include <ieee754.h>. + (____strtoull_l_internal): Remove declaration. + (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + (STRTOULL): Likewise. + (____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload. + * stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration. + (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define + macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define + macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration. + * wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise. + * wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise. + +Upstream-Status: Backport +CVE: CVE-2015-9761 patch #1 +[Yocto # 8980] + +https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e02cabecf0d025ec4f4ddee290bdf7aadb873bb3 + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ChangeLog | 49 ++++++++++++++++++ + include/stdlib.h | 18 +++++++ + include/wchar.h | 3 ++ + stdlib/Makefile | 1 + + stdlib/strtod_l.c | 48 ++++-------------- + stdlib/strtod_nan.c | 24 +++++++++ + stdlib/strtod_nan_double.h | 30 +++++++++++ + stdlib/strtod_nan_float.h | 29 +++++++++++ + stdlib/strtod_nan_main.c | 63 ++++++++++++++++++++++++ + stdlib/strtod_nan_narrow.h | 22 +++++++++ + stdlib/strtod_nan_wide.h | 22 +++++++++ + stdlib/strtof_l.c | 11 +---- + stdlib/strtof_nan.c | 24 +++++++++ + stdlib/strtold_nan.c | 30 +++++++++++ + sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h | 33 +++++++++++++ + sysdeps/ieee754/ldbl-128/strtold_l.c | 13 +---- + sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h | 30 +++++++++++ + sysdeps/ieee754/ldbl-128ibm/strtold_l.c | 10 +--- + sysdeps/ieee754/ldbl-64-128/strtold_l.c | 13 +---- + sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h | 30 +++++++++++ + sysdeps/ieee754/ldbl-96/strtold_l.c | 10 +--- + wcsmbs/Makefile | 1 + + wcsmbs/wcstod_l.c | 3 -- + wcsmbs/wcstod_nan.c | 23 +++++++++ + wcsmbs/wcstof_l.c | 3 -- + wcsmbs/wcstof_nan.c | 23 +++++++++ + wcsmbs/wcstold_l.c | 3 -- + wcsmbs/wcstold_nan.c | 30 +++++++++++ + 28 files changed, 504 insertions(+), 95 deletions(-) + create mode 100644 stdlib/strtod_nan.c + create mode 100644 stdlib/strtod_nan_double.h + create mode 100644 stdlib/strtod_nan_float.h + create mode 100644 stdlib/strtod_nan_main.c + create mode 100644 stdlib/strtod_nan_narrow.h + create mode 100644 stdlib/strtod_nan_wide.h + create mode 100644 stdlib/strtof_nan.c + create mode 100644 stdlib/strtold_nan.c + create mode 100644 sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h + create mode 100644 sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h + create mode 100644 sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h + create mode 100644 wcsmbs/wcstod_nan.c + create mode 100644 wcsmbs/wcstof_nan.c + create mode 100644 wcsmbs/wcstold_nan.c + +Index: git/include/stdlib.h +=================================================================== +--- git.orig/include/stdlib.h ++++ git/include/stdlib.h +@@ -203,6 +203,24 @@ libc_hidden_proto (strtoll) + libc_hidden_proto (strtoul) + libc_hidden_proto (strtoull) + ++extern float __strtof_nan (const char *, char **, char) internal_function; ++extern double __strtod_nan (const char *, char **, char) internal_function; ++extern long double __strtold_nan (const char *, char **, char) ++ internal_function; ++extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++ ++libc_hidden_proto (__strtof_nan) ++libc_hidden_proto (__strtod_nan) ++libc_hidden_proto (__strtold_nan) ++libc_hidden_proto (__wcstof_nan) ++libc_hidden_proto (__wcstod_nan) ++libc_hidden_proto (__wcstold_nan) ++ + extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign); + extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt, +Index: git/include/wchar.h +=================================================================== +--- git.orig/include/wchar.h ++++ git/include/wchar.h +@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull + __restrict __endptr, + int __base, + int __group) __THROW; ++extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, ++ wchar_t **, int, int, ++ __locale_t); + libc_hidden_proto (__wcstof_internal) + libc_hidden_proto (__wcstod_internal) + libc_hidden_proto (__wcstold_internal) +Index: git/stdlib/Makefile +=================================================================== +--- git.orig/stdlib/Makefile ++++ git/stdlib/Makefile +@@ -51,6 +51,7 @@ routines-y := \ + strtol_l strtoul_l strtoll_l strtoull_l \ + strtof strtod strtold \ + strtof_l strtod_l strtold_l \ ++ strtof_nan strtod_nan strtold_nan \ + system canonicalize \ + a64l l64a \ + getsubopt xpg_basename \ +Index: git/stdlib/strtod_l.c +=================================================================== +--- git.orig/stdlib/strtod_l.c ++++ git/stdlib/strtod_l.c +@@ -21,8 +21,6 @@ + #include <xlocale.h> + + extern double ____strtod_l_internal (const char *, char **, int, __locale_t); +-extern unsigned long long int ____strtoull_l_internal (const char *, char **, +- int, int, __locale_t); + + /* Configuration part. These macros are defined by `strtold.c', + `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the +@@ -34,27 +32,20 @@ extern unsigned long long int ____strtou + # ifdef USE_WIDE_CHAR + # define STRTOF wcstod_l + # define __STRTOF __wcstod_l ++# define STRTOF_NAN __wcstod_nan + # else + # define STRTOF strtod_l + # define __STRTOF __strtod_l ++# define STRTOF_NAN __strtod_nan + # endif + # define MPN2FLOAT __mpn_construct_double + # define FLOAT_HUGE_VAL HUGE_VAL +-# define SET_MANTISSA(flt, mant) \ +- do { union ieee754_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = (mant) >> 32; \ +- u.ieee_nan.mantissa1 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ +- (flt) = u.d; \ +- } while (0) + #endif + /* End of configuration part. */ + \f + #include <ctype.h> + #include <errno.h> + #include <float.h> +-#include <ieee754.h> + #include "../locale/localeinfo.h" + #include <locale.h> + #include <math.h> +@@ -105,7 +96,6 @@ extern unsigned long long int ____strtou + # define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr) + # define STRNCASECMP(S1, S2, N) \ + __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr) +-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc) + #else + # define STRING_TYPE char + # define CHAR_TYPE char +@@ -117,7 +107,6 @@ extern unsigned long long int ____strtou + # define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr) + # define STRNCASECMP(S1, S2, N) \ + __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr) +-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc) + #endif + + +@@ -668,33 +657,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group + if (*cp == L_('(')) + { + const STRING_TYPE *startp = cp; +- do +- ++cp; +- while ((*cp >= L_('0') && *cp <= L_('9')) +- || ({ CHAR_TYPE lo = TOLOWER (*cp); +- lo >= L_('a') && lo <= L_('z'); }) +- || *cp == L_('_')); +- +- if (*cp != L_(')')) +- /* The closing brace is missing. Only match the NAN +- part. */ +- cp = startp; ++ STRING_TYPE *endp; ++ retval = STRTOF_NAN (cp + 1, &endp, L_(')')); ++ if (*endp == L_(')')) ++ /* Consume the closing parenthesis. */ ++ cp = endp + 1; + else +- { +- /* This is a system-dependent way to specify the +- bitmask used for the NaN. We expect it to be +- a number which is put in the mantissa of the +- number. */ +- STRING_TYPE *endp; +- unsigned long long int mant; +- +- mant = STRTOULL (startp + 1, &endp, 0); +- if (endp == cp) +- SET_MANTISSA (retval, mant); +- +- /* Consume the closing brace. */ +- ++cp; +- } ++ /* Only match the NAN part. */ ++ cp = startp; + } + + if (endptr != NULL) +Index: git/stdlib/strtod_nan.c +=================================================================== +--- /dev/null ++++ git/stdlib/strtod_nan.c +@@ -0,0 +1,24 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <strtod_nan_narrow.h> ++#include <strtod_nan_double.h> ++ ++#define STRTOD_NAN __strtod_nan ++#include <strtod_nan_main.c> +Index: git/stdlib/strtod_nan_double.h +=================================================================== +--- /dev/null ++++ git/stdlib/strtod_nan_double.h +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For double. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define FLOAT double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee754_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.ieee_nan.mantissa1 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +Index: git/stdlib/strtod_nan_float.h +=================================================================== +--- /dev/null ++++ git/stdlib/strtod_nan_float.h +@@ -0,0 +1,29 @@ ++/* Convert string for NaN payload to corresponding NaN. For float. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define FLOAT float ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee754_float u; \ ++ u.f = (flt); \ ++ u.ieee_nan.mantissa = (mant); \ ++ if (u.ieee.mantissa != 0) \ ++ (flt) = u.f; \ ++ } \ ++ while (0) +Index: git/stdlib/strtod_nan_main.c +=================================================================== +--- /dev/null ++++ git/stdlib/strtod_nan_main.c +@@ -0,0 +1,63 @@ ++/* Convert string for NaN payload to corresponding NaN. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <ieee754.h> ++#include <locale.h> ++#include <math.h> ++#include <stdlib.h> ++#include <wchar.h> ++ ++ ++/* If STR starts with an optional n-char-sequence as defined by ISO C ++ (a sequence of ASCII letters, digits and underscores), followed by ++ ENDC, return a NaN whose payload is set based on STR. Otherwise, ++ return a default NAN. If ENDPTR is not NULL, set *ENDPTR to point ++ to the character after the initial n-char-sequence. */ ++ ++internal_function ++FLOAT ++STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc) ++{ ++ const STRING_TYPE *cp = str; ++ ++ while ((*cp >= L_('0') && *cp <= L_('9')) ++ || (*cp >= L_('A') && *cp <= L_('Z')) ++ || (*cp >= L_('a') && *cp <= L_('z')) ++ || *cp == L_('_')) ++ ++cp; ++ ++ FLOAT retval = NAN; ++ if (*cp != endc) ++ goto out; ++ ++ /* This is a system-dependent way to specify the bitmask used for ++ the NaN. We expect it to be a number which is put in the ++ mantissa of the number. */ ++ STRING_TYPE *endp; ++ unsigned long long int mant; ++ ++ mant = STRTOULL (str, &endp, 0); ++ if (endp == cp) ++ SET_MANTISSA (retval, mant); ++ ++ out: ++ if (endptr != NULL) ++ *endptr = (STRING_TYPE *) cp; ++ return retval; ++} ++libc_hidden_def (STRTOD_NAN) +Index: git/stdlib/strtod_nan_narrow.h +=================================================================== +--- /dev/null ++++ git/stdlib/strtod_nan_narrow.h +@@ -0,0 +1,22 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow strings. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define STRING_TYPE char ++#define L_(Ch) Ch ++#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, \ ++ _nl_C_locobj_ptr) +Index: git/stdlib/strtod_nan_wide.h +=================================================================== +--- /dev/null ++++ git/stdlib/strtod_nan_wide.h +@@ -0,0 +1,22 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define STRING_TYPE wchar_t ++#define L_(Ch) L##Ch ++#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, \ ++ _nl_C_locobj_ptr) +Index: git/stdlib/strtof_l.c +=================================================================== +--- git.orig/stdlib/strtof_l.c ++++ git/stdlib/strtof_l.c +@@ -20,26 +20,19 @@ + #include <xlocale.h> + + extern float ____strtof_l_internal (const char *, char **, int, __locale_t); +-extern unsigned long long int ____strtoull_l_internal (const char *, char **, +- int, int, __locale_t); + + #define FLOAT float + #define FLT FLT + #ifdef USE_WIDE_CHAR + # define STRTOF wcstof_l + # define __STRTOF __wcstof_l ++# define STRTOF_NAN __wcstof_nan + #else + # define STRTOF strtof_l + # define __STRTOF __strtof_l ++# define STRTOF_NAN __strtof_nan + #endif + #define MPN2FLOAT __mpn_construct_float + #define FLOAT_HUGE_VAL HUGE_VALF +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee754_float u; \ +- u.f = (flt); \ +- u.ieee_nan.mantissa = (mant); \ +- if (u.ieee.mantissa != 0) \ +- (flt) = u.f; \ +- } while (0) + + #include "strtod_l.c" +Index: git/stdlib/strtof_nan.c +=================================================================== +--- /dev/null ++++ git/stdlib/strtof_nan.c +@@ -0,0 +1,24 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, float. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <strtod_nan_narrow.h> ++#include <strtod_nan_float.h> ++ ++#define STRTOD_NAN __strtof_nan ++#include <strtod_nan_main.c> +Index: git/stdlib/strtold_nan.c +=================================================================== +--- /dev/null ++++ git/stdlib/strtold_nan.c +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, long double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <math.h> ++ ++/* This function is unused if long double and double have the same ++ representation. */ ++#ifndef __NO_LONG_DOUBLE_MATH ++# include <strtod_nan_narrow.h> ++# include <strtod_nan_ldouble.h> ++ ++# define STRTOD_NAN __strtold_nan ++# include <strtod_nan_main.c> ++#endif +Index: git/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h +=================================================================== +--- /dev/null ++++ git/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h +@@ -0,0 +1,33 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-128. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee854_long_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = 0; \ ++ u.ieee_nan.mantissa1 = 0; \ ++ u.ieee_nan.mantissa2 = (mant) >> 32; \ ++ u.ieee_nan.mantissa3 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ ++ | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +Index: git/sysdeps/ieee754/ldbl-128/strtold_l.c +=================================================================== +--- git.orig/sysdeps/ieee754/ldbl-128/strtold_l.c ++++ git/sysdeps/ieee754/ldbl-128/strtold_l.c +@@ -25,22 +25,13 @@ + #ifdef USE_WIDE_CHAR + # define STRTOF wcstold_l + # define __STRTOF __wcstold_l ++# define STRTOF_NAN __wcstold_nan + #else + # define STRTOF strtold_l + # define __STRTOF __strtold_l ++# define STRTOF_NAN __strtold_nan + #endif + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = 0; \ +- u.ieee_nan.mantissa1 = 0; \ +- u.ieee_nan.mantissa2 = (mant) >> 32; \ +- u.ieee_nan.mantissa3 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ +- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ +- (flt) = u.d; \ +- } while (0) + + #include <strtod_l.c> +Index: git/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h +=================================================================== +--- /dev/null ++++ git/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-128ibm. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ibm_extended_long_double u; \ ++ u.ld = (flt); \ ++ u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.d[0].ieee_nan.mantissa1 = (mant); \ ++ if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ ++ (flt) = u.ld; \ ++ } \ ++ while (0) +Index: git/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +=================================================================== +--- git.orig/sysdeps/ieee754/ldbl-128ibm/strtold_l.c ++++ git/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (co + # define STRTOF __new_wcstold_l + # define __STRTOF ____new_wcstold_l + # define ____STRTOF_INTERNAL ____wcstold_l_internal ++# define STRTOF_NAN __wcstold_nan + #else + extern long double ____new_strtold_l (const char *, char **, __locale_t); + # define STRTOF __new_strtold_l + # define __STRTOF ____new_strtold_l + # define ____STRTOF_INTERNAL ____strtold_l_internal ++# define STRTOF_NAN __strtold_nan + #endif + extern __typeof (__STRTOF) STRTOF; + libc_hidden_proto (__STRTOF) + libc_hidden_proto (STRTOF) + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-# define SET_MANTISSA(flt, mant) \ +- do { union ibm_extended_long_double u; \ +- u.ld = (flt); \ +- u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ +- u.d[0].ieee_nan.mantissa1 = (mant); \ +- if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ +- (flt) = u.ld; \ +- } while (0) + + #include <strtod_l.c> + +Index: git/sysdeps/ieee754/ldbl-64-128/strtold_l.c +=================================================================== +--- git.orig/sysdeps/ieee754/ldbl-64-128/strtold_l.c ++++ git/sysdeps/ieee754/ldbl-64-128/strtold_l.c +@@ -30,28 +30,19 @@ extern long double ____new_wcstold_l (co + # define STRTOF __new_wcstold_l + # define __STRTOF ____new_wcstold_l + # define ____STRTOF_INTERNAL ____wcstold_l_internal ++# define STRTOF_NAN __wcstold_nan + #else + extern long double ____new_strtold_l (const char *, char **, __locale_t); + # define STRTOF __new_strtold_l + # define __STRTOF ____new_strtold_l + # define ____STRTOF_INTERNAL ____strtold_l_internal ++# define STRTOF_NAN __strtold_nan + #endif + extern __typeof (__STRTOF) STRTOF; + libc_hidden_proto (__STRTOF) + libc_hidden_proto (STRTOF) + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = 0; \ +- u.ieee_nan.mantissa1 = 0; \ +- u.ieee_nan.mantissa2 = (mant) >> 32; \ +- u.ieee_nan.mantissa3 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ +- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ +- (flt) = u.d; \ +- } while (0) + + #include <strtod_l.c> + +Index: git/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h +=================================================================== +--- /dev/null ++++ git/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-96. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee854_long_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.ieee_nan.mantissa1 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +Index: git/sysdeps/ieee754/ldbl-96/strtold_l.c +=================================================================== +--- git.orig/sysdeps/ieee754/ldbl-96/strtold_l.c ++++ git/sysdeps/ieee754/ldbl-96/strtold_l.c +@@ -25,19 +25,13 @@ + #ifdef USE_WIDE_CHAR + # define STRTOF wcstold_l + # define __STRTOF __wcstold_l ++# define STRTOF_NAN __wcstold_nan + #else + # define STRTOF strtold_l + # define __STRTOF __strtold_l ++# define STRTOF_NAN __strtold_nan + #endif + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = (mant) >> 32; \ +- u.ieee_nan.mantissa1 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ +- (flt) = u.d; \ +- } while (0) + + #include <stdlib/strtod_l.c> +Index: git/wcsmbs/Makefile +=================================================================== +--- git.orig/wcsmbs/Makefile ++++ git/wcsmbs/Makefile +@@ -39,6 +39,7 @@ routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR + wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \ + wcstol_l wcstoul_l wcstoll_l wcstoull_l \ + wcstod_l wcstold_l wcstof_l \ ++ wcstod_nan wcstold_nan wcstof_nan \ + wcscoll wcsxfrm \ + wcwidth wcswidth \ + wcscoll_l wcsxfrm_l \ +Index: git/wcsmbs/wcstod_l.c +=================================================================== +--- git.orig/wcsmbs/wcstod_l.c ++++ git/wcsmbs/wcstod_l.c +@@ -23,9 +23,6 @@ + + extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #define USE_WIDE_CHAR 1 + +Index: git/wcsmbs/wcstod_nan.c +=================================================================== +--- /dev/null ++++ git/wcsmbs/wcstod_nan.c +@@ -0,0 +1,23 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include "../stdlib/strtod_nan_wide.h" ++#include "../stdlib/strtod_nan_double.h" ++ ++#define STRTOD_NAN __wcstod_nan ++#include "../stdlib/strtod_nan_main.c" +Index: git/wcsmbs/wcstof_l.c +=================================================================== +--- git.orig/wcsmbs/wcstof_l.c ++++ git/wcsmbs/wcstof_l.c +@@ -25,8 +25,5 @@ + + extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #include <stdlib/strtof_l.c> +Index: git/wcsmbs/wcstof_nan.c +=================================================================== +--- /dev/null ++++ git/wcsmbs/wcstof_nan.c +@@ -0,0 +1,23 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, float. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include "../stdlib/strtod_nan_wide.h" ++#include "../stdlib/strtod_nan_float.h" ++ ++#define STRTOD_NAN __wcstof_nan ++#include "../stdlib/strtod_nan_main.c" +Index: git/wcsmbs/wcstold_l.c +=================================================================== +--- git.orig/wcsmbs/wcstold_l.c ++++ git/wcsmbs/wcstold_l.c +@@ -24,8 +24,5 @@ + + extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #include <strtold_l.c> +Index: git/wcsmbs/wcstold_nan.c +=================================================================== +--- /dev/null ++++ git/wcsmbs/wcstold_nan.c +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, ++ long double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <math.h> ++ ++/* This function is unused if long double and double have the same ++ representation. */ ++#ifndef __NO_LONG_DOUBLE_MATH ++# include "../stdlib/strtod_nan_wide.h" ++# include <strtod_nan_ldouble.h> ++ ++# define STRTOD_NAN __wcstold_nan ++# include "../stdlib/strtod_nan_main.c" ++#endif +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog ++++ git/ChangeLog +@@ -1,3 +1,57 @@ ++2015-11-24 Joseph Myers <joseph@codesourcery.com> ++ ++ * stdlib/strtod_nan.c: New file. ++ * stdlib/strtod_nan_double.h: Likewise. ++ * stdlib/strtod_nan_float.h: Likewise. ++ * stdlib/strtod_nan_main.c: Likewise. ++ * stdlib/strtod_nan_narrow.h: Likewise. ++ * stdlib/strtod_nan_wide.h: Likewise. ++ * stdlib/strtof_nan.c: Likewise. ++ * stdlib/strtold_nan.c: Likewise. ++ * sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise. ++ * sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise. ++ * sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise. ++ * wcsmbs/wcstod_nan.c: Likewise. ++ * wcsmbs/wcstof_nan.c: Likewise. ++ * wcsmbs/wcstold_nan.c: Likewise. ++ * stdlib/Makefile (routines): Add strtof_nan, strtod_nan and ++ strtold_nan. ++ * wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and ++ wcstof_nan. ++ * include/stdlib.h (__strtof_nan): Declare and use ++ libc_hidden_proto. ++ (__strtod_nan): Likewise. ++ (__strtold_nan): Likewise. ++ (__wcstof_nan): Likewise. ++ (__wcstod_nan): Likewise. ++ (__wcstold_nan): Likewise. ++ * include/wchar.h (____wcstoull_l_internal): Declare. ++ * stdlib/strtod_l.c: Do not include <ieee754.h>. ++ (____strtoull_l_internal): Remove declaration. ++ (STRTOF_NAN): Define macro. ++ (SET_MANTISSA): Remove macro. ++ (STRTOULL): Likewise. ++ (____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload. ++ * stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration. ++ (STRTOF_NAN): Define macro. ++ (SET_MANTISSA): Remove macro. ++ * sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro. ++ (SET_MANTISSA): Remove macro. ++ * sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define ++ macro. ++ (SET_MANTISSA): Remove macro. ++ * sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define ++ macro. ++ (SET_MANTISSA): Remove macro. ++ * sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro. ++ (SET_MANTISSA): Remove macro. ++ * wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration. ++ * wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise. ++ * wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise. ++ ++ [BZ #19266] ++ * stdlib/strtod_l.c (____STRTOF_INTERNAL): Check directly for ++ upper case and lower case letters inside NAN(), not using TOLOWER. + 2015-08-08 Paul Pluzhnikov <ppluzhnikov@google.com> + + [BZ #17905] diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch b/meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch new file mode 100644 index 0000000..0df5e50 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch @@ -0,0 +1,388 @@ +From 8f5e8b01a1da2a207228f2072c934fa5918554b8 Mon Sep 17 00:00:00 2001 +From: Joseph Myers <joseph@codesourcery.com> +Date: Fri, 4 Dec 2015 20:36:28 +0000 +Subject: [PATCH] Fix nan functions handling of payload strings (bug 16961, bug + 16962). + +The nan, nanf and nanl functions handle payload strings by doing e.g.: + + if (tagp[0] != '\0') + { + char buf[6 + strlen (tagp)]; + sprintf (buf, "NAN(%s)", tagp); + return strtod (buf, NULL); + } + +This is an unbounded stack allocation based on the length of the +argument. Furthermore, if the argument starts with an n-char-sequence +followed by ')', that n-char-sequence is wrongly treated as +significant for determining the payload of the resulting NaN, when ISO +C says the call should be equivalent to strtod ("NAN", NULL), without +being affected by that initial n-char-sequence. This patch fixes both +those problems by using the __strtod_nan etc. functions recently +factored out of strtod etc. for that purpose, with those functions +being exported from libc at version GLIBC_PRIVATE. + +Tested for x86_64, x86, mips64 and powerpc. + + [BZ #16961] + [BZ #16962] + * math/s_nan.c (__nan): Use __strtod_nan instead of constructing a + string on the stack for strtod. + * math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing + a string on the stack for strtof. + * math/s_nanl.c (__nanl): Use __strtold_nan instead of + constructing a string on the stack for strtold. + * stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and + __strtold_nan to GLIBC_PRIVATE. + * math/test-nan-overflow.c: New file. + * math/test-nan-payload.c: Likewise. + * math/Makefile (tests): Add test-nan-overflow and + test-nan-payload. + +Upstream-Status: Backport +CVE: CVE-2015-9761 patch #2 +[Yocto # 8980] + +https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=8f5e8b01a1da2a207228f2072c934fa5918554b8 + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ChangeLog | 17 +++++++ + NEWS | 6 +++ + math/Makefile | 3 +- + math/s_nan.c | 9 +--- + math/s_nanf.c | 9 +--- + math/s_nanl.c | 9 +--- + math/test-nan-overflow.c | 66 +++++++++++++++++++++++++ + math/test-nan-payload.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++ + stdlib/Versions | 1 + + 9 files changed, 217 insertions(+), 25 deletions(-) + create mode 100644 math/test-nan-overflow.c + create mode 100644 math/test-nan-payload.c + +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog ++++ git/ChangeLog +@@ -1,3 +1,20 @@ ++2015-12-04 Joseph Myers <joseph@codesourcery.com> ++ ++ [BZ #16961] ++ [BZ #16962] ++ * math/s_nan.c (__nan): Use __strtod_nan instead of constructing a ++ string on the stack for strtod. ++ * math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing ++ a string on the stack for strtof. ++ * math/s_nanl.c (__nanl): Use __strtold_nan instead of ++ constructing a string on the stack for strtold. ++ * stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and ++ __strtold_nan to GLIBC_PRIVATE. ++ * math/test-nan-overflow.c: New file. ++ * math/test-nan-payload.c: Likewise. ++ * math/Makefile (tests): Add test-nan-overflow and ++ test-nan-payload. ++ + 2015-11-24 Joseph Myers <joseph@codesourcery.com> + + * stdlib/strtod_nan.c: New file. +Index: git/NEWS +=================================================================== +--- git.orig/NEWS ++++ git/NEWS +@@ -7,6 +7,12 @@ using `glibc' in the "product" field. + \f + Version 2.21 + ++Security related changes: ++ ++* The nan, nanf and nanl functions no longer have unbounded stack usage ++ depending on the length of the string passed as an argument to the ++ functions. Reported by Joseph Myers. ++ + * The following bugs are resolved with this release: + + 6652, 10672, 12674, 12847, 12926, 13862, 14132, 14138, 14171, 14498, +Index: git/math/s_nan.c +=================================================================== +--- git.orig/math/s_nan.c ++++ git/math/s_nan.c +@@ -28,14 +28,7 @@ + double + __nan (const char *tagp) + { +- if (tagp[0] != '\0') +- { +- char buf[6 + strlen (tagp)]; +- sprintf (buf, "NAN(%s)", tagp); +- return strtod (buf, NULL); +- } +- +- return NAN; ++ return __strtod_nan (tagp, NULL, 0); + } + weak_alias (__nan, nan) + #ifdef NO_LONG_DOUBLE +Index: git/math/s_nanf.c +=================================================================== +--- git.orig/math/s_nanf.c ++++ git/math/s_nanf.c +@@ -28,13 +28,6 @@ + float + __nanf (const char *tagp) + { +- if (tagp[0] != '\0') +- { +- char buf[6 + strlen (tagp)]; +- sprintf (buf, "NAN(%s)", tagp); +- return strtof (buf, NULL); +- } +- +- return NAN; ++ return __strtof_nan (tagp, NULL, 0); + } + weak_alias (__nanf, nanf) +Index: git/math/s_nanl.c +=================================================================== +--- git.orig/math/s_nanl.c ++++ git/math/s_nanl.c +@@ -28,13 +28,6 @@ + long double + __nanl (const char *tagp) + { +- if (tagp[0] != '\0') +- { +- char buf[6 + strlen (tagp)]; +- sprintf (buf, "NAN(%s)", tagp); +- return strtold (buf, NULL); +- } +- +- return NAN; ++ return __strtold_nan (tagp, NULL, 0); + } + weak_alias (__nanl, nanl) +Index: git/math/test-nan-overflow.c +=================================================================== +--- /dev/null ++++ git/math/test-nan-overflow.c +@@ -0,0 +1,66 @@ ++/* Test nan functions stack overflow (bug 16962). ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <math.h> ++#include <stdio.h> ++#include <string.h> ++#include <sys/resource.h> ++ ++#define STACK_LIM 1048576 ++#define STRING_SIZE (2 * STACK_LIM) ++ ++static int ++do_test (void) ++{ ++ int result = 0; ++ struct rlimit lim; ++ getrlimit (RLIMIT_STACK, &lim); ++ lim.rlim_cur = STACK_LIM; ++ setrlimit (RLIMIT_STACK, &lim); ++ char *nanstr = malloc (STRING_SIZE); ++ if (nanstr == NULL) ++ { ++ puts ("malloc failed, cannot test"); ++ return 77; ++ } ++ memset (nanstr, '0', STRING_SIZE - 1); ++ nanstr[STRING_SIZE - 1] = 0; ++#define NAN_TEST(TYPE, FUNC) \ ++ do \ ++ { \ ++ char *volatile p = nanstr; \ ++ volatile TYPE v = FUNC (p); \ ++ if (isnan (v)) \ ++ puts ("PASS: " #FUNC); \ ++ else \ ++ { \ ++ puts ("FAIL: " #FUNC); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ NAN_TEST (float, nanf); ++ NAN_TEST (double, nan); ++#ifndef NO_LONG_DOUBLE ++ NAN_TEST (long double, nanl); ++#endif ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: git/math/test-nan-payload.c +=================================================================== +--- /dev/null ++++ git/math/test-nan-payload.c +@@ -0,0 +1,122 @@ ++/* Test nan functions payload handling (bug 16961). ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <float.h> ++#include <math.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++ ++/* Avoid built-in functions. */ ++#define WRAP_NAN(FUNC, STR) \ ++ ({ const char *volatile wns = (STR); FUNC (wns); }) ++#define WRAP_STRTO(FUNC, STR) \ ++ ({ const char *volatile wss = (STR); FUNC (wss, NULL); }) ++ ++#define CHECK_IS_NAN(TYPE, A) \ ++ do \ ++ { \ ++ if (isnan (A)) \ ++ puts ("PASS: " #TYPE " " #A); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++#define CHECK_SAME_NAN(TYPE, A, B) \ ++ do \ ++ { \ ++ if (memcmp (&(A), &(B), sizeof (A)) == 0) \ ++ puts ("PASS: " #TYPE " " #A " = " #B); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A " = " #B); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++#define CHECK_DIFF_NAN(TYPE, A, B) \ ++ do \ ++ { \ ++ if (memcmp (&(A), &(B), sizeof (A)) != 0) \ ++ puts ("PASS: " #TYPE " " #A " != " #B); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A " != " #B); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++/* Cannot test payloads by memcmp for formats where NaNs have padding ++ bits. */ ++#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106) ++ ++#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \ ++ do \ ++ { \ ++ TYPE n123 = WRAP_NAN (FUNC, "123"); \ ++ CHECK_IS_NAN (TYPE, n123); \ ++ TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \ ++ CHECK_IS_NAN (TYPE, s123); \ ++ TYPE n456 = WRAP_NAN (FUNC, "456"); \ ++ CHECK_IS_NAN (TYPE, n456); \ ++ TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \ ++ CHECK_IS_NAN (TYPE, s456); \ ++ TYPE n123x = WRAP_NAN (FUNC, "123)"); \ ++ CHECK_IS_NAN (TYPE, n123x); \ ++ TYPE nemp = WRAP_NAN (FUNC, ""); \ ++ CHECK_IS_NAN (TYPE, nemp); \ ++ TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \ ++ CHECK_IS_NAN (TYPE, semp); \ ++ TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \ ++ CHECK_IS_NAN (TYPE, sx); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, n123, s123); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, n456, s456); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, nemp, semp); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, n123x, sx); \ ++ CHECK_DIFF_NAN (TYPE, n123, n456); \ ++ CHECK_DIFF_NAN (TYPE, n123, nemp); \ ++ CHECK_DIFF_NAN (TYPE, n123, n123x); \ ++ CHECK_DIFF_NAN (TYPE, n456, nemp); \ ++ CHECK_DIFF_NAN (TYPE, n456, n123x); \ ++ } \ ++ while (0) ++ ++static int ++do_test (void) ++{ ++ int result = 0; ++ RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG); ++ RUN_TESTS (double, strtod, nan, DBL_MANT_DIG); ++#ifndef NO_LONG_DOUBLE ++ RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG); ++#endif ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: git/stdlib/Versions +=================================================================== +--- git.orig/stdlib/Versions ++++ git/stdlib/Versions +@@ -118,5 +118,6 @@ libc { + # Used from other libraries + __libc_secure_getenv; + __call_tls_dtors; ++ __strtof_nan; __strtod_nan; __strtold_nan; + } + } +Index: git/math/Makefile +=================================================================== +--- git.orig/math/Makefile ++++ git/math/Makefile +@@ -92,7 +92,9 @@ tests = test-matherr test-fenv atest-exp + test-misc test-fpucw test-fpucw-ieee tst-definitions test-tgmath \ + test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \ + test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \ +- test-fenv-tls test-fenv-preserve test-fenv-return $(tests-static) ++ test-fenv-tls test-fenv-preserve test-fenv-return \ ++ test-nan-overflow test-nan-payload \ ++ $(tests-static) + tests-static = test-fpucw-static test-fpucw-ieee-static + # We do the `long double' tests only if this data type is available and + # distinct from `double'. diff --git a/meta/recipes-core/glibc/glibc_2.21.bb b/meta/recipes-core/glibc/glibc_2.21.bb index afe32d5..f712f18 100644 --- a/meta/recipes-core/glibc/glibc_2.21.bb +++ b/meta/recipes-core/glibc/glibc_2.21.bb @@ -50,6 +50,8 @@ CVEPATCHES = "\ file://CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch \ file://CVE-2015-8777.patch \ file://CVE-2015-8779.patch \ + file://CVE-2015-9761_1.patch \ + file://CVE-2015-9761_2.patch \ " LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \ -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 04/21] glibc: CVE-2015-8776 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (2 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 03/21] glibc: CVE-2015-9761 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 05/21] openssl: Security fix CVE-2015-3197 Armin Kuster ` (17 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> it was found that out-of-range time values passed to the strftime function may cause it to crash, leading to a denial of service, or potentially disclosure information. (From OE-Core rev: b9bc001ee834e4f8f756a2eaf2671aac3324b0ee) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- meta/recipes-core/glibc/glibc/CVE-2015-8776.patch | 155 ++++++++++++++++++++++ meta/recipes-core/glibc/glibc_2.21.bb | 1 + 2 files changed, 156 insertions(+) create mode 100644 meta/recipes-core/glibc/glibc/CVE-2015-8776.patch diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-8776.patch b/meta/recipes-core/glibc/glibc/CVE-2015-8776.patch new file mode 100644 index 0000000..684f344 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2015-8776.patch @@ -0,0 +1,155 @@ +From d36c75fc0d44deec29635dd239b0fbd206ca49b7 Mon Sep 17 00:00:00 2001 +From: Paul Pluzhnikov <ppluzhnikov@google.com> +Date: Sat, 26 Sep 2015 13:27:48 -0700 +Subject: [PATCH] Fix BZ #18985 -- out of range data to strftime() causes a + segfault + +Upstream-Status: Backport +CVE: CVE-2015-8776 +[Yocto # 8980] + +https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d36c75fc0d44deec29635dd239b0fbd206ca49b7 + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ChangeLog | 8 ++++++++ + NEWS | 2 +- + time/strftime_l.c | 20 +++++++++++++------- + time/tst-strftime.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 73 insertions(+), 9 deletions(-) + +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog ++++ git/ChangeLog +@@ -1,3 +1,11 @@ ++2015-09-26 Paul Pluzhnikov <ppluzhnikov@google.com> ++ ++ [BZ #18985] ++ * time/strftime_l.c (a_wkday, f_wkday, a_month, f_month): Range check. ++ (__strftime_internal): Likewise. ++ * time/tst-strftime.c (do_bz18985): New test. ++ (do_test): Call it. ++ + 2015-12-04 Joseph Myers <joseph@codesourcery.com> + + [BZ #16961] +Index: git/time/strftime_l.c +=================================================================== +--- git.orig/time/strftime_l.c ++++ git/time/strftime_l.c +@@ -514,13 +514,17 @@ __strftime_internal (s, maxsize, format, + only a few elements. Dereference the pointers only if the format + requires this. Then it is ok to fail if the pointers are invalid. */ + # define a_wkday \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) ++ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))) + # define f_wkday \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) ++ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))) + # define a_month \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))) + # define f_month \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) + # define ampm \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ + ? NLW(PM_STR) : NLW(AM_STR))) +@@ -530,8 +534,10 @@ __strftime_internal (s, maxsize, format, + # define ap_len STRLEN (ampm) + #else + # if !HAVE_STRFTIME +-# define f_wkday (weekday_name[tp->tm_wday]) +-# define f_month (month_name[tp->tm_mon]) ++# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : weekday_name[tp->tm_wday]) ++# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : month_name[tp->tm_mon]) + # define a_wkday f_wkday + # define a_month f_month + # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) +@@ -1325,7 +1331,7 @@ __strftime_internal (s, maxsize, format, + *tzset_called = true; + } + # endif +- zone = tzname[tp->tm_isdst]; ++ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?"; + } + #endif + if (! zone) +Index: git/time/tst-strftime.c +=================================================================== +--- git.orig/time/tst-strftime.c ++++ git/time/tst-strftime.c +@@ -4,6 +4,56 @@ + #include <time.h> + + ++static int ++do_bz18985 (void) ++{ ++ char buf[1000]; ++ struct tm ttm; ++ int rc, ret = 0; ++ ++ memset (&ttm, 1, sizeof (ttm)); ++ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ ++ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); ++ ++ if (rc == 66) ++ { ++ const char expected[] ++ = "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?"; ++ if (0 != strcmp (buf, expected)) ++ { ++ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); ++ ret += 1; ++ } ++ } ++ else ++ { ++ printf ("expected 66, got %d\n", rc); ++ ret += 1; ++ } ++ ++ /* Check negative values as well. */ ++ memset (&ttm, 0xFF, sizeof (ttm)); ++ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ ++ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); ++ ++ if (rc == 30) ++ { ++ const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 "; ++ if (0 != strcmp (buf, expected)) ++ { ++ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); ++ ret += 1; ++ } ++ } ++ else ++ { ++ printf ("expected 30, got %d\n", rc); ++ ret += 1; ++ } ++ ++ return ret; ++} ++ + static struct + { + const char *fmt; +@@ -104,7 +154,7 @@ do_test (void) + } + } + +- return result; ++ return result + do_bz18985 (); + } + + #define TEST_FUNCTION do_test () diff --git a/meta/recipes-core/glibc/glibc_2.21.bb b/meta/recipes-core/glibc/glibc_2.21.bb index f712f18..5cec4af 100644 --- a/meta/recipes-core/glibc/glibc_2.21.bb +++ b/meta/recipes-core/glibc/glibc_2.21.bb @@ -52,6 +52,7 @@ CVEPATCHES = "\ file://CVE-2015-8779.patch \ file://CVE-2015-9761_1.patch \ file://CVE-2015-9761_2.patch \ + file://CVE-2015-8776.patch \ " LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \ -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 05/21] openssl: Security fix CVE-2015-3197 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (3 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 04/21] glibc: CVE-2015-8776 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 06/21] openssl: Security fix CVE-2016-0701 Armin Kuster ` (16 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 CVE-2015-3197 OpenSSL: SSLv2 doesn't block disabled ciphers (From OE-Core rev: b387d9b8dff8e2c572ca14f9628ab8298347fd4f) Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../openssl/openssl/CVE-2015-3197.patch | 63 ++++++++++++++++++++++ .../recipes-connectivity/openssl/openssl_1.0.2d.bb | 1 + 2 files changed, 64 insertions(+) create mode 100644 meta/recipes-connectivity/openssl/openssl/CVE-2015-3197.patch diff --git a/meta/recipes-connectivity/openssl/openssl/CVE-2015-3197.patch b/meta/recipes-connectivity/openssl/openssl/CVE-2015-3197.patch new file mode 100644 index 0000000..dd288c9 --- /dev/null +++ b/meta/recipes-connectivity/openssl/openssl/CVE-2015-3197.patch @@ -0,0 +1,63 @@ +From d81a1600588b726c2bdccda7efad3cc7a87d6245 Mon Sep 17 00:00:00 2001 +From: Viktor Dukhovni <openssl-users@dukhovni.org> +Date: Wed, 30 Dec 2015 22:44:51 -0500 +Subject: [PATCH] Better SSLv2 cipher-suite enforcement + +Based on patch by: Nimrod Aviram <nimrod.aviram@gmail.com> + +CVE-2015-3197 + +Reviewed-by: Tim Hudson <tjh@openssl.org> +Reviewed-by: Richard Levitte <levitte@openssl.org> + +Upstream-Status: Backport +https://github.com/openssl/openssl/commit/d81a1600588b726c2bdccda7efad3cc7a87d6245 + +CVE: CVE-2015-3197 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ssl/s2_srvr.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +Index: openssl-1.0.2d/ssl/s2_srvr.c +=================================================================== +--- openssl-1.0.2d.orig/ssl/s2_srvr.c ++++ openssl-1.0.2d/ssl/s2_srvr.c +@@ -402,7 +402,7 @@ static int get_client_master_key(SSL *s) + } + + cp = ssl2_get_cipher_by_char(p); +- if (cp == NULL) { ++ if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); + return (-1); +@@ -687,8 +687,12 @@ static int get_client_hello(SSL *s) + prio = cs; + allow = cl; + } ++ ++ /* Generate list of SSLv2 ciphers shared between client and server */ + for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) { +- if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, z)) < 0) { ++ const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z); ++ if ((cp->algorithm_ssl & SSL_SSLV2) == 0 || ++ sk_SSL_CIPHER_find(allow, cp) < 0) { + (void)sk_SSL_CIPHER_delete(prio, z); + z--; + } +@@ -697,6 +701,13 @@ static int get_client_hello(SSL *s) + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = prio; + } ++ ++ /* Make sure we have at least one cipher in common */ ++ if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) { ++ ssl2_return_error(s, SSL2_PE_NO_CIPHER); ++ SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); ++ return -1; ++ } + /* + * s->session->ciphers should now have a list of ciphers that are on + * both the client and server. This list is ordered by the order the diff --git a/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb b/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb index a4e2f67..4a96a44 100644 --- a/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb +++ b/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb @@ -39,6 +39,7 @@ SRC_URI += "file://configure-targets.patch \ file://CVE-2015-3194-1-Add-PSS-parameter-check.patch \ file://0001-Add-test-for-CVE-2015-3194.patch \ file://CVE-2015-3195-Fix-leak-with-ASN.1-combine.patch \ + file://CVE-2015-3197.patch \ " SRC_URI[md5sum] = "38dd619b2e77cbac69b99f52a053d25a" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 06/21] openssl: Security fix CVE-2016-0701 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (4 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 05/21] openssl: Security fix CVE-2015-3197 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 07/21] subversion: fix CVE-2015-3184 Armin Kuster ` (15 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 CVE-2016-0701 OpenSSL: DH small subgroups (From OE-Core rev: c5868a7cd0a28c5800dfa4be1c9d98d3de08cd12) Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../openssl/openssl/CVE-2016-0701_1.patch | 102 ++++++++++++++ .../openssl/openssl/CVE-2016-0701_2.patch | 156 +++++++++++++++++++++ .../recipes-connectivity/openssl/openssl_1.0.2d.bb | 2 + 3 files changed, 260 insertions(+) create mode 100644 meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_1.patch create mode 100644 meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_2.patch diff --git a/meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_1.patch b/meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_1.patch new file mode 100644 index 0000000..cf2d9a7 --- /dev/null +++ b/meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_1.patch @@ -0,0 +1,102 @@ +From 878e2c5b13010329c203f309ed0c8f2113f85648 Mon Sep 17 00:00:00 2001 +From: Matt Caswell <matt@openssl.org> +Date: Mon, 18 Jan 2016 11:31:58 +0000 +Subject: [PATCH] Prevent small subgroup attacks on DH/DHE + +Historically OpenSSL only ever generated DH parameters based on "safe" +primes. More recently (in version 1.0.2) support was provided for +generating X9.42 style parameter files such as those required for RFC +5114 support. The primes used in such files may not be "safe". Where an +application is using DH configured with parameters based on primes that +are not "safe" then an attacker could use this fact to find a peer's +private DH exponent. This attack requires that the attacker complete +multiple handshakes in which the peer uses the same DH exponent. + +A simple mitigation is to ensure that y^q (mod p) == 1 + +CVE-2016-0701 (fix part 1 of 2) + +Issue reported by Antonio Sanso. + +Reviewed-by: Viktor Dukhovni <viktor@openssl.org> + +Upstream-Status: Backport + +https://github.com/openssl/openssl/commit/878e2c5b13010329c203f309ed0c8f2113f85648 + +CVE: CVE-2016-0701 +Signed-of-by: Armin Kuster <akuster@mvisa.com> + +--- + crypto/dh/dh.h | 1 + + crypto/dh/dh_check.c | 35 +++++++++++++++++++++++++---------- + 2 files changed, 26 insertions(+), 10 deletions(-) + +diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h +index b177673..5498a9d 100644 +--- a/crypto/dh/dh.h ++++ b/crypto/dh/dh.h +@@ -174,6 +174,7 @@ struct dh_st { + /* DH_check_pub_key error codes */ + # define DH_CHECK_PUBKEY_TOO_SMALL 0x01 + # define DH_CHECK_PUBKEY_TOO_LARGE 0x02 ++# define DH_CHECK_PUBKEY_INVALID 0x03 + + /* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for +diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c +index 347467c..5adedc0 100644 +--- a/crypto/dh/dh_check.c ++++ b/crypto/dh/dh_check.c +@@ -151,23 +151,38 @@ int DH_check(const DH *dh, int *ret) + int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) + { + int ok = 0; +- BIGNUM *q = NULL; ++ BIGNUM *tmp = NULL; ++ BN_CTX *ctx = NULL; + + *ret = 0; +- q = BN_new(); +- if (q == NULL) ++ ctx = BN_CTX_new(); ++ if (ctx == NULL) + goto err; +- BN_set_word(q, 1); +- if (BN_cmp(pub_key, q) <= 0) ++ BN_CTX_start(ctx); ++ tmp = BN_CTX_get(ctx); ++ if (tmp == NULL) ++ goto err; ++ BN_set_word(tmp, 1); ++ if (BN_cmp(pub_key, tmp) <= 0) + *ret |= DH_CHECK_PUBKEY_TOO_SMALL; +- BN_copy(q, dh->p); +- BN_sub_word(q, 1); +- if (BN_cmp(pub_key, q) >= 0) ++ BN_copy(tmp, dh->p); ++ BN_sub_word(tmp, 1); ++ if (BN_cmp(pub_key, tmp) >= 0) + *ret |= DH_CHECK_PUBKEY_TOO_LARGE; + ++ if (dh->q != NULL) { ++ /* Check pub_key^q == 1 mod p */ ++ if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) ++ goto err; ++ if (!BN_is_one(tmp)) ++ *ret |= DH_CHECK_PUBKEY_INVALID; ++ } ++ + ok = 1; + err: +- if (q != NULL) +- BN_free(q); ++ if (ctx != NULL) { ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ } + return (ok); + } +-- +2.3.5 + diff --git a/meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_2.patch b/meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_2.patch new file mode 100644 index 0000000..05caf0a --- /dev/null +++ b/meta/recipes-connectivity/openssl/openssl/CVE-2016-0701_2.patch @@ -0,0 +1,156 @@ +From c5b831f21d0d29d1e517d139d9d101763f60c9a2 Mon Sep 17 00:00:00 2001 +From: Matt Caswell <matt@openssl.org> +Date: Thu, 17 Dec 2015 02:57:20 +0000 +Subject: [PATCH] Always generate DH keys for ephemeral DH cipher suites + +Modified version of the commit ffaef3f15 in the master branch by Stephen +Henson. This makes the SSL_OP_SINGLE_DH_USE option a no-op and always +generates a new DH key for every handshake regardless. + +CVE-2016-0701 (fix part 2 or 2) + +Issue reported by Antonio Sanso + +Reviewed-by: Viktor Dukhovni <viktor@openssl.org> + +Upstream-Status: Backport + +https://github.com/openssl/openssl/commit/c5b831f21d0d29d1e517d139d9d101763f60c9a2 + +CVE: CVE-2016-0701 #2 +Signed-of-by: Armin Kuster <akuster@mvisa.com> + +--- + doc/ssl/SSL_CTX_set_tmp_dh_callback.pod | 29 +++++------------------------ + ssl/s3_lib.c | 14 -------------- + ssl/s3_srvr.c | 17 +++-------------- + ssl/ssl.h | 2 +- + 4 files changed, 9 insertions(+), 53 deletions(-) + +Index: openssl-1.0.2d/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod +=================================================================== +--- openssl-1.0.2d.orig/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod ++++ openssl-1.0.2d/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod +@@ -48,25 +48,8 @@ even if he gets hold of the normal (cert + only used for signing. + + In order to perform a DH key exchange the server must use a DH group +-(DH parameters) and generate a DH key. +-The server will always generate a new DH key during the negotiation +-if either the DH parameters are supplied via callback or the +-SSL_OP_SINGLE_DH_USE option of SSL_CTX_set_options(3) is set (or both). +-It will immediately create a DH key if DH parameters are supplied via +-SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. +-In this case, +-it may happen that a key is generated on initialization without later +-being needed, while on the other hand the computer time during the +-negotiation is being saved. +- +-If "strong" primes were used to generate the DH parameters, it is not strictly +-necessary to generate a new key for each handshake but it does improve forward +-secrecy. If it is not assured that "strong" primes were used, +-SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup +-attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the +-computer time needed during negotiation, but it is not very large, so +-application authors/users should consider always enabling this option. +-The option is required to implement perfect forward secrecy (PFS). ++(DH parameters) and generate a DH key. The server will always generate ++a new DH key during the negotiation. + + As generating DH parameters is extremely time consuming, an application + should not generate the parameters on the fly but supply the parameters. +@@ -93,10 +76,9 @@ can supply the DH parameters via a callb + Previous versions of the callback used B<is_export> and B<keylength> + parameters to control parameter generation for export and non-export + cipher suites. Modern servers that do not support export ciphersuites +-are advised to either use SSL_CTX_set_tmp_dh() in combination with +-SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore +-B<keylength> and B<is_export> and simply supply at least 2048-bit +-parameters in the callback. ++are advised to either use SSL_CTX_set_tmp_dh() or alternatively, use ++the callback but ignore B<keylength> and B<is_export> and simply ++supply at least 2048-bit parameters in the callback. + + =head1 EXAMPLES + +@@ -128,7 +110,6 @@ partly left out.) + if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) { + /* Error. */ + } +- SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); + ... + + =head1 RETURN VALUES +Index: openssl-1.0.2d/ssl/s3_lib.c +=================================================================== +--- openssl-1.0.2d.orig/ssl/s3_lib.c ++++ openssl-1.0.2d/ssl/s3_lib.c +@@ -3206,13 +3206,6 @@ long ssl3_ctrl(SSL *s, int cmd, long lar + SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB); + return (ret); + } +- if (!(s->options & SSL_OP_SINGLE_DH_USE)) { +- if (!DH_generate_key(dh)) { +- DH_free(dh); +- SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB); +- return (ret); +- } +- } + if (s->cert->dh_tmp != NULL) + DH_free(s->cert->dh_tmp); + s->cert->dh_tmp = dh; +@@ -3710,13 +3703,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB); + return 0; + } +- if (!(ctx->options & SSL_OP_SINGLE_DH_USE)) { +- if (!DH_generate_key(new)) { +- SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB); +- DH_free(new); +- return 0; +- } +- } + if (cert->dh_tmp != NULL) + DH_free(cert->dh_tmp); + cert->dh_tmp = new; +Index: openssl-1.0.2d/ssl/s3_srvr.c +=================================================================== +--- openssl-1.0.2d.orig/ssl/s3_srvr.c ++++ openssl-1.0.2d/ssl/s3_srvr.c +@@ -1684,20 +1684,9 @@ int ssl3_send_server_key_exchange(SSL *s + } + + s->s3->tmp.dh = dh; +- if ((dhp->pub_key == NULL || +- dhp->priv_key == NULL || +- (s->options & SSL_OP_SINGLE_DH_USE))) { +- if (!DH_generate_key(dh)) { +- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); +- goto err; +- } +- } else { +- dh->pub_key = BN_dup(dhp->pub_key); +- dh->priv_key = BN_dup(dhp->priv_key); +- if ((dh->pub_key == NULL) || (dh->priv_key == NULL)) { +- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); +- goto err; +- } ++ if (!DH_generate_key(dh)) { ++ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); ++ goto err; + } + r[0] = dh->p; + r[1] = dh->g; +Index: openssl-1.0.2d/ssl/ssl.h +=================================================================== +--- openssl-1.0.2d.orig/ssl/ssl.h ++++ openssl-1.0.2d/ssl/ssl.h +@@ -625,7 +625,7 @@ struct ssl_session_st { + # define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L + /* If set, always create a new key when using tmp_ecdh parameters */ + # define SSL_OP_SINGLE_ECDH_USE 0x00080000L +-/* If set, always create a new key when using tmp_dh parameters */ ++/* Does nothing: retained for compatibility */ + # define SSL_OP_SINGLE_DH_USE 0x00100000L + /* Does nothing: retained for compatibiity */ + # define SSL_OP_EPHEMERAL_RSA 0x0 diff --git a/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb b/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb index 4a96a44..726896b 100644 --- a/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb +++ b/meta/recipes-connectivity/openssl/openssl_1.0.2d.bb @@ -40,6 +40,8 @@ SRC_URI += "file://configure-targets.patch \ file://0001-Add-test-for-CVE-2015-3194.patch \ file://CVE-2015-3195-Fix-leak-with-ASN.1-combine.patch \ file://CVE-2015-3197.patch \ + file://CVE-2016-0701_1.patch \ + file://CVE-2016-0701_2.patch \ " SRC_URI[md5sum] = "38dd619b2e77cbac69b99f52a053d25a" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 07/21] subversion: fix CVE-2015-3184 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (5 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 06/21] openssl: Security fix CVE-2016-0701 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 08/21] subversion: fix CVE-2015-3187 Armin Kuster ` (14 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Wenzong Fan <wenzong.fan@windriver.com> mod_authz_svn in Apache Subversion 1.7.x before 1.7.21 and 1.8.x before 1.8.14, when using Apache httpd 2.4.x, does not properly restrict anonymous access, which allows remote anonymous users to read hidden files via the path name. Patch is from: http://subversion.apache.org/security/CVE-2015-3184-advisory.txt (From OE-Core master rev: 29eb921ed074d86fa8d5b205a313eb3177473a63) (From OE-Core rev: 7af7a3e692a6cd0d92768024efe32bfa7d83bc8f) Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../subversion-CVE-2015-3184.patch | 2082 ++++++++++++++++++++ .../subversion/subversion_1.8.11.bb | 1 + 2 files changed, 2083 insertions(+) create mode 100644 meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3184.patch diff --git a/meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3184.patch b/meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3184.patch new file mode 100644 index 0000000..2daa7c7 --- /dev/null +++ b/meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3184.patch @@ -0,0 +1,2082 @@ +Fix CVE-2015-3184 + +Patch is from: +http://subversion.apache.org/security/CVE-2015-3184-advisory.txt + +Upstream-Status: Backport + +Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com> + +Index: subversion-1.8.11/Makefile.in +=================================================================== +--- subversion-1.8.11.orig/Makefile.in ++++ subversion-1.8.11/Makefile.in +@@ -357,6 +357,7 @@ TEST_SHLIB_VAR_SWIG_RB=\ + fi; + + APXS = @APXS@ ++HTTPD_VERSION = @HTTPD_VERSION@ + + PYTHON = @PYTHON@ + PERL = @PERL@ +@@ -509,6 +510,9 @@ check: bin @TRANSFORM_LIBTOOL_SCRIPTS@ $ + if test "$(HTTP_LIBRARY)" != ""; then \ + flags="--http-library $(HTTP_LIBRARY) $$flags"; \ + fi; \ ++ if test "$(HTTPD_VERSION)" != ""; then \ ++ flags="--httpd-version $(HTTPD_VERSION) $$flags"; \ ++ fi; \ + if test "$(SERVER_MINOR_VERSION)" != ""; then \ + flags="--server-minor-version $(SERVER_MINOR_VERSION) $$flags"; \ + fi; \ +Index: subversion-1.8.11/build/ac-macros/apache.m4 +=================================================================== +--- subversion-1.8.11.orig/build/ac-macros/apache.m4 ++++ subversion-1.8.11/build/ac-macros/apache.m4 +@@ -160,6 +160,20 @@ if test -n "$APXS" && test "$APXS" != "n + BUILD_APACHE_RULE=apache-mod + INSTALL_APACHE_RULE=install-mods-shared + INSTALL_APACHE_MODS=true ++ HTTPD="`$APXS -q sbindir`/`$APXS -q PROGNAME`" ++ if ! test -e $HTTPD ; then ++ HTTPD="`$APXS -q bindir`/`$APXS -q PROGNAME`" ++ fi ++ HTTPD_VERSION=["`$HTTPD -v | $SED -e 's@^.*/\([0-9.]*\)\(.*$\)@\1@ ; 1q'`"] ++ AC_ARG_ENABLE(broken-httpd-auth, ++ AS_HELP_STRING([--enable-broken-httpd-auth], ++ [Allow building against httpd 2.4 with broken auth]), ++ [broken_httpd_auth=$enableval],[broken_httpd_auth=no]) ++ if test "$enable_broken_httpd_auth" = "yes"; then ++ AC_MSG_NOTICE([Building with broken httpd auth]) ++ AC_DEFINE(SVN_ALLOW_BROKEN_HTTPD_AUTH, 1, ++ [Defined to allow building against httpd 2.4 with broken auth]) ++ fi + + case $host in + *-*-cygwin*) +@@ -178,6 +192,7 @@ AC_SUBST(APACHE_LDFLAGS) + AC_SUBST(APACHE_INCLUDES) + AC_SUBST(APACHE_LIBEXECDIR) + AC_SUBST(INSTALL_APACHE_MODS) ++AC_SUBST(HTTPD_VERSION) + + # there aren't any flags that interest us ... + #if test -n "$APXS" && test "$APXS" != "no"; then +Index: subversion-1.8.11/build/run_tests.py +=================================================================== +--- subversion-1.8.11.orig/build/run_tests.py ++++ subversion-1.8.11/build/run_tests.py +@@ -29,6 +29,7 @@ + [--fs-type=<fs-type>] [--fsfs-packing] [--fsfs-sharding=<n>] + [--list] [--milestone-filter=<regex>] [--mode-filter=<type>] + [--server-minor-version=<version>] [--http-proxy=<host>:<port>] ++ [--httpd-version=<version>] + [--config-file=<file>] [--ssl-cert=<file>] + <abs_srcdir> <abs_builddir> + <prog ...> +@@ -125,7 +126,7 @@ class TestHarness: + fsfs_sharding=None, fsfs_packing=None, + list_tests=None, svn_bin=None, mode_filter=None, + milestone_filter=None, set_log_level=None, ssl_cert=None, +- http_proxy=None): ++ http_proxy=None, httpd_version=None): + '''Construct a TestHarness instance. + + ABS_SRCDIR and ABS_BUILDDIR are the source and build directories. +@@ -178,6 +179,7 @@ class TestHarness: + self.log = None + self.ssl_cert = ssl_cert + self.http_proxy = http_proxy ++ self.httpd_version = httpd_version + if not sys.stdout.isatty() or sys.platform == 'win32': + TextColors.disable() + +@@ -481,6 +483,8 @@ class TestHarness: + svntest.main.options.ssl_cert = self.ssl_cert + if self.http_proxy is not None: + svntest.main.options.http_proxy = self.http_proxy ++ if self.httpd_version is not None: ++ svntest.main.options.httpd_version = self.httpd_version + + svntest.main.options.srcdir = self.srcdir + +@@ -645,7 +649,7 @@ def main(): + 'enable-sasl', 'parallel', 'config-file=', + 'log-to-stdout', 'list', 'milestone-filter=', + 'mode-filter=', 'set-log-level=', 'ssl-cert=', +- 'http-proxy=']) ++ 'http-proxy=', 'httpd-version=']) + except getopt.GetoptError: + args = [] + +@@ -656,9 +660,9 @@ def main(): + base_url, fs_type, verbose, cleanup, enable_sasl, http_library, \ + server_minor_version, fsfs_sharding, fsfs_packing, parallel, \ + config_file, log_to_stdout, list_tests, mode_filter, milestone_filter, \ +- set_log_level, ssl_cert, http_proxy = \ ++ set_log_level, ssl_cert, http_proxy, httpd_version = \ + None, None, None, None, None, None, None, None, None, None, None, \ +- None, None, None, None, None, None, None ++ None, None, None, None, None, None, None, None + for opt, val in opts: + if opt in ['-u', '--url']: + base_url = val +@@ -696,6 +700,8 @@ def main(): + ssl_cert = val + elif opt in ['--http-proxy']: + http_proxy = val ++ elif opt in ['--httpd-version']: ++ httpd_version = val + else: + raise getopt.GetoptError + +@@ -712,7 +718,7 @@ def main(): + fsfs_sharding, fsfs_packing, list_tests, + mode_filter=mode_filter, milestone_filter=milestone_filter, + set_log_level=set_log_level, ssl_cert=ssl_cert, +- http_proxy=http_proxy) ++ http_proxy=http_proxy, httpd_version=httpd_version) + + failed = th.run(args[2:]) + if failed: +Index: subversion-1.8.11/subversion/mod_authz_svn/mod_authz_svn.c +=================================================================== +--- subversion-1.8.11.orig/subversion/mod_authz_svn/mod_authz_svn.c ++++ subversion-1.8.11/subversion/mod_authz_svn/mod_authz_svn.c +@@ -48,6 +48,23 @@ + #include "svn_dirent_uri.h" + #include "private/svn_fspath.h" + ++/* The apache headers define these and they conflict with our definitions. */ ++#ifdef PACKAGE_BUGREPORT ++#undef PACKAGE_BUGREPORT ++#endif ++#ifdef PACKAGE_NAME ++#undef PACKAGE_NAME ++#endif ++#ifdef PACKAGE_STRING ++#undef PACKAGE_STRING ++#endif ++#ifdef PACKAGE_TARNAME ++#undef PACKAGE_TARNAME ++#endif ++#ifdef PACKAGE_VERSION ++#undef PACKAGE_VERSION ++#endif ++#include "svn_private_config.h" + + #ifdef APLOG_USE_MODULE + APLOG_USE_MODULE(authz_svn); +@@ -67,6 +84,30 @@ typedef struct authz_svn_config_rec { + const char *force_username_case; + } authz_svn_config_rec; + ++#if AP_MODULE_MAGIC_AT_LEAST(20060110,0) /* version where ++ ap_some_auth_required breaks */ ++# if AP_MODULE_MAGIC_AT_LEAST(20120211,47) /* first version with ++ force_authn hook and ++ ap_some_authn_required() which ++ allows us to work without ++ ap_some_auth_required() */ ++# define USE_FORCE_AUTHN 1 ++# define IN_SOME_AUTHN_NOTE "authz_svn-in-some-authn" ++# define FORCE_AUTHN_NOTE "authz_svn-force-authn" ++# else ++ /* ap_some_auth_required() is busted and no viable alternative exists */ ++# ifndef SVN_ALLOW_BROKEN_HTTPD_AUTH ++# error This version of httpd has a security hole with mod_authz_svn ++# else ++ /* user wants to build anyway */ ++# define USE_FORCE_AUTHN 0 ++# endif ++# endif ++#else ++ /* old enough that ap_some_auth_required() still works */ ++# define USE_FORCE_AUTHN 0 ++#endif ++ + /* + * Configuration + */ +@@ -819,7 +860,49 @@ access_checker(request_rec *r) + &authz_svn_module); + const char *repos_path = NULL; + const char *dest_repos_path = NULL; +- int status; ++ int status, authn_required; ++ ++#if USE_FORCE_AUTHN ++ /* Use the force_authn() hook available in 2.4.x to work securely ++ * given that ap_some_auth_required() is no longer functional for our ++ * purposes in 2.4.x. ++ */ ++ int authn_configured; ++ ++ /* We are not configured to run */ ++ if (!conf->anonymous || apr_table_get(r->notes, IN_SOME_AUTHN_NOTE) ++ || (! (conf->access_file || conf->repo_relative_access_file))) ++ return DECLINED; ++ ++ /* Authentication is configured */ ++ authn_configured = ap_auth_type(r) != NULL; ++ if (authn_configured) ++ { ++ /* If the user is trying to authenticate, let him. It doesn't ++ * make much sense to grant anonymous access but deny authenticated ++ * users access, even though you can do that with '$anon' in the ++ * access file. ++ */ ++ if (apr_table_get(r->headers_in, ++ (PROXYREQ_PROXY == r->proxyreq) ++ ? "Proxy-Authorization" : "Authorization")) ++ { ++ /* Set the note to force authn regardless of what access_checker_ex ++ hook requires */ ++ apr_table_setn(r->notes, FORCE_AUTHN_NOTE, (const char*)1); ++ ++ /* provide the proper return so the access_checker hook doesn't ++ * prevent the code from continuing on to the other auth hooks */ ++ if (ap_satisfies(r) != SATISFY_ANY) ++ return OK; ++ else ++ return HTTP_FORBIDDEN; ++ } ++ } ++ ++#else ++ /* Support for older versions of httpd that have a working ++ * ap_some_auth_required() */ + + /* We are not configured to run */ + if (!conf->anonymous +@@ -834,9 +917,10 @@ access_checker(request_rec *r) + if (ap_satisfies(r) != SATISFY_ANY) + return DECLINED; + +- /* If the user is trying to authenticate, let him. If anonymous +- * access is allowed, so is authenticated access, by definition +- * of the meaning of '*' in the access file. ++ /* If the user is trying to authenticate, let him. It doesn't ++ * make much sense to grant anonymous access but deny authenticated ++ * users access, even though you can do that with '$anon' in the ++ * access file. + */ + if (apr_table_get(r->headers_in, + (PROXYREQ_PROXY == r->proxyreq) +@@ -848,6 +932,7 @@ access_checker(request_rec *r) + return HTTP_FORBIDDEN; + } + } ++#endif + + /* If anon access is allowed, return OK */ + status = req_check_access(r, conf, &repos_path, &dest_repos_path); +@@ -856,7 +941,26 @@ access_checker(request_rec *r) + if (!conf->authoritative) + return DECLINED; + ++#if USE_FORCE_AUTHN ++ if (authn_configured) { ++ /* We have to check to see if authn is required because if so we must ++ * return UNAUTHORIZED (401) rather than FORBIDDEN (403) since returning ++ * the 403 leaks information about what paths may exist to ++ * unauthenticated users. We must set a note here in order ++ * to use ap_some_authn_rquired() without triggering an infinite ++ * loop since the call will trigger this function to be called again. */ ++ apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, (const char*)1); ++ authn_required = ap_some_authn_required(r); ++ apr_table_unset(r->notes, IN_SOME_AUTHN_NOTE); ++ if (authn_required) ++ { ++ ap_note_auth_failure(r); ++ return HTTP_UNAUTHORIZED; ++ } ++ } ++#else + if (!ap_some_auth_required(r)) ++#endif + log_access_verdict(APLOG_MARK, r, 0, repos_path, dest_repos_path); + + return HTTP_FORBIDDEN; +@@ -937,6 +1041,17 @@ auth_checker(request_rec *r) + return OK; + } + ++#if USE_FORCE_AUTHN ++static int ++force_authn(request_rec *r) ++{ ++ if (apr_table_get(r->notes, FORCE_AUTHN_NOTE)) ++ return OK; ++ ++ return DECLINED; ++} ++#endif ++ + /* + * Module flesh + */ +@@ -953,6 +1068,9 @@ register_hooks(apr_pool_t *p) + * give SSLOptions +FakeBasicAuth a chance to work. */ + ap_hook_check_user_id(check_user_id, mod_ssl, NULL, APR_HOOK_FIRST); + ap_hook_auth_checker(auth_checker, NULL, NULL, APR_HOOK_FIRST); ++#if USE_FORCE_AUTHN ++ ap_hook_force_authn(force_authn, NULL, NULL, APR_HOOK_FIRST); ++#endif + ap_register_provider(p, + AUTHZ_SVN__SUBREQ_BYPASS_PROV_GRP, + AUTHZ_SVN__SUBREQ_BYPASS_PROV_NAME, +Index: subversion-1.8.11/subversion/tests/cmdline/README +=================================================================== +--- subversion-1.8.11.orig/subversion/tests/cmdline/README ++++ subversion-1.8.11/subversion/tests/cmdline/README +@@ -83,6 +83,133 @@ paths adjusted appropriately: + Require valid-user + </Location> + ++ <Location /authz-test-work/anon> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ # This may seem unnecessary but granting access to everyone here is necessary ++ # to exercise a bug with httpd 2.3.x+. The "Require all granted" syntax is ++ # new to 2.3.x+ which we can detect with the mod_authz_core.c module ++ # signature. Use the "Allow from all" syntax with older versions for symmetry. ++ <IfModule mod_authz_core.c> ++ Require all granted ++ </IfModule> ++ <IfModule !mod_authz_core.c> ++ Allow from all ++ </IfMOdule> ++ </Location> ++ <Location /authz-test-work/mixed> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ Require valid-user ++ Satisfy Any ++ </Location> ++ <Location /authz-test-work/mixed-noauthwhenanon> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ Require valid-user ++ AuthzSVNNoAuthWhenAnonymousAllowed On ++ </Location> ++ <Location /authz-test-work/authn> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ Require valid-user ++ </Location> ++ <Location /authz-test-work/authn-anonoff> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ Require valid-user ++ AuthzSVNAnonymous Off ++ </Location> ++ <Location /authz-test-work/authn-lcuser> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ Require valid-user ++ AuthzForceUsernameCase Lower ++ </Location> ++ <Location /authz-test-work/authn-lcuser> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ Require valid-user ++ AuthzForceUsernameCase Lower ++ </Location> ++ <Location /authz-test-work/authn-group> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ AuthGroupFile /usr/local/apache2/conf/groups ++ Require group random ++ AuthzSVNAuthoritative Off ++ </Location> ++ <IfModule mod_authz_core.c> ++ <Location /authz-test-work/sallrany> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ AuthzSendForbiddenOnFailure On ++ Satisfy All ++ <RequireAny> ++ Require valid-user ++ Require expr req('ALLOW') == '1' ++ </RequireAny> ++ </Location> ++ <Location /authz-test-work/sallrall> ++ DAV svn ++ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp ++ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile /usr/local/apache2/conf/users ++ AuthzSendForbiddenOnFailure On ++ Satisfy All ++ <RequireAll> ++ Require valid-user ++ Require expr req('ALLOW') == '1' ++ </RequireAll> ++ </Location> ++ </IfModule> ++ ++ + RedirectMatch permanent ^/svn-test-work/repositories/REDIRECT-PERM-(.*)$ /svn-test-work/repositories/$1 + RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)$ /svn-test-work/repositories/$1 + +@@ -101,6 +228,15 @@ just drop the following 2-line snippet i + ---------------------------- + jrandom:xCGl35kV9oWCY + jconstant:xCGl35kV9oWCY ++JRANDOM:xCGl35kV9oWCY ++JCONSTANT:xCGl35kV9oWCY ++---------------------------- ++ ++and these lines into the ++/usr/local/apache/conf/groups file: ++---------------------------- ++random: jrandom ++constant: jconstant + ---------------------------- + + Now, (re)start Apache and run the tests over mod_dav_svn. +@@ -138,6 +274,8 @@ Note [1]: It would be quite too much to + ---------------------------- + jrandom:$apr1$3p1.....$FQW6RceW5QhJ2blWDQgKn0 + jconstant:$apr1$jp1.....$Usrqji1c9H6AbOxOGAzzb0 ++ JRANDOM:$apr1$3p1.....$FQW6RceW5QhJ2blWDQgKn0 ++ JCONSTANT:$apr1$jp1.....$Usrqji1c9H6AbOxOGAzzb0 + ---------------------------- + + +Index: subversion-1.8.11/subversion/tests/cmdline/davautocheck.sh +=================================================================== +--- subversion-1.8.11.orig/subversion/tests/cmdline/davautocheck.sh ++++ subversion-1.8.11/subversion/tests/cmdline/davautocheck.sh +@@ -289,8 +289,6 @@ LOAD_MOD_AUTHN_CORE="$(get_loadmodule_co + || fail "Authn_Core module not found." + LOAD_MOD_AUTHZ_CORE="$(get_loadmodule_config mod_authz_core)" \ + || fail "Authz_Core module not found." +-LOAD_MOD_AUTHZ_HOST="$(get_loadmodule_config mod_authz_host)" \ +- || fail "Authz_Host module not found." + LOAD_MOD_UNIXD=$(get_loadmodule_config mod_unixd) \ + || fail "UnixD module not found" + } +@@ -298,6 +296,10 @@ LOAD_MOD_AUTHN_FILE="$(get_loadmodule_co + || fail "Authn_File module not found." + LOAD_MOD_AUTHZ_USER="$(get_loadmodule_config mod_authz_user)" \ + || fail "Authz_User module not found." ++LOAD_MOD_AUTHZ_GROUPFILE="$(get_loadmodule_config mod_authz_groupfile)" \ ++ || fail "Authz_GroupFile module not found." ++LOAD_MOD_AUTHZ_HOST="$(get_loadmodule_config mod_authz_host)" \ ++ || fail "Authz_Host module not found." + } + if [ ${APACHE_MPM:+set} ]; then + LOAD_MOD_MPM=$(get_loadmodule_config mod_mpm_$APACHE_MPM) \ +@@ -328,6 +330,7 @@ HTTPD_ERROR_LOG="$HTTPD_ROOT/error_log" + HTTPD_MIME_TYPES="$HTTPD_ROOT/mime.types" + BASE_URL="http://localhost:$HTTPD_PORT" + HTTPD_USERS="$HTTPD_ROOT/users" ++HTTPD_GROUPS="$HTTPD_ROOT/groups" + + mkdir "$HTTPD_ROOT" \ + || fail "couldn't create temporary directory '$HTTPD_ROOT'" +@@ -388,6 +391,14 @@ fi + say "Adding users for lock authentication" + $HTPASSWD -bc $HTTPD_USERS jrandom rayjandom + $HTPASSWD -b $HTTPD_USERS jconstant rayjandom ++$HTPASSWD -b $HTTPD_USERS JRANDOM rayjandom ++$HTPASSWD -b $HTTPD_USERS JCONSTANT rayjandom ++ ++say "Adding groups for mod_authz_svn tests" ++cat > "$HTTPD_GROUPS" <<__EOF__ ++random: jrandom ++constant: jconstant ++__EOF__ + + touch $HTTPD_MIME_TYPES + +@@ -405,7 +416,9 @@ $LOAD_MOD_AUTHN_CORE + $LOAD_MOD_AUTHN_FILE + $LOAD_MOD_AUTHZ_CORE + $LOAD_MOD_AUTHZ_USER ++$LOAD_MOD_AUTHZ_GROUPFILE + $LOAD_MOD_AUTHZ_HOST ++$LOAD_MOD_ACCESS_COMPAT + LoadModule authz_svn_module "$MOD_AUTHZ_SVN" + + __EOF__ +@@ -489,6 +502,161 @@ CustomLog "$HTTPD_ROOT/ops" "% + SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} + ${SVN_PATH_AUTHZ_LINE} + </Location> ++<Location /authz-test-work/anon> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ # This may seem unnecessary but granting access to everyone here is necessary ++ # to exercise a bug with httpd 2.3.x+. The "Require all granted" syntax is ++ # new to 2.3.x+ which we can detect with the mod_authz_core.c module ++ # signature. Use the "Allow from all" syntax with older versions for symmetry. ++ <IfModule mod_authz_core.c> ++ Require all granted ++ </IfModule> ++ <IfModule !mod_authz_core.c> ++ Allow from all ++ </IfMOdule> ++ ${SVN_PATH_AUTHZ_LINE} ++</Location> ++<Location /authz-test-work/mixed> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ Require valid-user ++ Satisfy Any ++ ${SVN_PATH_AUTHZ_LINE} ++</Location> ++<Location /authz-test-work/mixed-noauthwhenanon> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ Require valid-user ++ AuthzSVNNoAuthWhenAnonymousAllowed On ++ SVNPathAuthz On ++</Location> ++<Location /authz-test-work/authn> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ Require valid-user ++ ${SVN_PATH_AUTHZ_LINE} ++</Location> ++<Location /authz-test-work/authn-anonoff> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ Require valid-user ++ AuthzSVNAnonymous Off ++ SVNPathAuthz On ++</Location> ++<Location /authz-test-work/authn-lcuser> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ Require valid-user ++ AuthzForceUsernameCase Lower ++ ${SVN_PATH_AUTHZ_LINE} ++</Location> ++<Location /authz-test-work/authn-lcuser> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ Require valid-user ++ AuthzForceUsernameCase Lower ++ ${SVN_PATH_AUTHZ_LINE} ++</Location> ++<Location /authz-test-work/authn-group> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ AuthGroupFile $HTTPD_GROUPS ++ Require group random ++ AuthzSVNAuthoritative Off ++ SVNPathAuthz On ++</Location> ++<IfModule mod_authz_core.c> ++ <Location /authz-test-work/sallrany> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ AuthzSendForbiddenOnFailure On ++ Satisfy All ++ <RequireAny> ++ Require valid-user ++ Require expr req('ALLOW') == '1' ++ </RequireAny> ++ ${SVN_PATH_AUTHZ_LINE} ++ </Location> ++ <Location /authz-test-work/sallrall> ++ DAV svn ++ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp" ++ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz" ++ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL} ++ SVNCacheRevProps ${CACHE_REVPROPS_SETTING} ++ SVNListParentPath On ++ AuthType Basic ++ AuthName "Subversion Repository" ++ AuthUserFile $HTTPD_USERS ++ AuthzSendForbiddenOnFailure On ++ Satisfy All ++ <RequireAll> ++ Require valid-user ++ Require expr req('ALLOW') == '1' ++ </RequireAll> ++ ${SVN_PATH_AUTHZ_LINE} ++ </Location> ++</IfModule> + RedirectMatch permanent ^/svn-test-work/repositories/REDIRECT-PERM-(.*)\$ /svn-test-work/repositories/\$1 + RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)\$ /svn-test-work/repositories/\$1 + __EOF__ +Index: subversion-1.8.11/subversion/tests/cmdline/mod_authz_svn_tests.py +=================================================================== +--- /dev/null ++++ subversion-1.8.11/subversion/tests/cmdline/mod_authz_svn_tests.py +@@ -0,0 +1,1073 @@ ++#!/usr/bin/env python ++# ++# mod_authz_svn_tests.py: testing mod_authz_svn ++# ++# Subversion is a tool for revision control. ++# See http://subversion.apache.org for more information. ++# ++# ==================================================================== ++# Licensed to the Apache Software Foundation (ASF) under one ++# or more contributor license agreements. See the NOTICE file ++# distributed with this work for additional information ++# regarding copyright ownership. The ASF licenses this file ++# to you under the Apache License, Version 2.0 (the ++# "License"); you may not use this file except in compliance ++# with the License. You may obtain a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, ++# software distributed under the License is distributed on an ++# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++# KIND, either express or implied. See the License for the ++# specific language governing permissions and limitations ++# under the License. ++###################################################################### ++ ++# General modules ++import os, re, logging ++ ++logger = logging.getLogger() ++ ++# Our testing module ++import svntest ++ ++# (abbreviation) ++Skip = svntest.testcase.Skip_deco ++SkipUnless = svntest.testcase.SkipUnless_deco ++XFail = svntest.testcase.XFail_deco ++Issues = svntest.testcase.Issues_deco ++Issue = svntest.testcase.Issue_deco ++Wimp = svntest.testcase.Wimp_deco ++ ++ls_of_D_no_H = '''<html><head><title>repos - Revision 1: /A/D</title></head> ++<body> ++ <h2>repos - Revision 1: /A/D</h2> ++ <ul> ++ <li><a href="../">..</a></li> ++ <li><a href="G/">G/</a></li> ++ <li><a href="gamma">gamma</a></li> ++ </ul> ++</body></html>''' ++ ++ls_of_D_H = '''<html><head><title>repos - Revision 1: /A/D</title></head> ++<body> ++ <h2>repos - Revision 1: /A/D</h2> ++ <ul> ++ <li><a href="../">..</a></li> ++ <li><a href="G/">G/</a></li> ++ <li><a href="H/">H/</a></li> ++ <li><a href="gamma">gamma</a></li> ++ </ul> ++</body></html>''' ++ ++ls_of_H = '''<html><head><title>repos - Revision 1: /A/D/H</title></head> ++<body> ++ <h2>repos - Revision 1: /A/D/H</h2> ++ <ul> ++ <li><a href="../">..</a></li> ++ <li><a href="chi">chi</a></li> ++ <li><a href="omega">omega</a></li> ++ <li><a href="psi">psi</a></li> ++ </ul> ++</body></html>''' ++ ++user1 = svntest.main.wc_author ++user1_upper = user1.upper() ++user1_pass = svntest.main.wc_passwd ++user1_badpass = 'XXX' ++assert user1_pass != user1_badpass, "Passwords can't match" ++user2 = svntest.main.wc_author2 ++user2_upper = user2.upper() ++user2_pass = svntest.main.wc_passwd ++user2_badpass = 'XXX' ++assert user2_pass != user2_badpass, "Passwords can't match" ++ ++def write_authz_file(sbox): ++ svntest.main.write_authz_file(sbox, { ++ '/': '$anonymous = r\n' + ++ 'jrandom = rw\n' + ++ 'jconstant = rw', ++ '/A/D/H': '$anonymous =\n' + ++ '$authenticated =\n' + ++ 'jrandom = rw' ++ }) ++ ++def write_authz_file_groups(sbox): ++ authz_name = sbox.authz_name() ++ svntest.main.write_authz_file(sbox,{ ++ '/': '* =', ++ }) ++ ++def verify_get(test_area_url, path, user, pw, ++ expected_status, expected_body, headers): ++ import httplib ++ from urlparse import urlparse ++ import base64 ++ ++ req_url = test_area_url + path ++ ++ loc = urlparse(req_url) ++ ++ if loc.scheme == 'http': ++ h = httplib.HTTPConnection(loc.hostname, loc.port) ++ else: ++ h = httplib.HTTPSConnection(loc.hostname, loc.port) ++ ++ if headers is None: ++ headers = {} ++ ++ if user and pw: ++ auth_info = user + ':' + pw ++ headers['Authorization'] = 'Basic ' + base64.b64encode(auth_info) ++ else: ++ auth_info = "anonymous" ++ ++ h.request('GET', req_url, None, headers) ++ ++ r = h.getresponse() ++ ++ actual_status = r.status ++ if expected_status and expected_status != actual_status: ++ ++ logger.warn("Expected status '" + str(expected_status) + ++ "' but got '" + str(actual_status) + ++ "' on url '" + req_url + "' (" + ++ auth_info + ").") ++ raise svntest.Failure ++ ++ if expected_body: ++ actual_body = r.read() ++ if expected_body != actual_body: ++ logger.warn("Expected body:") ++ logger.warn(expected_body) ++ logger.warn("But got:") ++ logger.warn(actual_body) ++ logger.warn("on url '" + req_url + "' (" + auth_info + ").") ++ raise svntest.Failure ++ ++def verify_gets(test_area_url, tests): ++ for test in tests: ++ verify_get(test_area_url, test['path'], test.get('user'), test.get('pw'), ++ test['status'], test.get('body'), test.get('headers')) ++ ++ ++###################################################################### ++# Tests ++# ++# Each test must return on success or raise on failure. ++ ++ ++#---------------------------------------------------------------------- ++ ++ ++@SkipUnless(svntest.main.is_ra_type_dav) ++def anon(sbox): ++ "test anonymous access" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/anon') ++ ++ write_authz_file(sbox) ++ ++ anon_tests = ( ++ { 'path': '', 'status': 301 }, ++ { 'path': '/', 'status': 200 }, ++ { 'path': '/repos', 'status': 301 }, ++ { 'path': '/repos/', 'status': 200 }, ++ { 'path': '/repos/A', 'status': 301 }, ++ { 'path': '/repos/A/', 'status': 200 }, ++ { 'path': '/repos/A/D', 'status': 301 }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H }, ++ { 'path': '/repos/A/D/gamma', 'status': 200 }, ++ { 'path': '/repos/A/D/H', 'status': 403 }, ++ { 'path': '/repos/A/D/H/', 'status': 403 }, ++ { 'path': '/repos/A/D/H/chi', 'status': 403 }, ++ # auth isn't configured so nothing should change when passing ++ # authn details ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ ) ++ ++ verify_gets(test_area_url, anon_tests) ++ ++ ++@SkipUnless(svntest.main.is_ra_type_dav) ++def mixed(sbox): ++ "test mixed anonymous and authenticated access" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/mixed') ++ ++ write_authz_file(sbox) ++ ++ mixed_tests = ( ++ { 'path': '', 'status': 301, }, ++ { 'path': '/', 'status': 200, }, ++ { 'path': '/repos', 'status': 301, }, ++ { 'path': '/repos/', 'status': 200, }, ++ { 'path': '/repos/A', 'status': 301, }, ++ { 'path': '/repos/A/', 'status': 200, }, ++ { 'path': '/repos/A/D', 'status': 301, }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, }, ++ { 'path': '/repos/A/D/H', 'status': 401, }, ++ { 'path': '/repos/A/D/H/', 'status': 401, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, }, ++ # auth is configured and user1 is allowed access to H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ ) ++ ++ verify_gets(test_area_url, mixed_tests) ++ ++@SkipUnless(svntest.main.is_ra_type_dav) ++@XFail(svntest.main.is_httpd_authz_provider_enabled) ++# uses the AuthzSVNNoAuthWhenAnonymousAllowed On directive ++# this is broken with httpd 2.3.x+ since it requires the auth system to accept ++# r->user == NULL and there is a test for this in server/request.c now. It ++# was intended as a workaround for the lack of Satisfy Any in 2.3.x+ which ++# was resolved by httpd with mod_access_compat in 2.3.x+. ++def mixed_noauthwhenanon(sbox): ++ "test mixed with noauthwhenanon directive" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/mixed-noauthwhenanon') ++ ++ write_authz_file(sbox) ++ ++ noauthwhenanon_tests = ( ++ { 'path': '', 'status': 301, }, ++ { 'path': '/', 'status': 200, }, ++ { 'path': '/repos', 'status': 301, }, ++ { 'path': '/repos/', 'status': 200, }, ++ { 'path': '/repos/A', 'status': 301, }, ++ { 'path': '/repos/A/', 'status': 200, }, ++ { 'path': '/repos/A/D', 'status': 301, }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, }, ++ { 'path': '/repos/A/D/H', 'status': 401, }, ++ { 'path': '/repos/A/D/H/', 'status': 401, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, }, ++ # auth is configured and user1 is allowed access to H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ # try with the wrong password for user1 ++ # note that unlike doing this with Satisfy Any this case ++ # actually provides anon access when provided with an invalid ++ # password ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ ) ++ ++ verify_gets(test_area_url, noauthwhenanon_tests) ++ ++ ++@SkipUnless(svntest.main.is_ra_type_dav) ++def authn(sbox): ++ "test authenticated only access" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/authn') ++ ++ write_authz_file(sbox) ++ ++ authn_tests = ( ++ { 'path': '', 'status': 401, }, ++ { 'path': '/', 'status': 401, }, ++ { 'path': '/repos', 'status': 401, }, ++ { 'path': '/repos/', 'status': 401, }, ++ { 'path': '/repos/A', 'status': 401, }, ++ { 'path': '/repos/A/', 'status': 401, }, ++ { 'path': '/repos/A/D', 'status': 401, }, ++ { 'path': '/repos/A/D/', 'status': 401, }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, }, ++ { 'path': '/repos/A/D/H', 'status': 401, }, ++ { 'path': '/repos/A/D/H/', 'status': 401, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, }, ++ # auth is configured and user1 is allowed access to H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ # try with upper case username for user1 ++ { 'path': '', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ # try with upper case username for user2 ++ { 'path': '', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ ) ++ ++ verify_gets(test_area_url, authn_tests) ++ ++@SkipUnless(svntest.main.is_ra_type_dav) ++def authn_anonoff(sbox): ++ "test authenticated only access with anonoff" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/authn-anonoff') ++ ++ write_authz_file(sbox) ++ ++ anonoff_tests = ( ++ { 'path': '', 'status': 401, }, ++ { 'path': '/', 'status': 401, }, ++ { 'path': '/repos', 'status': 401, }, ++ { 'path': '/repos/', 'status': 401, }, ++ { 'path': '/repos/A', 'status': 401, }, ++ { 'path': '/repos/A/', 'status': 401, }, ++ { 'path': '/repos/A/D', 'status': 401, }, ++ { 'path': '/repos/A/D/', 'status': 401, }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, }, ++ { 'path': '/repos/A/D/H', 'status': 401, }, ++ { 'path': '/repos/A/D/H/', 'status': 401, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, }, ++ # auth is configured and user1 is allowed access to H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ # try with upper case username for user1 ++ { 'path': '', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ # try with upper case username for user2 ++ { 'path': '', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ ) ++ ++ verify_gets(test_area_url, anonoff_tests) ++ ++@SkipUnless(svntest.main.is_ra_type_dav) ++def authn_lcuser(sbox): ++ "test authenticated only access with lcuser" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/authn-lcuser') ++ ++ write_authz_file(sbox) ++ ++ lcuser_tests = ( ++ # try with upper case username for user1 (works due to lcuser option) ++ { 'path': '', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1_upper, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, ++ # try with upper case username for user2 (works due to lcuser option) ++ { 'path': '', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, ++ ) ++ ++ verify_gets(test_area_url, lcuser_tests) ++ ++# authenticated access only by group - a excuse to use AuthzSVNAuthoritative Off ++# this is terribly messed up, Require group runs after mod_authz_svn. ++# so if mod_authz_svn grants the access then it doesn't matter what the group ++# requirement says. If we reject the access then you can use the AuthzSVNAuthoritative Off ++# directive to fall through to the group check. Overall the behavior of setups like this ++# is almost guaranteed to not be what users expect. ++@SkipUnless(svntest.main.is_ra_type_dav) ++def authn_group(sbox): ++ "test authenticated only access via groups" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/authn-group') ++ ++ # Can't use write_authz_file() as most tests because we want to deny all ++ # access with mod_authz_svn so the tests fall through to the group handling ++ authz_name = sbox.authz_name() ++ svntest.main.write_authz_file(sbox, { ++ '/': '* =', ++ }) ++ ++ group_tests = ( ++ { 'path': '', 'status': 401, }, ++ { 'path': '/', 'status': 401, }, ++ { 'path': '/repos', 'status': 401, }, ++ { 'path': '/repos/', 'status': 401, }, ++ { 'path': '/repos/A', 'status': 401, }, ++ { 'path': '/repos/A/', 'status': 401, }, ++ { 'path': '/repos/A/D', 'status': 401, }, ++ { 'path': '/repos/A/D/', 'status': 401, }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, }, ++ { 'path': '/repos/A/D/H', 'status': 401, }, ++ { 'path': '/repos/A/D/H/', 'status': 401, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, }, ++ # auth is configured and user1 is allowed access repo including H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ ) ++ ++ verify_gets(test_area_url, group_tests) ++ ++# This test exists to validate our behavior when used with the new authz ++# provider system introduced in httpd 2.3.x. The Satisfy directive ++# determines how older authz hooks are combined and the RequireA(ll|ny) ++# blocks handles how new authz providers are combined. The overall results of ++# all the authz providers (combined per the Require* blocks) are then ++# combined with the other authz hooks via the Satisfy directive. ++# Meaning this test requires that mod_authz_svn says yes and there is ++# either a valid user or the ALLOW header is 1. The header may seem ++# like a silly test but it's easier to excercise than say a host directive ++# in a repeatable test. ++@SkipUnless(svntest.main.is_httpd_authz_provider_enabled) ++def authn_sallrany(sbox): ++ "test satisfy all require any config" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/sallrany') ++ ++ write_authz_file(sbox) ++ ++ allow_header = { 'ALLOW': '1' } ++ ++ sallrany_tests = ( ++ #anon access isn't allowed without ALLOW header ++ { 'path': '', 'status': 401, }, ++ { 'path': '/', 'status': 401, }, ++ { 'path': '/repos', 'status': 401, }, ++ { 'path': '/repos/', 'status': 401, }, ++ { 'path': '/repos/A', 'status': 401, }, ++ { 'path': '/repos/A/', 'status': 401, }, ++ { 'path': '/repos/A/D', 'status': 401, }, ++ { 'path': '/repos/A/D/', 'status': 401, }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, }, ++ { 'path': '/repos/A/D/H', 'status': 401, }, ++ { 'path': '/repos/A/D/H/', 'status': 401, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, }, ++ # auth is configured and user1 is allowed access repo including H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, ++ # anon is allowed with the ALLOW header ++ { 'path': '', 'status': 301, 'headers': allow_header }, ++ { 'path': '/', 'status': 200, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 301, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 200, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 301, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 200, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 301, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'headers': allow_header }, ++ # these 3 tests return 403 instead of 401 becasue the config allows ++ # the anon user with the ALLOW header without any auth and the old hook ++ # system has no way of knowing it should return 401 since authentication is ++ # configured and can change the behavior. It could decide to return 401 just on ++ # the basis of authentication being configured but then that leaks info in other ++ # cases so it's better for this case to be "broken". ++ { 'path': '/repos/A/D/H', 'status': 403, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'headers': allow_header }, ++ # auth is configured and user1 is allowed access repo including H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ ++ ) ++ ++ verify_gets(test_area_url, sallrany_tests) ++ ++# See comments on authn_sallrany test for some background on the interaction ++# of Satisfy Any and the newer Require blocks. ++@SkipUnless(svntest.main.is_httpd_authz_provider_enabled) ++def authn_sallrall(sbox): ++ "test satisfy all require all config" ++ sbox.build(read_only = True, create_wc = False) ++ ++ test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', ++ '/authz-test-work/sallrall') ++ ++ write_authz_file(sbox) ++ ++ allow_header = { 'ALLOW': '1' } ++ ++ sallrall_tests = ( ++ #anon access isn't allowed without ALLOW header ++ { 'path': '', 'status': 403, }, ++ { 'path': '/', 'status': 403, }, ++ { 'path': '/repos', 'status': 403, }, ++ { 'path': '/repos/', 'status': 403, }, ++ { 'path': '/repos/A', 'status': 403, }, ++ { 'path': '/repos/A/', 'status': 403, }, ++ { 'path': '/repos/A/D', 'status': 403, }, ++ { 'path': '/repos/A/D/', 'status': 403, }, ++ { 'path': '/repos/A/D/gamma', 'status': 403, }, ++ { 'path': '/repos/A/D/H', 'status': 403, }, ++ { 'path': '/repos/A/D/H/', 'status': 403, }, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, }, ++ # auth is configured but no access is allowed without the ALLOW header ++ { 'path': '', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_pass}, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_badpass}, ++ # auth is configured but no access is allowed without the ALLOW header ++ { 'path': '', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_badpass}, ++ # anon is not allowed even with ALLOW header ++ { 'path': '', 'status': 401, 'headers': allow_header }, ++ { 'path': '/', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'headers': allow_header }, ++ # auth is configured and user1 is allowed access repo including H ++ { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, ++ 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, ++ # try with the wrong password for user1 ++ { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, ++ # auth is configured and user2 is not allowed access to H ++ { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, ++ 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, ++ # try with the wrong password for user2 ++ { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, ++ ++ ) ++ ++ verify_gets(test_area_url, sallrall_tests) ++ ++ ++######################################################################## ++# Run the tests ++ ++ ++# list all tests here, starting with None: ++test_list = [ None, ++ anon, ++ mixed, ++ mixed_noauthwhenanon, ++ authn, ++ authn_anonoff, ++ authn_lcuser, ++ authn_group, ++ authn_sallrany, ++ authn_sallrall, ++ ] ++serial_only = True ++ ++if __name__ == '__main__': ++ svntest.main.run_tests(test_list) ++ # NOTREACHED ++ ++ ++### End of file. +Index: subversion-1.8.11/subversion/tests/cmdline/svntest/main.py +=================================================================== +--- subversion-1.8.11.orig/subversion/tests/cmdline/svntest/main.py ++++ subversion-1.8.11/subversion/tests/cmdline/svntest/main.py +@@ -1368,6 +1368,30 @@ def is_plaintext_password_storage_disabl + return False + return True + ++ ++# https://issues.apache.org/bugzilla/show_bug.cgi?id=56480 ++# https://issues.apache.org/bugzilla/show_bug.cgi?id=55397 ++__mod_dav_url_quoting_broken_versions = frozenset([ ++ '2.2.27', ++ '2.2.26', ++ '2.2.25', ++ '2.4.9', ++ '2.4.8', ++ '2.4.7', ++ '2.4.6', ++ '2.4.5', ++]) ++def is_mod_dav_url_quoting_broken(): ++ if is_ra_type_dav(): ++ return (options.httpd_version in __mod_dav_url_quoting_broken_versions) ++ return None ++ ++def is_httpd_authz_provider_enabled(): ++ if is_ra_type_dav(): ++ v = options.httpd_version.split('.') ++ return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2 ++ return None ++ + ###################################################################### + + +@@ -1425,6 +1449,8 @@ class TestSpawningThread(threading.Threa + args.append('--ssl-cert=' + options.ssl_cert) + if options.http_proxy: + args.append('--http-proxy=' + options.http_proxy) ++ if options.httpd_version: ++ args.append('--httpd-version=' + options.httpd_version) + + result, stdout_lines, stderr_lines = spawn_process(command, 0, False, None, + *args) +@@ -1590,6 +1616,12 @@ class TestRunner: + sandbox.cleanup_test_paths() + return exit_code + ++def is_httpd_authz_provider_enabled(): ++ if is_ra_type_dav(): ++ v = options.httpd_version.split('.') ++ return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2 ++ return None ++ + ###################################################################### + # Main testing functions + +@@ -1770,6 +1802,8 @@ def _create_parser(): + help='Path to SSL server certificate.') + parser.add_option('--http-proxy', action='store', + help='Use the HTTP Proxy at hostname:port.') ++ parser.add_option('--httpd-version', action='store', ++ help='Assume HTTPD is this version.') + parser.add_option('--tools-bin', action='store', dest='tools_bin', + help='Use the svn tools installed in this path') + +Index: subversion-1.8.11/win-tests.py +=================================================================== +--- subversion-1.8.11.orig/win-tests.py ++++ subversion-1.8.11/win-tests.py +@@ -481,6 +481,7 @@ class Httpd: + self.httpd_config = os.path.join(self.root, 'httpd.conf') + self.httpd_users = os.path.join(self.root, 'users') + self.httpd_mime_types = os.path.join(self.root, 'mime.types') ++ self.httpd_groups = os.path.join(self.root, 'groups') + self.abs_builddir = abs_builddir + self.abs_objdir = abs_objdir + self.service_name = 'svn-test-httpd-' + str(httpd_port) +@@ -494,6 +495,7 @@ class Httpd: + create_target_dir(self.root_dir) + + self._create_users_file() ++ self._create_groups_file() + self._create_mime_types_file() + self._create_dontdothat_file() + +@@ -540,6 +542,8 @@ class Httpd: + if self.httpd_ver >= 2.2: + fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so')) + fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so')) ++ fp.write(self._sys_module('authz_groupfile_module', 'mod_authz_groupfile.so')) ++ fp.write(self._sys_module('authz_host_module', 'mod_authz_host.so')) + else: + fp.write(self._sys_module('auth_module', 'mod_auth.so')) + fp.write(self._sys_module('alias_module', 'mod_alias.so')) +@@ -562,6 +566,7 @@ class Httpd: + # Define two locations for repositories + fp.write(self._svn_repo('repositories')) + fp.write(self._svn_repo('local_tmp')) ++ fp.write(self._svn_authz_repo()) + + # And two redirects for the redirect tests + fp.write('RedirectMatch permanent ^/svn-test-work/repositories/' +@@ -592,6 +597,17 @@ class Httpd: + 'jrandom', 'rayjandom']) + os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, + 'jconstant', 'rayjandom']) ++ os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, ++ 'JRANDOM', 'rayjandom']) ++ os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, ++ 'JCONSTANT', 'rayjandom']) ++ ++ def _create_groups_file(self): ++ "Create groups for mod_authz_svn tests" ++ fp = open(self.httpd_groups, 'w') ++ fp.write('random: jrandom\n') ++ fp.write('constant: jconstant\n') ++ fp.close() + + def _create_mime_types_file(self): + "Create empty mime.types file" +@@ -652,6 +668,153 @@ class Httpd: + ' DontDoThatConfigFile ' + self._quote(self.dontdothat_file) + '\n' \ + '</Location>\n' + ++ def _svn_authz_repo(self): ++ local_tmp = os.path.join(self.abs_builddir, ++ CMDLINE_TEST_SCRIPT_NATIVE_PATH, ++ 'svn-test-work', 'local_tmp') ++ return \ ++ '<Location /authz-test-work/anon>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' <IfModule mod_authz_core.c>' + '\n' \ ++ ' Require all granted' + '\n' \ ++ ' </IfModule>' + '\n' \ ++ ' <IfModule !mod_authz_core.c>' + '\n' \ ++ ' Allow from all' + '\n' \ ++ ' </IfModule>' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/mixed>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' Satisfy Any' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/mixed-noauthwhenanon>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' AuthzSVNNoAuthWhenAnonymousAllowed On' + '\n' \ ++ ' SVNPathAuthz On' + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/authn>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/authn-anonoff>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' AuthzSVNAnonymous Off' + '\n' \ ++ ' SVNPathAuthz On' + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/authn-lcuser>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' AuthzForceUsernameCase Lower' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/authn-lcuser>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' AuthzForceUsernameCase Lower' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/authn-group>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' AuthGroupFile ' + self._quote(self.httpd_groups) + '\n' \ ++ ' Require group random' + '\n' \ ++ ' AuthzSVNAuthoritative Off' + '\n' \ ++ ' SVNPathAuthz On' + '\n' \ ++ '</Location>' + '\n' \ ++ '<IfModule mod_authz_core.c>' + '\n' \ ++ '<Location /authz-test-work/sallrany>' + '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' AuthzSendForbiddenOnFailure On' + '\n' \ ++ ' Satisfy All' + '\n' \ ++ ' <RequireAny>' + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \ ++ ' </RequireAny>' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '<Location /authz-test-work/sallrall>'+ '\n' \ ++ ' DAV svn' + '\n' \ ++ ' SVNParentPath ' + local_tmp + '\n' \ ++ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ ++ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ ++ ' SVNListParentPath On' + '\n' \ ++ ' AuthType Basic' + '\n' \ ++ ' AuthName "Subversion Repository"' + '\n' \ ++ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ ++ ' AuthzSendForbiddenOnFailure On' + '\n' \ ++ ' Satisfy All' + '\n' \ ++ ' <RequireAll>' + '\n' \ ++ ' Require valid-user' + '\n' \ ++ ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \ ++ ' </RequireAll>' + '\n' \ ++ ' SVNPathAuthz ' + self.path_authz_option + '\n' \ ++ '</Location>' + '\n' \ ++ '</IfModule>' + '\n' \ ++ + def start(self): + if self.service: + self._start_service() +@@ -786,6 +949,10 @@ if not test_javahl: + log_file = os.path.join(abs_builddir, log) + fail_log_file = os.path.join(abs_builddir, faillog) + ++ if run_httpd: ++ httpd_version = "%.1f" % daemon.httpd_ver ++ else: ++ httpd_version = None + th = run_tests.TestHarness(abs_srcdir, abs_builddir, + log_file, + fail_log_file, +@@ -795,6 +962,7 @@ if not test_javahl: + fsfs_sharding, fsfs_packing, + list_tests, svn_bin, mode_filter, + milestone_filter, ++ httpd_version=httpd_version, + set_log_level=log_level, ssl_cert=ssl_cert) + old_cwd = os.getcwd() + try: diff --git a/meta/recipes-devtools/subversion/subversion_1.8.11.bb b/meta/recipes-devtools/subversion/subversion_1.8.11.bb index a5a5761..7893929 100644 --- a/meta/recipes-devtools/subversion/subversion_1.8.11.bb +++ b/meta/recipes-devtools/subversion/subversion_1.8.11.bb @@ -12,6 +12,7 @@ inherit gettext pythonnative SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \ file://libtool2.patch \ file://disable_macos.patch \ + file://subversion-CVE-2015-3184.patch \ " SRC_URI[md5sum] = "766a89bbbb388f8eb76166672d3b9e49" SRC_URI[sha256sum] = "10b056420e1f194c12840368f6bf58842e6200f9cb8cc5ebbf9be2e89e56e4d9" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 08/21] subversion: fix CVE-2015-3187 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (6 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 07/21] subversion: fix CVE-2015-3184 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 09/21] qemu: Security fix CVE-2015-8504 Armin Kuster ` (13 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Wenzong Fan <wenzong.fan@windriver.com> The svn_repos_trace_node_locations function in Apache Subversion before 1.7.21 and 1.8.x before 1.8.14, when path-based authorization is used, allows remote authenticated users to obtain sensitive path information by reading the history of a node that has been moved from a hidden path. Patch is from: http://subversion.apache.org/security/CVE-2015-3187-advisory.txt (From OE-Core master rev: 6da25614edcad30fdb4bea8ff47b81ff81cdaed2) (From OE-Core rev: e1e277bf51c6f00268358f6bf8623261b1b9bc22) Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../subversion-CVE-2015-3187.patch | 346 +++++++++++++++++++++ .../subversion/subversion_1.8.11.bb | 1 + 2 files changed, 347 insertions(+) create mode 100644 meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3187.patch diff --git a/meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3187.patch b/meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3187.patch new file mode 100644 index 0000000..e300380 --- /dev/null +++ b/meta/recipes-devtools/subversion/subversion-1.8.11/subversion-CVE-2015-3187.patch @@ -0,0 +1,346 @@ +Fix CVE-2015-3187 + +Patch is from: +http://subversion.apache.org/security/CVE-2015-3187-advisory.txt + +Upstream-Status: Backport + +Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com> + +Index: subversion-1.8.11/subversion/libsvn_repos/rev_hunt.c +=================================================================== +--- subversion-1.8.11.orig/subversion/libsvn_repos/rev_hunt.c ++++ subversion-1.8.11/subversion/libsvn_repos/rev_hunt.c +@@ -726,23 +726,6 @@ svn_repos_trace_node_locations(svn_fs_t + if (! prev_path) + break; + +- if (authz_read_func) +- { +- svn_boolean_t readable; +- svn_fs_root_t *tmp_root; +- +- SVN_ERR(svn_fs_revision_root(&tmp_root, fs, revision, currpool)); +- SVN_ERR(authz_read_func(&readable, tmp_root, path, +- authz_read_baton, currpool)); +- if (! readable) +- { +- svn_pool_destroy(lastpool); +- svn_pool_destroy(currpool); +- +- return SVN_NO_ERROR; +- } +- } +- + /* Assign the current path to all younger revisions until we reach + the copy target rev. */ + while ((revision_ptr < revision_ptr_end) +@@ -765,6 +748,20 @@ svn_repos_trace_node_locations(svn_fs_t + path = prev_path; + revision = prev_rev; + ++ if (authz_read_func) ++ { ++ svn_boolean_t readable; ++ SVN_ERR(svn_fs_revision_root(&root, fs, revision, currpool)); ++ SVN_ERR(authz_read_func(&readable, root, path, ++ authz_read_baton, currpool)); ++ if (!readable) ++ { ++ svn_pool_destroy(lastpool); ++ svn_pool_destroy(currpool); ++ return SVN_NO_ERROR; ++ } ++ } ++ + /* Clear last pool and switch. */ + svn_pool_clear(lastpool); + tmppool = lastpool; +Index: subversion-1.8.11/subversion/tests/cmdline/authz_tests.py +=================================================================== +--- subversion-1.8.11.orig/subversion/tests/cmdline/authz_tests.py ++++ subversion-1.8.11/subversion/tests/cmdline/authz_tests.py +@@ -609,8 +609,10 @@ def authz_log_and_tracing_test(sbox): + + ## cat + ++ expected_err2 = ".*svn: E195012: Unable to find repository location.*" ++ + # now see if we can look at the older version of rho +- svntest.actions.run_and_verify_svn(None, None, expected_err, ++ svntest.actions.run_and_verify_svn(None, None, expected_err2, + 'cat', '-r', '2', D_url+'/rho') + + if sbox.repo_url.startswith('http'): +@@ -627,10 +629,11 @@ def authz_log_and_tracing_test(sbox): + svntest.actions.run_and_verify_svn(None, None, expected_err, + 'diff', '-r', 'HEAD', G_url+'/rho') + +- svntest.actions.run_and_verify_svn(None, None, expected_err, ++ # diff treats the unreadable path as indicating an add so no error ++ svntest.actions.run_and_verify_svn(None, None, [], + 'diff', '-r', '2', D_url+'/rho') + +- svntest.actions.run_and_verify_svn(None, None, expected_err, ++ svntest.actions.run_and_verify_svn(None, None, [], + 'diff', '-r', '2:4', D_url+'/rho') + + # test whether read access is correctly granted and denied +Index: subversion-1.8.11/subversion/tests/libsvn_repos/repos-test.c +=================================================================== +--- subversion-1.8.11.orig/subversion/tests/libsvn_repos/repos-test.c ++++ subversion-1.8.11/subversion/tests/libsvn_repos/repos-test.c +@@ -3320,6 +3320,245 @@ test_dump_r0_mergeinfo(const svn_test_op + return SVN_NO_ERROR; + } + ++static svn_error_t * ++mkdir_delete_copy(svn_repos_t *repos, ++ const char *src, ++ const char *dst, ++ apr_pool_t *pool) ++{ ++ svn_fs_t *fs = svn_repos_fs(repos); ++ svn_revnum_t youngest_rev; ++ svn_fs_txn_t *txn; ++ svn_fs_root_t *txn_root, *rev_root; ++ ++ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool)); ++ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_make_dir(txn_root, "A/T", pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_delete(txn_root, "A/T", pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_revision_root(&rev_root, fs, youngest_rev - 1, pool)); ++ SVN_ERR(svn_fs_copy(rev_root, src, txn_root, dst, pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ return SVN_NO_ERROR; ++} ++ ++struct authz_read_baton_t { ++ apr_hash_t *paths; ++ apr_pool_t *pool; ++ const char *deny; ++}; ++ ++static svn_error_t * ++authz_read_func(svn_boolean_t *allowed, ++ svn_fs_root_t *root, ++ const char *path, ++ void *baton, ++ apr_pool_t *pool) ++{ ++ struct authz_read_baton_t *b = baton; ++ ++ if (b->deny && !strcmp(b->deny, path)) ++ *allowed = FALSE; ++ else ++ *allowed = TRUE; ++ ++ svn_hash_sets(b->paths, apr_pstrdup(b->pool, path), (void*)1); ++ ++ return SVN_NO_ERROR; ++} ++ ++static svn_error_t * ++verify_locations(apr_hash_t *actual, ++ apr_hash_t *expected, ++ apr_hash_t *checked, ++ apr_pool_t *pool) ++{ ++ apr_hash_index_t *hi; ++ ++ for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi)) ++ { ++ const svn_revnum_t *rev = svn__apr_hash_index_key(hi); ++ const char *path = apr_hash_get(actual, rev, sizeof(svn_revnum_t)); ++ ++ if (!path) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "expected %s for %d found (null)", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev); ++ else if (strcmp(path, svn__apr_hash_index_val(hi))) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "expected %s for %d found %s", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev, path); ++ ++ } ++ ++ for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi)) ++ { ++ const svn_revnum_t *rev = svn__apr_hash_index_key(hi); ++ const char *path = apr_hash_get(expected, rev, sizeof(svn_revnum_t)); ++ ++ if (!path) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "found %s for %d expected (null)", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev); ++ else if (strcmp(path, svn__apr_hash_index_val(hi))) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "found %s for %d expected %s", ++ (char*)svn__apr_hash_index_val(hi), ++ (int)*rev, path); ++ ++ if (!svn_hash_gets(checked, path)) ++ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, ++ "did not check %s", path); ++ } ++ ++ return SVN_NO_ERROR; ++} ++ ++static void ++set_expected(apr_hash_t *expected, ++ svn_revnum_t rev, ++ const char *path, ++ apr_pool_t *pool) ++{ ++ svn_revnum_t *rp = apr_palloc(pool, sizeof(svn_revnum_t)); ++ *rp = rev; ++ apr_hash_set(expected, rp, sizeof(svn_revnum_t), path); ++} ++ ++static svn_error_t * ++trace_node_locations_authz(const svn_test_opts_t *opts, ++ apr_pool_t *pool) ++{ ++ svn_repos_t *repos; ++ svn_fs_t *fs; ++ svn_revnum_t youngest_rev = 0; ++ svn_fs_txn_t *txn; ++ svn_fs_root_t *txn_root; ++ struct authz_read_baton_t arb; ++ apr_array_header_t *revs = apr_array_make(pool, 10, sizeof(svn_revnum_t)); ++ apr_hash_t *locations; ++ apr_hash_t *expected = apr_hash_make(pool); ++ int i; ++ ++ /* Create test repository. */ ++ SVN_ERR(svn_test__create_repos(&repos, "test-repo-trace-node-locations-authz", ++ opts, pool)); ++ fs = svn_repos_fs(repos); ++ ++ /* r1 create A */ ++ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); ++ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); ++ SVN_ERR(svn_fs_make_dir(txn_root, "A", pool)); ++ SVN_ERR(svn_fs_make_file(txn_root, "A/f", pool)); ++ SVN_ERR(svn_test__set_file_contents(txn_root, "A/f", "foobar", pool)); ++ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); ++ ++ /* r4 copy A to B */ ++ SVN_ERR(mkdir_delete_copy(repos, "A", "B", pool)); ++ ++ /* r7 copy B to C */ ++ SVN_ERR(mkdir_delete_copy(repos, "B", "C", pool)); ++ ++ /* r10 copy C to D */ ++ SVN_ERR(mkdir_delete_copy(repos, "C", "D", pool)); ++ ++ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool)); ++ SVN_ERR_ASSERT(youngest_rev == 10); ++ ++ arb.paths = apr_hash_make(pool); ++ arb.pool = pool; ++ arb.deny = NULL; ++ ++ apr_array_clear(revs); ++ for (i = 0; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 10, "/D/f", pool); ++ set_expected(expected, 8, "/C/f", pool); ++ set_expected(expected, 7, "/C/f", pool); ++ set_expected(expected, 5, "/B/f", pool); ++ set_expected(expected, 4, "/B/f", pool); ++ set_expected(expected, 2, "/A/f", pool); ++ set_expected(expected, 1, "/A/f", pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 1; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 2; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 1, NULL, pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 3; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 2, NULL, pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 6; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ set_expected(expected, 5, NULL, pool); ++ set_expected(expected, 4, NULL, pool); ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ arb.deny = "/B/f"; ++ apr_array_clear(revs); ++ for (i = 0; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ apr_array_clear(revs); ++ for (i = 6; i <= youngest_rev; ++i) ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = i; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ APR_ARRAY_PUSH(revs, svn_revnum_t) = 0; ++ apr_hash_clear(arb.paths); ++ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, ++ authz_read_func, &arb, pool)); ++ SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); ++ ++ return SVN_NO_ERROR; ++} ++ + /* The test table. */ + + struct svn_test_descriptor_t test_funcs[] = +@@ -3367,5 +3606,7 @@ struct svn_test_descriptor_t test_funcs[ + "test filenames with control characters"), + SVN_TEST_OPTS_PASS(test_dump_r0_mergeinfo, + "test dumping with r0 mergeinfo"), ++ SVN_TEST_OPTS_PASS(trace_node_locations_authz, ++ "authz for svn_repos_trace_node_locations"), + SVN_TEST_NULL + }; diff --git a/meta/recipes-devtools/subversion/subversion_1.8.11.bb b/meta/recipes-devtools/subversion/subversion_1.8.11.bb index 7893929..b2825d9 100644 --- a/meta/recipes-devtools/subversion/subversion_1.8.11.bb +++ b/meta/recipes-devtools/subversion/subversion_1.8.11.bb @@ -13,6 +13,7 @@ SRC_URI = "${APACHE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \ file://libtool2.patch \ file://disable_macos.patch \ file://subversion-CVE-2015-3184.patch \ + file://subversion-CVE-2015-3187.patch \ " SRC_URI[md5sum] = "766a89bbbb388f8eb76166672d3b9e49" SRC_URI[sha256sum] = "10b056420e1f194c12840368f6bf58842e6200f9cb8cc5ebbf9be2e89e56e4d9" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 09/21] qemu: Security fix CVE-2015-8504 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (7 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 08/21] subversion: fix CVE-2015-3187 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 10/21] qemu: Security fix CVE-2015-7504 Armin Kuster ` (12 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-8504 Qemu: ui: vnc: avoid floating point exception (From OE-Core rev: c622bdd7133d31d7fbefe87fb38187f0aea4b592) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../recipes-devtools/qemu/qemu/CVE-2015-8504.patch | 51 ++++++++++++++++++++++ meta/recipes-devtools/qemu/qemu_2.2.0.bb | 1 + 2 files changed, 52 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-8504.patch diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-8504.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-8504.patch new file mode 100644 index 0000000..2e6c897 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-8504.patch @@ -0,0 +1,51 @@ +From 4c65fed8bdf96780735dbdb92a8bd0d6b6526cc3 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit <pjp@fedoraproject.org> +Date: Thu, 3 Dec 2015 18:54:17 +0530 +Subject: [PATCH] ui: vnc: avoid floating point exception + +While sending 'SetPixelFormat' messages to a VNC server, +the client could set the 'red-max', 'green-max' and 'blue-max' +values to be zero. This leads to a floating point exception in +write_png_palette while doing frame buffer updates. + +Reported-by: Lian Yihan <lianyihan@360.cn> +Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> +Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> +Signed-off-by: Peter Maydell <peter.maydell@linaro.org> + +Upstream-Status: Backport + +http://git.qemu.org/?p=qemu.git;a=commitdiff;h=4c65fed8bdf96780735dbdb92a8 + +CVE: CVE-2015-8504 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + ui/vnc.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: qemu-2.2.0/ui/vnc.c +=================================================================== +--- qemu-2.2.0.orig/ui/vnc.c ++++ qemu-2.2.0/ui/vnc.c +@@ -2036,15 +2036,15 @@ static void set_pixel_format(VncState *v + return; + } + +- vs->client_pf.rmax = red_max; ++ vs->client_pf.rmax = red_max ? red_max : 0xFF; + vs->client_pf.rbits = hweight_long(red_max); + vs->client_pf.rshift = red_shift; + vs->client_pf.rmask = red_max << red_shift; +- vs->client_pf.gmax = green_max; ++ vs->client_pf.gmax = green_max ? green_max : 0xFF; + vs->client_pf.gbits = hweight_long(green_max); + vs->client_pf.gshift = green_shift; + vs->client_pf.gmask = green_max << green_shift; +- vs->client_pf.bmax = blue_max; ++ vs->client_pf.bmax = blue_max ? blue_max : 0xFF; + vs->client_pf.bbits = hweight_long(blue_max); + vs->client_pf.bshift = blue_shift; + vs->client_pf.bmask = blue_max << blue_shift; diff --git a/meta/recipes-devtools/qemu/qemu_2.2.0.bb b/meta/recipes-devtools/qemu/qemu_2.2.0.bb index 4c6880b..eaf8daf 100644 --- a/meta/recipes-devtools/qemu/qemu_2.2.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.2.0.bb @@ -20,6 +20,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch \ file://11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch \ file://qemu-fix-CVE-2015-3209.patch \ + file://CVE-2015-8504.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" SRC_URI[md5sum] = "f7a5e2da22d057eb838a91da7aff43c8" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 10/21] qemu: Security fix CVE-2015-7504 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (8 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 09/21] qemu: Security fix CVE-2015-8504 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 11/21] qemu: Security fix CVE-2015-7512 Armin Kuster ` (11 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-7504 Qemu: net: pcnet: heap overflow vulnerability in loopback mode (From OE-Core rev: b01b569d7d7e651a35fa38750462f13aeb64a2f3) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../recipes-devtools/qemu/qemu/CVE-2015-7504.patch | 56 ++++++++++++++++++++++ meta/recipes-devtools/qemu/qemu_2.2.0.bb | 1 + 2 files changed, 57 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7504.patch diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-7504.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-7504.patch new file mode 100644 index 0000000..04e6183 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-7504.patch @@ -0,0 +1,56 @@ +From 837f21aacf5a714c23ddaadbbc5212f9b661e3f7 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit <pjp@fedoraproject.org> +Date: Fri, 20 Nov 2015 11:50:31 +0530 +Subject: [PATCH] net: pcnet: add check to validate receive data + size(CVE-2015-7504) + +In loopback mode, pcnet_receive routine appends CRC code to the +receive buffer. If the data size given is same as the buffer size, +the appended CRC code overwrites 4 bytes after s->buffer. Added a +check to avoid that. + +Reported by: Qinghao Tang <luodalongde@gmail.com> +Cc: qemu-stable@nongnu.org +Reviewed-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> +Signed-off-by: Jason Wang <jasowang@redhat.com> + +Upstream-Status: Backport + +http://git.qemu.org/?p=qemu.git;a=commit;h=837f21aacf5a714c23ddaadbbc5212f9b661e3f7 + +CVE: CVE-2015-7504 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/net/pcnet.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +Index: qemu-2.2.0/hw/net/pcnet.c +=================================================================== +--- qemu-2.2.0.orig/hw/net/pcnet.c ++++ qemu-2.2.0/hw/net/pcnet.c +@@ -1106,7 +1106,7 @@ ssize_t pcnet_receive(NetClientState *nc + uint32_t fcs = ~0; + uint8_t *p = src; + +- while (p != &src[size-4]) ++ while (p != &src[size]) + CRC(fcs, *p++); + crc_err = (*(uint32_t *)p != htonl(fcs)); + } +@@ -1255,8 +1255,10 @@ static void pcnet_transmit(PCNetState *s + bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); + + /* if multi-tmd packet outsizes s->buffer then skip it silently. +- Note: this is not what real hw does */ +- if (s->xmit_pos + bcnt > sizeof(s->buffer)) { ++ * Note: this is not what real hw does. ++ * Last four bytes of s->buffer are used to store CRC FCS code. ++ */ ++ if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) { + s->xmit_pos = -1; + goto txdone; + } diff --git a/meta/recipes-devtools/qemu/qemu_2.2.0.bb b/meta/recipes-devtools/qemu/qemu_2.2.0.bb index eaf8daf..bb27034 100644 --- a/meta/recipes-devtools/qemu/qemu_2.2.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.2.0.bb @@ -21,6 +21,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch \ file://qemu-fix-CVE-2015-3209.patch \ file://CVE-2015-8504.patch \ + file://CVE-2015-7504.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" SRC_URI[md5sum] = "f7a5e2da22d057eb838a91da7aff43c8" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 11/21] qemu: Security fix CVE-2015-7512 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (9 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 10/21] qemu: Security fix CVE-2015-7504 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 12/21] qemu: Security fix CVE-2015-8345 Armin Kuster ` (10 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-7512 Qemu: net: pcnet: buffer overflow in non-loopback mod (From OE-Core rev: e6e9be51f77c9531f49cebe0ca6b495c23cf022d) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../recipes-devtools/qemu/qemu/CVE-2015-7512.patch | 44 ++++++++++++++++++++++ meta/recipes-devtools/qemu/qemu_2.2.0.bb | 1 + 2 files changed, 45 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7512.patch diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-7512.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-7512.patch new file mode 100644 index 0000000..9b4cf14 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-7512.patch @@ -0,0 +1,44 @@ +From 8b98a2f07175d46c3f7217639bd5e03f2ec56343 Mon Sep 17 00:00:00 2001 +From: Jason Wang <jasowang@redhat.com> +Date: Mon, 30 Nov 2015 15:00:06 +0800 +Subject: [PATCH] pcnet: fix rx buffer overflow(CVE-2015-7512) + +Backends could provide a packet whose length is greater than buffer +size. Check for this and truncate the packet to avoid rx buffer +overflow in this case. + +Cc: Prasad J Pandit <pjp@fedoraproject.org> +Cc: qemu-stable@nongnu.org +Reviewed-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Jason Wang <jasowang@redhat.com> + +Upsteam_Status: Backport + +http://git.qemu.org/?p=qemu.git;a=commit;h=8b98a2f07175d46c3f7217639bd5e03f2ec56343 + +CVE: CVE-2015-7512 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/net/pcnet.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: qemu-2.2.0/hw/net/pcnet.c +=================================================================== +--- qemu-2.2.0.orig/hw/net/pcnet.c ++++ qemu-2.2.0/hw/net/pcnet.c +@@ -1086,6 +1086,12 @@ ssize_t pcnet_receive(NetClientState *nc + int pktcount = 0; + + if (!s->looptest) { ++ if (size > 4092) { ++#ifdef PCNET_DEBUG_RMD ++ fprintf(stderr, "pcnet: truncates rx packet.\n"); ++#endif ++ size = 4092; ++ } + memcpy(src, buf, size); + /* no need to compute the CRC */ + src[size] = 0; diff --git a/meta/recipes-devtools/qemu/qemu_2.2.0.bb b/meta/recipes-devtools/qemu/qemu_2.2.0.bb index bb27034..950917e 100644 --- a/meta/recipes-devtools/qemu/qemu_2.2.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.2.0.bb @@ -22,6 +22,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://qemu-fix-CVE-2015-3209.patch \ file://CVE-2015-8504.patch \ file://CVE-2015-7504.patch \ + file://CVE-2015-7512.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" SRC_URI[md5sum] = "f7a5e2da22d057eb838a91da7aff43c8" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 12/21] qemu: Security fix CVE-2015-8345 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (10 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 11/21] qemu: Security fix CVE-2015-7512 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 13/21] qemu: Security fix CVE-2016-1568 Armin Kuster ` (9 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-8345 Qemu: net: eepro100: infinite loop in processing command block list (From OE-Core rev: 99ffcd66895e4ba064542a1797057e45ec4d3220) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../recipes-devtools/qemu/qemu/CVE-2015-8345.patch | 73 ++++++++++++++++++++++ meta/recipes-devtools/qemu/qemu_2.2.0.bb | 1 + 2 files changed, 74 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-8345.patch diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-8345.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-8345.patch new file mode 100644 index 0000000..310b458 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-8345.patch @@ -0,0 +1,73 @@ +From 00837731d254908a841d69298a4f9f077babaf24 Mon Sep 17 00:00:00 2001 +From: Stefan Weil <sw@weilnetz.de> +Date: Fri, 20 Nov 2015 08:42:33 +0100 +Subject: [PATCH] eepro100: Prevent two endless loops + +http://lists.nongnu.org/archive/html/qemu-devel/2015-11/msg04592.html +shows an example how an endless loop in function action_command can +be achieved. + +During my code review, I noticed a 2nd case which can result in an +endless loop. + +Reported-by: Qinghao Tang <luodalongde@gmail.com> +Signed-off-by: Stefan Weil <sw@weilnetz.de> +Signed-off-by: Jason Wang <jasowang@redhat.com> + +Upstream-Status: Backport + +http://git.qemu.org/?p=qemu.git;a=commit;h=00837731d254908a841d69298a4f9f077babaf24 + +CVE: CVE-2015-8345 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/net/eepro100.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c +index 60333b7..685a478 100644 +--- a/hw/net/eepro100.c ++++ b/hw/net/eepro100.c +@@ -774,6 +774,11 @@ static void tx_command(EEPRO100State *s) + #if 0 + uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6); + #endif ++ if (tx_buffer_size == 0) { ++ /* Prevent an endless loop. */ ++ logout("loop in %s:%u\n", __FILE__, __LINE__); ++ break; ++ } + tbd_address += 8; + TRACE(RXTX, logout + ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n", +@@ -855,6 +860,10 @@ static void set_multicast_list(EEPRO100State *s) + + static void action_command(EEPRO100State *s) + { ++ /* The loop below won't stop if it gets special handcrafted data. ++ Therefore we limit the number of iterations. */ ++ unsigned max_loop_count = 16; ++ + for (;;) { + bool bit_el; + bool bit_s; +@@ -870,6 +879,13 @@ static void action_command(EEPRO100State *s) + #if 0 + bool bit_sf = ((s->tx.command & COMMAND_SF) != 0); + #endif ++ ++ if (max_loop_count-- == 0) { ++ /* Prevent an endless loop. */ ++ logout("loop in %s:%u\n", __FILE__, __LINE__); ++ break; ++ } ++ + s->cu_offset = s->tx.link; + TRACE(OTHER, + logout("val=(cu start), status=0x%04x, command=0x%04x, link=0x%08x\n", +-- +2.3.5 + diff --git a/meta/recipes-devtools/qemu/qemu_2.2.0.bb b/meta/recipes-devtools/qemu/qemu_2.2.0.bb index 950917e..72fda62 100644 --- a/meta/recipes-devtools/qemu/qemu_2.2.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.2.0.bb @@ -23,6 +23,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://CVE-2015-8504.patch \ file://CVE-2015-7504.patch \ file://CVE-2015-7512.patch \ + file://CVE-2015-8345.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" SRC_URI[md5sum] = "f7a5e2da22d057eb838a91da7aff43c8" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 13/21] qemu: Security fix CVE-2016-1568 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (11 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 12/21] qemu: Security fix CVE-2015-8345 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 14/21] qemu: Security fix CVE-2015-7295 Armin Kuster ` (8 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2016-1568 Qemu: ide: ahci use-after-free vulnerability in aio port commands (From OE-Core rev: 166c19df8be28da255cc68032e2d11afc59d4197) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../recipes-devtools/qemu/qemu/CVE-2016-1568.patch | 46 ++++++++++++++++++++++ meta/recipes-devtools/qemu/qemu_2.2.0.bb | 1 + 2 files changed, 47 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2016-1568.patch diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-1568.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-1568.patch new file mode 100644 index 0000000..319ae24 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-1568.patch @@ -0,0 +1,46 @@ +From 4ab0359a8ae182a7ac5c99609667273167703fab Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit <pjp@fedoraproject.org> +Date: Mon, 11 Jan 2016 14:10:42 -0500 +Subject: [PATCH] ide: ahci: reset ncq object to unused on error + +When processing NCQ commands, AHCI device emulation prepares a +NCQ transfer object; To which an aio control block(aiocb) object +is assigned in 'execute_ncq_command'. In case, when the NCQ +command is invalid, the 'aiocb' object is not assigned, and NCQ +transfer object is left as 'used'. This leads to a use after +free kind of error in 'bdrv_aio_cancel_async' via 'ahci_reset_port'. +Reset NCQ transfer object to 'unused' to avoid it. + +[Maintainer edit: s/ACHI/AHCI/ in the commit message. --js] + +Reported-by: Qinghao Tang <luodalongde@gmail.com> +Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> +Reviewed-by: John Snow <jsnow@redhat.com> +Message-id: 1452282511-4116-1-git-send-email-ppandit@redhat.com +Signed-off-by: John Snow <jsnow@redhat.com> + +Upstream-Status: Backport + +http://git.qemu.org/?p=qemu.git;a=commit;h=4ab0359a8ae182a7ac5c99609667273167703fab + +CVE: CVE-2016-1568 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/ide/ahci.c | 1 + + 1 file changed, 1 insertion(+) + +Index: qemu-2.2.0/hw/ide/ahci.c +=================================================================== +--- qemu-2.2.0.orig/hw/ide/ahci.c ++++ qemu-2.2.0/hw/ide/ahci.c +@@ -838,6 +838,7 @@ static void ncq_cb(void *opaque, int ret + ide_state->error = ABRT_ERR; + ide_state->status = READY_STAT | ERR_STAT; + ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag); ++ ncq_tfs->used = 0; + } else { + ide_state->status = READY_STAT | SEEK_STAT; + } diff --git a/meta/recipes-devtools/qemu/qemu_2.2.0.bb b/meta/recipes-devtools/qemu/qemu_2.2.0.bb index 72fda62..66e928f 100644 --- a/meta/recipes-devtools/qemu/qemu_2.2.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.2.0.bb @@ -24,6 +24,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://CVE-2015-7504.patch \ file://CVE-2015-7512.patch \ file://CVE-2015-8345.patch \ + file://CVE-2016-1568.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" SRC_URI[md5sum] = "f7a5e2da22d057eb838a91da7aff43c8" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 14/21] qemu: Security fix CVE-2015-7295 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (12 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 13/21] qemu: Security fix CVE-2016-1568 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 15/21] tzcode: update to 2016a Armin Kuster ` (7 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-7295 Qemu: net: virtio-net possible remote DoS (From OE-Core rev: 74771f8c41aaede0ddfb86983c6841bd1f1c1f0f) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../qemu/qemu/CVE-2015-7295_1.patch | 63 ++++++++++++++++++++++ .../qemu/qemu/CVE-2015-7295_2.patch | 58 ++++++++++++++++++++ .../qemu/qemu/CVE-2015-7295_3.patch | 52 ++++++++++++++++++ meta/recipes-devtools/qemu/qemu_2.2.0.bb | 3 ++ 4 files changed, 176 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7295_1.patch create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7295_2.patch create mode 100644 meta/recipes-devtools/qemu/qemu/CVE-2015-7295_3.patch diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_1.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_1.patch new file mode 100644 index 0000000..bc41c45 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_1.patch @@ -0,0 +1,63 @@ +From ce317461573bac12b10d67699b4ddf1f97cf066c Mon Sep 17 00:00:00 2001 +From: Jason Wang <jasowang@redhat.com> +Date: Fri, 25 Sep 2015 13:21:28 +0800 +Subject: [PATCH] virtio: introduce virtqueue_unmap_sg() + +Factor out sg unmapping logic. This will be reused by the patch that +can discard descriptor. + +Cc: Michael S. Tsirkin <mst@redhat.com> +Cc: Andrew James <andrew.james@hpe.com> +Signed-off-by: Jason Wang <jasowang@redhat.com> +Reviewed-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Michael S. Tsirkin <mst@redhat.com> + +Upstream-Status: Backport + +git.qemu.org/?p=qemu.git;a=commit;h=ce317461573bac12b10d67699b4ddf1f97cf066c + +CVE: CVE-2015-7295 patch #1 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/virtio/virtio.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +Index: qemu-2.2.0/hw/virtio/virtio.c +=================================================================== +--- qemu-2.2.0.orig/hw/virtio/virtio.c ++++ qemu-2.2.0/hw/virtio/virtio.c +@@ -240,14 +240,12 @@ int virtio_queue_empty(VirtQueue *vq) + return vring_avail_idx(vq) == vq->last_avail_idx; + } + +-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, +- unsigned int len, unsigned int idx) ++static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len) + { + unsigned int offset; + int i; + +- trace_virtqueue_fill(vq, elem, len, idx); +- + offset = 0; + for (i = 0; i < elem->in_num; i++) { + size_t size = MIN(len - offset, elem->in_sg[i].iov_len); +@@ -263,6 +261,14 @@ void virtqueue_fill(VirtQueue *vq, const + cpu_physical_memory_unmap(elem->out_sg[i].iov_base, + elem->out_sg[i].iov_len, + 0, elem->out_sg[i].iov_len); ++} ++ ++void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len, unsigned int idx) ++{ ++ trace_virtqueue_fill(vq, elem, len, idx); ++ ++ virtqueue_unmap_sg(vq, elem, len); + + idx = (idx + vring_used_idx(vq)) % vq->vring.num; + diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_2.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_2.patch new file mode 100644 index 0000000..74debf4 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_2.patch @@ -0,0 +1,58 @@ +From 29b9f5efd78ae0f9cc02dd169b6e80d2c404bade Mon Sep 17 00:00:00 2001 +From: Jason Wang <jasowang@redhat.com> +Date: Fri, 25 Sep 2015 13:21:29 +0800 +Subject: [PATCH] virtio: introduce virtqueue_discard() + +This patch introduces virtqueue_discard() to discard a descriptor and +unmap the sgs. This will be used by the patch that will discard +descriptor when packet is truncated. + +Cc: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Jason Wang <jasowang@redhat.com> +Reviewed-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Michael S. Tsirkin <mst@redhat.com> +Upstream-Status: Backport + +git.qemu.org/?p=qemu.git;a=commit;h=29b9f5efd78ae0f9cc02dd169b6e80d2c404bade + +CVE: CVE-2015-7295 patch #2 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/virtio/virtio.c | 7 +++++++ + include/hw/virtio/virtio.h | 2 ++ + 2 files changed, 9 insertions(+) + +Index: qemu-2.2.0/hw/virtio/virtio.c +=================================================================== +--- qemu-2.2.0.orig/hw/virtio/virtio.c ++++ qemu-2.2.0/hw/virtio/virtio.c +@@ -263,6 +263,13 @@ static void virtqueue_unmap_sg(VirtQueue + 0, elem->out_sg[i].iov_len); + } + ++void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len) ++{ ++ vq->last_avail_idx--; ++ virtqueue_unmap_sg(vq, elem, len); ++} ++ + void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len, unsigned int idx) + { +Index: qemu-2.2.0/include/hw/virtio/virtio.h +=================================================================== +--- qemu-2.2.0.orig/include/hw/virtio/virtio.h ++++ qemu-2.2.0/include/hw/virtio/virtio.h +@@ -180,6 +180,8 @@ void virtio_del_queue(VirtIODevice *vdev + void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len); + void virtqueue_flush(VirtQueue *vq, unsigned int count); ++void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len); + void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len, unsigned int idx); + diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_3.patch b/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_3.patch new file mode 100644 index 0000000..0f69e9c --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2015-7295_3.patch @@ -0,0 +1,52 @@ +From 0cf33fb6b49a19de32859e2cdc6021334f448fb3 Mon Sep 17 00:00:00 2001 +From: Jason Wang <jasowang@redhat.com> +Date: Fri, 25 Sep 2015 13:21:30 +0800 +Subject: [PATCH] virtio-net: correctly drop truncated packets + +When packet is truncated during receiving, we drop the packets but +neither discard the descriptor nor add and signal used +descriptor. This will lead several issues: + +- sg mappings are leaked +- rx will be stalled if a lots of packets were truncated + +In order to be consistent with vhost, fix by discarding the descriptor +in this case. + +Cc: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Jason Wang <jasowang@redhat.com> +Reviewed-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Michael S. Tsirkin <mst@redhat.com> + +Upstream-Status: Backport + +git.qemu.org/?p=qemu.git;a=commit;h=0cf33fb6b49a19de32859e2cdc6021334f448fb3 + +CVE: CVE-2015-7295 patch #3 +[Yocto # 9013] + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + hw/net/virtio-net.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +Index: qemu-2.2.0/hw/net/virtio-net.c +=================================================================== +--- qemu-2.2.0.orig/hw/net/virtio-net.c ++++ qemu-2.2.0/hw/net/virtio-net.c +@@ -1070,13 +1070,7 @@ static ssize_t virtio_net_receive(NetCli + * must have consumed the complete packet. + * Otherwise, drop it. */ + if (!n->mergeable_rx_bufs && offset < size) { +-#if 0 +- error_report("virtio-net truncated non-mergeable packet: " +- "i %zd mergeable %d offset %zd, size %zd, " +- "guest hdr len %zd, host hdr len %zd", +- i, n->mergeable_rx_bufs, +- offset, size, n->guest_hdr_len, n->host_hdr_len); +-#endif ++ virtqueue_discard(q->rx_vq, &elem, total); + return size; + } + diff --git a/meta/recipes-devtools/qemu/qemu_2.2.0.bb b/meta/recipes-devtools/qemu/qemu_2.2.0.bb index 66e928f..890a9b6 100644 --- a/meta/recipes-devtools/qemu/qemu_2.2.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.2.0.bb @@ -25,6 +25,9 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://CVE-2015-7512.patch \ file://CVE-2015-8345.patch \ file://CVE-2016-1568.patch \ + file://CVE-2015-7295_1.patch \ + file://CVE-2015-7295_2.patch \ + file://CVE-2015-7295_3.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" SRC_URI[md5sum] = "f7a5e2da22d057eb838a91da7aff43c8" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 15/21] tzcode: update to 2016a 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (13 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 14/21] qemu: Security fix CVE-2015-7295 Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 16/21] tzdata: " Armin Kuster ` (6 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> Change LIC_CHKSUM_FILES to License. Some files are BSD clause 3 Changes affecting build procedure An installer can now combine leap seconds with use of the backzone file, e.g., with 'make PACKRATDATA=backzone REDO=posix_right zones'. The old 'make posix_packrat' rule is now marked as obsolescent. (Thanks to Ian Abbott for an initial implementation.) Changes affecting documentation and commentary A new file LICENSE makes it easier to see that the code and data are mostly public-domain. (Thanks to James Knight.) The three non-public-domain files now use the current (3-clause) BSD license instead of older versions of that license. tz-link.htm mentions the BDE library (thanks to Andrew Paprocki), CCTZ (thanks to Tim Parenti), TimeJones.com, and has a new section on editing tz source files (with a mention of Sublime zoneinfo, thanks to Gilmore Davidson). The Theory and asia files now mention the 2015 book "The Global Transformation of Time, 1870-1950", and cite a couple of reviews. The America/Chicago entry now documents the informal use of US central time in Fort Pierre, South Dakota. (Thanks to Rick McDermid, Matt Johnson, and Steve Jones.) (From OE-Core rev: 1ee9072e16d96f95d07ec5a1f63888ce4730d60e) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Ross Burton <ross.burton@intel.com> (cherry picked from commit b7f292b84eea202fb13730c11452ac1957e41cf0) Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> --- .../{tzcode-native_2015g.bb => tzcode-native_2016a.bb} | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) rename meta/recipes-extended/tzcode/{tzcode-native_2015g.bb => tzcode-native_2016a.bb} (40%) diff --git a/meta/recipes-extended/tzcode/tzcode-native_2015g.bb b/meta/recipes-extended/tzcode/tzcode-native_2016a.bb similarity index 40% rename from meta/recipes-extended/tzcode/tzcode-native_2015g.bb rename to meta/recipes-extended/tzcode/tzcode-native_2016a.bb index 989e24b..76f97f0 100644 --- a/meta/recipes-extended/tzcode/tzcode-native_2015g.bb +++ b/meta/recipes-extended/tzcode/tzcode-native_2016a.bb @@ -1,17 +1,17 @@ # note that we allow for us to use data later than our code version # -DESCRIPTION = "tzcode, timezone zoneinfo utils -- zic, zdump, tzselect" -LICENSE = "PD & BSD" +SUMMARY = "tzcode, timezone zoneinfo utils -- zic, zdump, tzselect" +LICENSE = "PD & BSD & BSD-3-Clause" -LIC_FILES_CHKSUM = "file://${WORKDIR}/README;md5=d0ff93a73dd5bc3c6e724bb4343760f6" +LIC_FILES_CHKSUM = "file://LICENSE;md5=76ae2becfcb9a685041c6f166b44c2c2" SRC_URI =" ftp://ftp.iana.org/tz/releases/tzcode${PV}.tar.gz;name=tzcode \ - ftp://ftp.iana.org/tz/releases/tzdata2015g.tar.gz;name=tzdata" + ftp://ftp.iana.org/tz/releases/tzdata${PV}.tar.gz;name=tzdata" -SRC_URI[tzcode.md5sum] = "a2c47d908a6426f530efb1393cf1cd06" -SRC_URI[tzcode.sha256sum] = "18e402ef24bfad2ded38643c9a7a9a580f940a729cb47d983052fc28ff0c7ec4" -SRC_URI[tzdata.md5sum] = "8d46e8b225b9a04c75f5c39636435ad6" -SRC_URI[tzdata.sha256sum] = "b923cdbf078491696b17bc8d069c74bce73fabc5774629da2f410c9b31576161" +SRC_URI[tzcode.md5sum] = "f5e0299925631da7cf82d8ce1205111d" +SRC_URI[tzcode.sha256sum] = "11ae66d59b844e8c6c81914c9dd73b666627bd7792855ba9de195eee4520c28d" +SRC_URI[tzdata.md5sum] = "0d3123eb1b453ec0620822bd65be4c42" +SRC_URI[tzdata.sha256sum] = "5efa6b324e64ef921ef700ac3273a51895f672684a30e342f68e47871c6a8cd1" S = "${WORKDIR}" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 16/21] tzdata: update to 2016a 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (14 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 15/21] tzcode: update to 2016a Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 17/21] tzdata: reinstate changes reverted in 2014c upgrade Armin Kuster ` (5 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> Changed LIC_CHKSUM_FILES to a new LICENSE file. Add BSD-3-clause to licenses Changes affecting future time stamps America/Cayman will not observe daylight saving this year after all. Revert our guess that it would. (Thanks to Matt Johnson.) Asia/Chita switches from +0800 to +0900 on 2016-03-27 at 02:00. (Thanks to Alexander Krivenyshev.) Asia/Tehran now has DST predictions for the year 2038 and later, to be March 21 00:00 to September 21 00:00. This is likely better than predicting no DST, albeit off by a day every now and then. Changes affecting past and future time stamps America/Metlakatla switched from PST all year to AKST/AKDT on 2015-11-01 at 02:00. (Thanks to Steffen Thorsen.) America/Santa_Isabel has been removed, and replaced with a backward compatibility link to America/Tijuana. Its contents were apparently based on a misreading of Mexican legislation. Changes affecting past time stamps Asia/Karachi's two transition times in 2002 were off by a minute. (Thanks to Matt Johnson.) (From OE-Core rev: 790315dbd2dcb5b2024948ef412f32d2788cb6b5) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Ross Burton <ross.burton@intel.com> (cherry picked from commit 39e231cfabda8d75906c935d2a01f37df6121b84) Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> --- .../tzdata/{tzdata_2015g.bb => tzdata_2016a.bb} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename meta/recipes-extended/tzdata/{tzdata_2015g.bb => tzdata_2016a.bb} (96%) diff --git a/meta/recipes-extended/tzdata/tzdata_2015g.bb b/meta/recipes-extended/tzdata/tzdata_2016a.bb similarity index 96% rename from meta/recipes-extended/tzdata/tzdata_2015g.bb rename to meta/recipes-extended/tzdata/tzdata_2016a.bb index 5b2afa6..6ba5f81 100644 --- a/meta/recipes-extended/tzdata/tzdata_2015g.bb +++ b/meta/recipes-extended/tzdata/tzdata_2016a.bb @@ -1,15 +1,15 @@ SUMMARY = "Timezone data" HOMEPAGE = "http://www.iana.org/time-zones" SECTION = "base" -LICENSE = "PD & BSD" -LIC_FILES_CHKSUM = "file://asia;beginline=2;endline=3;md5=996a9811747aa48db91ed239e5b355a1 \ - file://README;md5=d0ff93a73dd5bc3c6e724bb4343760f6" +LICENSE = "PD & BSD & BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=76ae2becfcb9a685041c6f166b44c2c2" + DEPENDS = "tzcode-native" SRC_URI = "ftp://ftp.iana.org/tz/releases/tzdata${PV}.tar.gz;name=tzdata" -SRC_URI[tzdata.md5sum] = "8d46e8b225b9a04c75f5c39636435ad6" -SRC_URI[tzdata.sha256sum] = "b923cdbf078491696b17bc8d069c74bce73fabc5774629da2f410c9b31576161" +SRC_URI[tzdata.md5sum] = "0d3123eb1b453ec0620822bd65be4c42" +SRC_URI[tzdata.sha256sum] = "5efa6b324e64ef921ef700ac3273a51895f672684a30e342f68e47871c6a8cd1" inherit allarch -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 17/21] tzdata: reinstate changes reverted in 2014c upgrade 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (15 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 16/21] tzdata: " Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:14 ` [PATCH 18/21] dpkg: Security fix CVE-2015-0860 Armin Kuster ` (4 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Paul Eggleton <paul.eggleton@linux.intel.com> OE-Core commit 57af3fb9662106f0a65a1b4edf83e2398be0a8f1 upgraded tzdata but also reverted a couple of changes to SUMMARY and LIC_FILES_CHKSUM. Reinstate these (with an update to the README md5 value since that has changed slightly, without any change to the licensing statements within). (From OE-Core rev: cea4f6b86129f84a99700207777929bf7e811ed6) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> --- meta/recipes-extended/tzdata/tzdata.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/meta/recipes-extended/tzdata/tzdata.inc b/meta/recipes-extended/tzdata/tzdata.inc index 25743f6..f9050dd 100644 --- a/meta/recipes-extended/tzdata/tzdata.inc +++ b/meta/recipes-extended/tzdata/tzdata.inc @@ -1,8 +1,9 @@ -DESCRIPTION = "Timezone data" +SUMMARY = "Timezone data" HOMEPAGE = "http://www.iana.org/time-zones" SECTION = "base" LICENSE = "PD & BSD" -LIC_FILES_CHKSUM = "file://asia;beginline=2;endline=3;md5=996a9811747aa48db91ed239e5b355a1" +LIC_FILES_CHKSUM = "file://asia;beginline=2;endline=3;md5=996a9811747aa48db91ed239e5b355a1 \ + file://README;md5=d0ff93a73dd5bc3c6e724bb4343760f6" DEPENDS = "tzcode-native" inherit allarch -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 18/21] dpkg: Security fix CVE-2015-0860 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (16 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 17/21] tzdata: reinstate changes reverted in 2014c upgrade Armin Kuster @ 2016-02-06 23:14 ` Armin Kuster 2016-02-06 23:15 ` [PATCH 19/21] libxml2: Security fix CVE-2015-8241 Armin Kuster ` (3 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:14 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=y, Size: 3328 bytes --] From: Armin Kuster <akuster@mvista.com> CVE-2015-0860 dpkg: stack overflows and out of bounds read (From OE-Core rev: 5aaec01acc9e5a19374a566307a425d43c887f4b) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> --- .../recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch | 53 ++++++++++++++++++++++ meta/recipes-devtools/dpkg/dpkg_1.17.21.bb | 1 + 2 files changed, 54 insertions(+) create mode 100644 meta/recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch diff --git a/meta/recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch b/meta/recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch new file mode 100644 index 0000000..2008d89 --- /dev/null +++ b/meta/recipes-devtools/dpkg/dpkg/CVE-2015-0860.patch @@ -0,0 +1,53 @@ +From f1aac7d933819569bf6f347c3c0d5a64a90bbce0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Hanno=20B=C3=B6ck?= <hanno@hboeck.de> +Date: Thu, 19 Nov 2015 20:03:10 +0100 +Subject: [PATCH] dpkg-deb: Fix off-by-one write access on ctrllenbuf variable + +This affects old format .deb packages. + +Fixes: CVE-2015-0860 +Warned-by: afl +Signed-off-by: Guillem Jover <guillem@debian.org> + +Upstream-Status: Backport + +https://anonscm.debian.org/cgit/dpkg/dpkg.git/commit/?h=wheezy&id=f1aac7d933819569bf6f347c3c0d5a64a90bbce0 + +CVE: CVE-2015-0860 + +hand merge Changelog + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + debian/changelog | 3 +++ + dpkg-deb/extract.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +Index: dpkg-1.17.21/dpkg-deb/extract.c +=================================================================== +--- dpkg-1.17.21.orig/dpkg-deb/extract.c ++++ dpkg-1.17.21/dpkg-deb/extract.c +@@ -245,7 +245,7 @@ extracthalf(const char *debar, const cha + if (errstr) + ohshit(_("archive has invalid format version: %s"), errstr); + +- r = read_line(arfd, ctrllenbuf, 1, sizeof(ctrllenbuf)); ++ r = read_line(arfd, ctrllenbuf, 1, sizeof(ctrllenbuf) - 1); + if (r < 0) + read_fail(r, debar, _("archive control member size")); + if (sscanf(ctrllenbuf, "%jd%c%d", &ctrllennum, &nlc, &dummy) != 2 || +Index: dpkg-1.17.21/ChangeLog +=================================================================== +--- dpkg-1.17.21.orig/ChangeLog ++++ dpkg-1.17.21/ChangeLog +@@ -1,3 +1,9 @@ ++[ Guillem Jover ] ++ * Fix an off-by-one write access in dpkg-deb when parsing the old format ++ .deb control member size. Thanks to Hanno Böck <hanno@hboeck.de>. ++ Fixes CVE-2015-0860. ++ ++ + commit 6fc9e281551e0d851e38249679688bbabbad5c5f + Author: Guillem Jover <guillem@debian.org> + Date: Sat Oct 25 02:24:41 2014 +0200 diff --git a/meta/recipes-devtools/dpkg/dpkg_1.17.21.bb b/meta/recipes-devtools/dpkg/dpkg_1.17.21.bb index 7adb2b2..9133d91 100644 --- a/meta/recipes-devtools/dpkg/dpkg_1.17.21.bb +++ b/meta/recipes-devtools/dpkg/dpkg_1.17.21.bb @@ -14,6 +14,7 @@ SRC_URI += "file://noman.patch \ file://no-vla-warning.patch \ file://add_armeb_triplet_entry.patch \ file://tarfix.patch \ + file://CVE-2015-0860.patch \ " SRC_URI[md5sum] = "765a96fd0180196613bbfa3c4aef0775" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 19/21] libxml2: Security fix CVE-2015-8241 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (17 preceding siblings ...) 2016-02-06 23:14 ` [PATCH 18/21] dpkg: Security fix CVE-2015-0860 Armin Kuster @ 2016-02-06 23:15 ` Armin Kuster 2016-02-06 23:15 ` [PATCH 20/21] libxml2: Security fix CVE-2015-8710 Armin Kuster ` (2 subsequent siblings) 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:15 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-8241 libxml2: Buffer overread with XML parser in xmlNextChar (From OE-Core rev: f3c19a39cdec435f26a7f46a3432231ba4daa19c) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> --- meta/recipes-core/libxml/libxml2.inc | 1 + .../libxml/libxml2/CVE-2015-8241.patch | 40 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2015-8241.patch diff --git a/meta/recipes-core/libxml/libxml2.inc b/meta/recipes-core/libxml/libxml2.inc index 4f2034e..01d6bbe 100644 --- a/meta/recipes-core/libxml/libxml2.inc +++ b/meta/recipes-core/libxml/libxml2.inc @@ -37,6 +37,7 @@ SRC_URI = "ftp://xmlsoft.org/libxml2/libxml2-${PV}.tar.gz;name=libtar \ file://0001-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch \ file://0001-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch \ file://0001-CVE-2015-5312-Another-entity-expansion-issue.patch \ + file://CVE-2015-8241.patch \ " BINCONFIG = "${bindir}/xml2-config" diff --git a/meta/recipes-core/libxml/libxml2/CVE-2015-8241.patch b/meta/recipes-core/libxml/libxml2/CVE-2015-8241.patch new file mode 100644 index 0000000..89a46ad --- /dev/null +++ b/meta/recipes-core/libxml/libxml2/CVE-2015-8241.patch @@ -0,0 +1,40 @@ +From ab2b9a93ff19cedde7befbf2fcc48c6e352b6cbe Mon Sep 17 00:00:00 2001 +From: Hugh Davenport <hugh@allthethings.co.nz> +Date: Tue, 3 Nov 2015 20:40:49 +0800 +Subject: [PATCH] Avoid extra processing of MarkupDecl when EOF + +For https://bugzilla.gnome.org/show_bug.cgi?id=756263 + +One place where ctxt->instate == XML_PARSER_EOF whic was set up +by entity detection issues doesn't get noticed, and even overrided + +Upstream-status: Backport + +https://git.gnome.org/browse/libxml2/commit/?id=ab2b9a93ff19cedde7befbf2fcc48c6e352b6cbe + +CVE: CVE-2015-8241 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + parser.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: libxml2-2.9.2/parser.c +=================================================================== +--- libxml2-2.9.2.orig/parser.c ++++ libxml2-2.9.2/parser.c +@@ -6999,6 +6999,14 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt + xmlParsePI(ctxt); + } + } ++ ++ /* ++ * detect requirement to exit there and act accordingly ++ * and avoid having instate overriden later on ++ */ ++ if (ctxt->instate == XML_PARSER_EOF) ++ return; ++ + /* + * This is only for internal subset. On external entities, + * the replacement is done before parsing stage -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 20/21] libxml2: Security fix CVE-2015-8710 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (18 preceding siblings ...) 2016-02-06 23:15 ` [PATCH 19/21] libxml2: Security fix CVE-2015-8241 Armin Kuster @ 2016-02-06 23:15 ` Armin Kuster 2016-02-06 23:15 ` [PATCH 21/21] bind: Security fix CVE-2015-8704 Armin Kuster 2016-02-08 15:29 ` [PATCH 00/21][Fido v3] pull request Joshua G Lock 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:15 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-8710 libxml2: out-of-bounds memory access when parsing an unclosed HTML comment (From OE-Core rev: 03d481070ebc6f9af799aec5d038871f9c73901c) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> --- meta/recipes-core/libxml/libxml2.inc | 1 + .../libxml/libxml2/CVE-2015-8710.patch | 71 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2015-8710.patch diff --git a/meta/recipes-core/libxml/libxml2.inc b/meta/recipes-core/libxml/libxml2.inc index 01d6bbe..2748b4f 100644 --- a/meta/recipes-core/libxml/libxml2.inc +++ b/meta/recipes-core/libxml/libxml2.inc @@ -38,6 +38,7 @@ SRC_URI = "ftp://xmlsoft.org/libxml2/libxml2-${PV}.tar.gz;name=libtar \ file://0001-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch \ file://0001-CVE-2015-5312-Another-entity-expansion-issue.patch \ file://CVE-2015-8241.patch \ + file://CVE-2015-8710.patch \ " BINCONFIG = "${bindir}/xml2-config" diff --git a/meta/recipes-core/libxml/libxml2/CVE-2015-8710.patch b/meta/recipes-core/libxml/libxml2/CVE-2015-8710.patch new file mode 100644 index 0000000..be06cc2 --- /dev/null +++ b/meta/recipes-core/libxml/libxml2/CVE-2015-8710.patch @@ -0,0 +1,71 @@ +From e724879d964d774df9b7969fc846605aa1bac54c Mon Sep 17 00:00:00 2001 +From: Daniel Veillard <veillard@redhat.com> +Date: Fri, 30 Oct 2015 21:14:55 +0800 +Subject: [PATCH] Fix parsing short unclosed comment uninitialized access + +For https://bugzilla.gnome.org/show_bug.cgi?id=746048 +The HTML parser was too optimistic when processing comments and +didn't check for the end of the stream on the first 2 characters + +Upstream-Status: Backport + +https://git.gnome.org/browse/libxml2/commit/?id=e724879d964d774df9b7969fc846605aa1bac54c + +CVE: CVE-2015-8710 + +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + HTMLparser.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +Index: libxml2-2.9.2/HTMLparser.c +=================================================================== +--- libxml2-2.9.2.orig/HTMLparser.c ++++ libxml2-2.9.2/HTMLparser.c +@@ -3245,12 +3245,17 @@ htmlParseComment(htmlParserCtxtPtr ctxt) + ctxt->instate = state; + return; + } ++ len = 0; ++ buf[len] = 0; + q = CUR_CHAR(ql); ++ if (!IS_CHAR(q)) ++ goto unfinished; + NEXTL(ql); + r = CUR_CHAR(rl); ++ if (!IS_CHAR(r)) ++ goto unfinished; + NEXTL(rl); + cur = CUR_CHAR(l); +- len = 0; + while (IS_CHAR(cur) && + ((cur != '>') || + (r != '-') || (q != '-'))) { +@@ -3281,18 +3286,20 @@ htmlParseComment(htmlParserCtxtPtr ctxt) + } + } + buf[len] = 0; +- if (!IS_CHAR(cur)) { +- htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, +- "Comment not terminated \n<!--%.50s\n", buf, NULL); +- xmlFree(buf); +- } else { ++ if (IS_CHAR(cur)) { + NEXT; + if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) && + (!ctxt->disableSAX)) + ctxt->sax->comment(ctxt->userData, buf); + xmlFree(buf); ++ ctxt->instate = state; ++ return; + } +- ctxt->instate = state; ++ ++unfinished: ++ htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, ++ "Comment not terminated \n<!--%.50s\n", buf, NULL); ++ xmlFree(buf); + } + + /** -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 21/21] bind: Security fix CVE-2015-8704 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (19 preceding siblings ...) 2016-02-06 23:15 ` [PATCH 20/21] libxml2: Security fix CVE-2015-8710 Armin Kuster @ 2016-02-06 23:15 ` Armin Kuster 2016-02-08 15:29 ` [PATCH 00/21][Fido v3] pull request Joshua G Lock 21 siblings, 0 replies; 23+ messages in thread From: Armin Kuster @ 2016-02-06 23:15 UTC (permalink / raw) To: openembedded-core, joshua.g.lock, akuster808 From: Armin Kuster <akuster@mvista.com> CVE-2015-8704 bind: specific APL data could trigger an INSIST in apl_42.c Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../bind/bind/CVE-2015-8704.patch | 29 ++++++++++++++++++++++ meta/recipes-connectivity/bind/bind_9.9.5.bb | 1 + 2 files changed, 30 insertions(+) create mode 100644 meta/recipes-connectivity/bind/bind/CVE-2015-8704.patch diff --git a/meta/recipes-connectivity/bind/bind/CVE-2015-8704.patch b/meta/recipes-connectivity/bind/bind/CVE-2015-8704.patch new file mode 100644 index 0000000..7f28e44 --- /dev/null +++ b/meta/recipes-connectivity/bind/bind/CVE-2015-8704.patch @@ -0,0 +1,29 @@ +Upstream-Status: Backport + +https://bugzilla.redhat.com/attachment.cgi?id=1115781 + +CVE: CVE-2015-8704 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +Index: bind-9.9.5/lib/dns/rdata/in_1/apl_42.c +=================================================================== +--- bind-9.9.5.orig/lib/dns/rdata/in_1/apl_42.c ++++ bind-9.9.5/lib/dns/rdata/in_1/apl_42.c +@@ -116,7 +116,7 @@ totext_in_apl(ARGS_TOTEXT) { + isc_uint8_t len; + isc_boolean_t neg; + unsigned char buf[16]; +- char txt[sizeof(" !64000")]; ++ char txt[sizeof(" !64000:")]; + const char *sep = ""; + int n; + +@@ -140,7 +140,7 @@ totext_in_apl(ARGS_TOTEXT) { + isc_region_consume(&sr, 1); + INSIST(len <= sr.length); + n = snprintf(txt, sizeof(txt), "%s%s%u:", sep, +- neg ? "!": "", afi); ++ neg ? "!" : "", afi); + INSIST(n < (int)sizeof(txt)); + RETERR(str_totext(txt, target)); + switch (afi) { diff --git a/meta/recipes-connectivity/bind/bind_9.9.5.bb b/meta/recipes-connectivity/bind/bind_9.9.5.bb index 79b0397..a904d6e 100644 --- a/meta/recipes-connectivity/bind/bind_9.9.5.bb +++ b/meta/recipes-connectivity/bind/bind_9.9.5.bb @@ -26,6 +26,7 @@ SRC_URI = "ftp://ftp.isc.org/isc/bind9/${PV}/${BPN}-${PV}.tar.gz \ file://CVE-2015-4620.patch \ file://CVE-2015-5722.patch \ file://CVE-2015-8000.patch \ + file://CVE-2015-8704.patch \ " SRC_URI[md5sum] = "e676c65cad5234617ee22f48e328c24e" -- 2.3.5 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 00/21][Fido v3] pull request 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster ` (20 preceding siblings ...) 2016-02-06 23:15 ` [PATCH 21/21] bind: Security fix CVE-2015-8704 Armin Kuster @ 2016-02-08 15:29 ` Joshua G Lock 21 siblings, 0 replies; 23+ messages in thread From: Joshua G Lock @ 2016-02-08 15:29 UTC (permalink / raw) To: openembedded-core On Sat, 2016-02-06 at 15:14 -0800, Armin Kuster wrote: > From: Armin Kuster <akuster@mvista.com> > > forgot to append a change to bind recipe. > > This includes a miss fire on the glibc request plus many others. > This supersedes the last tow fido pull request I've included those which weren't already present in my joshuagl/fido- next branch. Per Richard's request we need to document which patches are and aren't applicable to Jethro/master and why. Can I help with that? Regards, Joshua ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2016-02-08 15:29 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-02-06 23:14 [PATCH 00/21][Fido v3] pull request Armin Kuster 2016-02-06 23:14 ` [PATCH 01/21] glibc: CVE-2015-8777 Armin Kuster 2016-02-06 23:14 ` [PATCH 02/21] glibc: CVE-2015-8779 Armin Kuster 2016-02-06 23:14 ` [PATCH 03/21] glibc: CVE-2015-9761 Armin Kuster 2016-02-06 23:14 ` [PATCH 04/21] glibc: CVE-2015-8776 Armin Kuster 2016-02-06 23:14 ` [PATCH 05/21] openssl: Security fix CVE-2015-3197 Armin Kuster 2016-02-06 23:14 ` [PATCH 06/21] openssl: Security fix CVE-2016-0701 Armin Kuster 2016-02-06 23:14 ` [PATCH 07/21] subversion: fix CVE-2015-3184 Armin Kuster 2016-02-06 23:14 ` [PATCH 08/21] subversion: fix CVE-2015-3187 Armin Kuster 2016-02-06 23:14 ` [PATCH 09/21] qemu: Security fix CVE-2015-8504 Armin Kuster 2016-02-06 23:14 ` [PATCH 10/21] qemu: Security fix CVE-2015-7504 Armin Kuster 2016-02-06 23:14 ` [PATCH 11/21] qemu: Security fix CVE-2015-7512 Armin Kuster 2016-02-06 23:14 ` [PATCH 12/21] qemu: Security fix CVE-2015-8345 Armin Kuster 2016-02-06 23:14 ` [PATCH 13/21] qemu: Security fix CVE-2016-1568 Armin Kuster 2016-02-06 23:14 ` [PATCH 14/21] qemu: Security fix CVE-2015-7295 Armin Kuster 2016-02-06 23:14 ` [PATCH 15/21] tzcode: update to 2016a Armin Kuster 2016-02-06 23:14 ` [PATCH 16/21] tzdata: " Armin Kuster 2016-02-06 23:14 ` [PATCH 17/21] tzdata: reinstate changes reverted in 2014c upgrade Armin Kuster 2016-02-06 23:14 ` [PATCH 18/21] dpkg: Security fix CVE-2015-0860 Armin Kuster 2016-02-06 23:15 ` [PATCH 19/21] libxml2: Security fix CVE-2015-8241 Armin Kuster 2016-02-06 23:15 ` [PATCH 20/21] libxml2: Security fix CVE-2015-8710 Armin Kuster 2016-02-06 23:15 ` [PATCH 21/21] bind: Security fix CVE-2015-8704 Armin Kuster 2016-02-08 15:29 ` [PATCH 00/21][Fido v3] pull request Joshua G Lock
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox