test_write_disk_secure744.c revision 306941
1139823Simp/*- 211819Sjulian * Copyright (c) 2003-2007,2016 Tim Kientzle 311819Sjulian * All rights reserved. 411819Sjulian * 511819Sjulian * Redistribution and use in source and binary forms, with or without 611819Sjulian * modification, are permitted provided that the following conditions 711819Sjulian * are met: 811819Sjulian * 1. Redistributions of source code must retain the above copyright 911819Sjulian * notice, this list of conditions and the following disclaimer. 1011819Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1111819Sjulian * notice, this list of conditions and the following disclaimer in the 1211819Sjulian * documentation and/or other materials provided with the distribution. 13165899Srwatson * 14165899Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15165899Srwatson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16165899Srwatson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17165899Srwatson * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18165899Srwatson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19165899Srwatson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20165899Srwatson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21165899Srwatson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22165899Srwatson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23165899Srwatson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24165899Srwatson */ 25165899Srwatson#include "test.h" 26165899Srwatson__FBSDID("$FreeBSD: releng/10.3/contrib/libarchive/libarchive/test/test_write_disk_secure744.c 306941 2016-10-10 07:18:54Z delphij $"); 27165899Srwatson 28165899Srwatson#define UMASK 022 29165899Srwatson 30165899Srwatson/* 31165899Srwatson * Github Issue #744 describes a bug in the sandboxing code that 32165899Srwatson * causes very long pathnames to not get checked for symlinks. 33165899Srwatson */ 34165899Srwatson 35165899SrwatsonDEFINE_TEST(test_write_disk_secure744) 36165899Srwatson{ 37165899Srwatson#if defined(_WIN32) && !defined(__CYGWIN__) 38165899Srwatson skipping("archive_write_disk security checks not supported on Windows"); 3911819Sjulian#else 4011819Sjulian struct archive *a; 4111819Sjulian struct archive_entry *ae; 4211819Sjulian size_t buff_size = 8192; 4311819Sjulian char *buff = malloc(buff_size); 4411819Sjulian char *p = buff; 4511819Sjulian int n = 0; 4611819Sjulian int t; 4711819Sjulian 4811819Sjulian assert(buff != NULL); 4911819Sjulian 5011819Sjulian /* Start with a known umask. */ 5111819Sjulian assertUmask(UMASK); 5211819Sjulian 5311819Sjulian /* Create an archive_write_disk object. */ 5411819Sjulian assert((a = archive_write_disk_new()) != NULL); 5511819Sjulian archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); 5611819Sjulian 5711819Sjulian while (p + 500 < buff + buff_size) { 5811819Sjulian memset(p, 'x', 100); 5912057Sjulian p += 100; 6011819Sjulian p[0] = '\0'; 6111819Sjulian 62116189Sobrien buff[0] = ((n / 1000) % 10) + '0'; 63116189Sobrien buff[1] = ((n / 100) % 10)+ '0'; 64116189Sobrien buff[2] = ((n / 10) % 10)+ '0'; 6511819Sjulian buff[3] = ((n / 1) % 10)+ '0'; 6611819Sjulian buff[4] = '_'; 6750519Sjhay ++n; 6811819Sjulian 6950519Sjhay /* Create a symlink pointing to the testworkdir */ 7025652Sjhay assert((ae = archive_entry_new()) != NULL); 7111991Sjulian archive_entry_copy_pathname(ae, buff); 7211819Sjulian archive_entry_set_mode(ae, S_IFREG | 0777); 7350519Sjhay archive_entry_copy_symlink(ae, testworkdir); 7411819Sjulian assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 7511819Sjulian archive_entry_free(ae); 76169463Srwatson 77169463Srwatson *p++ = '/'; 7850519Sjhay sprintf(p, "target%d", n); 79132779Skan 8050519Sjhay /* Try to create a file through the symlink, should fail. */ 8150519Sjhay assert((ae = archive_entry_new()) != NULL); 8250519Sjhay archive_entry_copy_pathname(ae, buff); 8311819Sjulian archive_entry_set_mode(ae, S_IFDIR | 0777); 8450519Sjhay 8550519Sjhay t = archive_write_header(a, ae); 8650519Sjhay archive_entry_free(ae); 8711819Sjulian failure("Attempt to create target%d via %d-character symlink should have failed", n, (int)strlen(buff)); 8850519Sjhay if(!assertEqualInt(ARCHIVE_FAILED, t)) { 8950519Sjhay break; 9050519Sjhay } 91132779Skan } 9250519Sjhay archive_free(a); 9350519Sjhay free(buff); 9450519Sjhay#endif 9550519Sjhay} 9650519Sjhay/*- 9750519Sjhay * Copyright (c) 2003-2007,2016 Tim Kientzle 9850519Sjhay * All rights reserved. 9950519Sjhay * 10050519Sjhay * Redistribution and use in source and binary forms, with or without 10150519Sjhay * modification, are permitted provided that the following conditions 10250519Sjhay * are met: 10350519Sjhay * 1. Redistributions of source code must retain the above copyright 10450519Sjhay * notice, this list of conditions and the following disclaimer. 10511819Sjulian * 2. Redistributions in binary form must reproduce the above copyright 10650519Sjhay * notice, this list of conditions and the following disclaimer in the 10750519Sjhay * documentation and/or other materials provided with the distribution. 10850519Sjhay * 10950519Sjhay * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 11050519Sjhay * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 11150519Sjhay * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 112132779Skan * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 11350519Sjhay * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 11450519Sjhay * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 11550519Sjhay * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 11650519Sjhay * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 11750519Sjhay * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 11811819Sjulian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11950519Sjhay */ 12050519Sjhay#include "test.h" 12150519Sjhay__FBSDID("$FreeBSD: releng/10.3/contrib/libarchive/libarchive/test/test_write_disk_secure744.c 306941 2016-10-10 07:18:54Z delphij $"); 122132779Skan 12350519Sjhay#define UMASK 022 124132779Skan 12550519Sjhay/* 126132779Skan * Github Issue #744 describes a bug in the sandboxing code that 12750519Sjhay * causes very long pathnames to not get checked for symlinks. 12850519Sjhay */ 129139584Srwatson 13011819SjulianDEFINE_TEST(test_write_disk_secure744) 13150519Sjhay{ 13250519Sjhay#if defined(_WIN32) && !defined(__CYGWIN__) 13350519Sjhay skipping("archive_write_disk security checks not supported on Windows"); 13450519Sjhay#else 13550519Sjhay struct archive *a; 13650519Sjhay struct archive_entry *ae; 13750519Sjhay size_t buff_size = 8192; 13850519Sjhay char *buff = malloc(buff_size); 13911819Sjulian char *p = buff; 14011819Sjulian int n = 0; 141 int t; 142 143 assert(buff != NULL); 144 145 /* Start with a known umask. */ 146 assertUmask(UMASK); 147 148 /* Create an archive_write_disk object. */ 149 assert((a = archive_write_disk_new()) != NULL); 150 archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); 151 152 while (p + 500 < buff + buff_size) { 153 memset(p, 'x', 100); 154 p += 100; 155 p[0] = '\0'; 156 157 buff[0] = ((n / 1000) % 10) + '0'; 158 buff[1] = ((n / 100) % 10)+ '0'; 159 buff[2] = ((n / 10) % 10)+ '0'; 160 buff[3] = ((n / 1) % 10)+ '0'; 161 buff[4] = '_'; 162 ++n; 163 164 /* Create a symlink pointing to the testworkdir */ 165 assert((ae = archive_entry_new()) != NULL); 166 archive_entry_copy_pathname(ae, buff); 167 archive_entry_set_mode(ae, S_IFREG | 0777); 168 archive_entry_copy_symlink(ae, testworkdir); 169 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 170 archive_entry_free(ae); 171 172 *p++ = '/'; 173 sprintf(p, "target%d", n); 174 175 /* Try to create a file through the symlink, should fail. */ 176 assert((ae = archive_entry_new()) != NULL); 177 archive_entry_copy_pathname(ae, buff); 178 archive_entry_set_mode(ae, S_IFDIR | 0777); 179 180 t = archive_write_header(a, ae); 181 archive_entry_free(ae); 182 failure("Attempt to create target%d via %d-character symlink should have failed", n, (int)strlen(buff)); 183 if(!assertEqualInt(ARCHIVE_FAILED, t)) { 184 break; 185 } 186 } 187 archive_free(a); 188 free(buff); 189#endif 190} 191