Bill Garrison avatar Bill Garrison committed 4783fff

Apple modifications from the Mac OS X 10.7.0 release.

Comments (0)

Files changed (12)

xar.xcodeproj/project.pbxproj

 			isa = PBXProject;
 			buildConfigurationList = B41FC04209F6B74500006FAE /* Build configuration list for PBXProject "xar" */;
 			compatibilityVersion = "Xcode 2.4";
+			developmentRegion = English;
 			hasScannedForEncodings = 0;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+			);
 			mainGroup = B41FC03F09F6B74500006FAE;
 			productRefGroup = B41FC06009F6B7C200006FAE /* Products */;
 			projectDirPath = "";
 				ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
 				ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 36.2;
+				CURRENT_PROJECT_VERSION = 45;
 				STRIP_STYLE = debugging;
+				VALID_ARCHS = "i386 x86_64";
 				VERSIONING_SYSTEM = "apple-generic";
 			};
 			name = Development;
 				ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
 				ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
 				COPY_PHASE_STRIP = YES;
+				VALID_ARCHS = "i386 x86_64";
 			};
 			name = Release;
 		};
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				COPY_PHASE_STRIP = YES;
-				CURRENT_PROJECT_VERSION = 36.2;
+				CURRENT_PROJECT_VERSION = 45;
 				EXECUTABLE_PREFIX = lib;
 				GCC_ENABLE_FIX_AND_CONTINUE = NO;
 				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				COPY_PHASE_STRIP = YES;
-				CURRENT_PROJECT_VERSION = 36.2;
+				CURRENT_PROJECT_VERSION = 45;
 				GCC_ENABLE_FIX_AND_CONTINUE = NO;
 				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
 				GCC_MODEL_TUNING = G5;

xar/include/xar.h.in

 char *xar_get_group(xar_t x, xar_file_t f);
 char *xar_get_mtime(xar_t x, xar_file_t f);
 
+/* For helping calling apps harden against hacked archives that attempt to escape their extraction roots. */
+int xar_path_issane(char* path);
+
 /* These are for xar modules and should never be needed from a calling app */
 void xar_register_errhandler(xar_t x, err_handler callback, void *usrctx);
 xar_t xar_err_get_archive(xar_errctx_t ctx);

xar/lib/archive.c

 		rbuf = malloc(rsize);
 		if( !rbuf ) {
 			retval = -1;
+			close(fd);
+			close(tocfd);
 			goto CLOSE_BAIL;
 		}
 		zs.zalloc = Z_NULL;
 				if( 0 != sig->signer_callback( sig, sig->callback_context, chkstr, data_len, &signed_data, &signed_len ) ){
 					fprintf(stderr, "Error signing data.\n");
 					retval = -1;
+					close(fd);
+					close(tocfd);
 					goto CLOSE_BAIL;					
 				}
 				
 				if( signed_len != XAR_SIGNATURE(sig)->len ){
 					fprintf(stderr, "Signed data not the proper length.  %i should be %i.\n",signed_len,XAR_SIGNATURE(sig)->len);
 					retval = -1;
+					close(fd);
+					close(tocfd);
 					goto CLOSE_BAIL;										
 				}
 				
 					continue;
 				if( r < 0 ) {
 					retval = -1;
+					close(fd);
+					close(tocfd);
 					goto CLOSEEND;
 				}
 				off += r;
 				break;
 		}
 CLOSEEND:
+		close(fd);
+		close(tocfd);
 		free(rbuf);
 		free(wbuf);
 		deflateEnd(&XAR(x)->zs);
 #include <stdlib.h>
 #include <string.h>
 
-static unsigned char table [] = {
-'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
-'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
-'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
-'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
-'s', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2',
-'3', '4', '5', '6', '7', '8', '9', '+', '/' };
-
-unsigned char* xar_to_base64(const unsigned char* input, size_t len)
-{
-    unsigned char b6;
-    /*UNUSED unsigned char tmp; */
-    unsigned char count = 0;
-    int i=0;
-    unsigned char* output;
-    int outsize = (((float)len)*4/3)+5;
-	
-
-    output = malloc(outsize);
-    if( !output )
-        return NULL;
-
-    while(1) {
-        if( i >= len ) {
-            output[count++] = '\n';
-            output[count++] = '\0';
-            return output;
-        }
-        b6 = input[i];
-        b6 >>= 2;
-        output[count++] = table[b6];
-
-        b6 = input[i++];
-        b6 &= 0x03;
-        b6 <<= 4;
-        if( i >= len ) {
-            output[count++] = table[b6];
-            output[count++] = '=';
-            output[count++] = '=';
-            output[count++] = '\n';
-            output[count++] = '\0';
-            return output;
-        }
-        b6 |= input[i] >> 4;
-        output[count++] = table[b6];
-
-        b6 = input[i++] & 0x0F;
-        b6 <<= 2;
-        if( i >= len ) {
-            output[count++] = table[b6];
-            output[count++] = '=';
-            output[count++] = '\n';
-            output[count++] = '\0';
-            return output;
-        }
-        b6 |= input[i] >> 6;
-        output[count++] = table[b6];
-
-        b6 = input[i++] & 0x3F;
-        output[count++] = table[b6];
-    }
-}
-
 #ifdef _BTEST_
 int main(int argc, char* argv[]) {
     unsigned char* enc = benc(argv[1], strlen(argv[1]));
 #ifndef _XAR_BASE64_H_
 #define _XAR_BASE64_H_
 
-unsigned char* xar_to_base64(const unsigned char* input, size_t len);
 unsigned char* xar_from_base64(const unsigned char* input, size_t inputLength, size_t *outputLength);
 
 #endif /* _XAR_BASE64_H_ */
 	tmpp = xar_prop_pfirst(f);
 	if( tmpp )
 		tmpp = xar_prop_find(tmpp, "data");
+	
+	if (!tmpp)		// It appears that xar can have truely empty files, aka, no data. We should just fail to verify these files. 
+		return 0;	// After all, the checksum of blank is meaningless. So, failing to do so will cause a crash.
+	
 	return xar_attrcopy_from_heap(x, f, tmpp, NULL , (void *)(&context));
 }

xar/lib/filetree.c

 				if( XAR_FILE(f)->parent ) {
 					
 					if (XAR_FILE(f)->fspath) {		/* It's possible that a XAR header may contain multiple name entries. Make sure we don't smash the old one. */
-						free(XAR_FILE(f)->fspath);
+						free((void*)XAR_FILE(f)->fspath);
 						XAR_FILE(f)->fspath = NULL;
 					}
 					
 				} else {
 					
 					if (XAR_FILE(f)->fspath) {		/* It's possible that a XAR header may contain multiple name entries. Make sure we don't smash the old one. */
-						free(XAR_FILE(f)->fspath);
+						free((void*)XAR_FILE(f)->fspath);
 						XAR_FILE(f)->fspath = NULL;
 					}
 					
 	if( tmpp )
 		opt = xar_prop_getvalue(tmpp);
 	if( !opt ) {
-		wcb(x, f, NULL, 0, context);
+        if( wcb )
+            wcb(x, f, NULL, 0, context);
 		return 0;
 	} else {
 		seekoff = strtoll(opt, NULL, 0);

xar/lib/signature.c

 
 	/* <size> */
 	xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("size"), NULL);
-	xmlTextWriterWriteFormatString(writer, "%ld", (XAR_SIGNATURE(sig)->len));
+	xmlTextWriterWriteFormatString(writer, "%d", (XAR_SIGNATURE(sig)->len));
 	xmlTextWriterEndElement(writer);	
 
 	/* <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> */
 	}
 
 CREATEFILE:
+	if (!file)
+        return 0;
+	
 	unlink(file);
 	fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0600);
 	if( fd > 0 )
 	char* component = NULL;
 	int path_depth = 0;
 	
+	// Ban 0 length / absolute paths.
+	if (strlen(path) == 0 || path[0] == '/')
+		return 0;
+	
 	while (component = xar_path_nextcomponent(&path_walker)) {
 		
 		if (strlen(component) == 0 || strcmp(component, ".") == 0) { // Since // is legal, and '.' is legal it's possible to have empty path elements. Ignore them
 	return signedDataOffset;
 }
 
-static void extract_sig_offset(xar_t x, const char *filename) {
+static int extract_sig_offset(xar_t x, const char *filename) {
 	off_t signedDataOffset;
 	FILE *file;
 	int i;
 	file = fopen(filename, "w");
 	if (!file) {
 		fprintf(stderr, "Could not open %s for saving signature offset!\n", filename);
-		exit(1);
+		return 1;
 	}
 	i = fprintf(file, "%lli\n", signedDataOffset);
 	if (i < 0) {
 		fprintf(stderr, "Failed to write signature offset to %s (fprintf() returned %i)!\n", filename, i);
-		exit(1);
+		return 1;
 	}
 	fclose(file);
+	
+	return 0;
 }
 
 stack stack_new() {
 	new_xar = xar_open(new_xar_path, READ);
 	if( !new_xar ) {
 		fprintf(stderr, "Error re-opening new archive %s\n", new_xar_path);
+		unlink(new_xar_path);
 		exit(1);
 	}
-	extract_sig_offset(new_xar, SigOffsetDumpPath);
+	
+	if (extract_sig_offset(new_xar, SigOffsetDumpPath)) {
+		xar_close(new_xar);
+		unlink(new_xar_path);
+		exit(1);
+	}
+		
 	xar_close(new_xar);
 	
 	// delete old archive, move new in its place
 	err = system(systemcall);
 	if (err) {
 		fprintf(stderr, "Could not copy new archive to final location (system() returned %i)\n", err);
+		unlink(new_xar_path);
 		exit(1);
 	}
+	
+	// Delete the tmp archive
+	unlink(new_xar_path);
+	
 	free(systemcall);
 }
 
 			fprintf(stderr, "Error re-opening archive %s\n", filename);
 			exit(1);
 		}
-		extract_sig_offset(x, SigOffsetDumpPath);
+		if (extract_sig_offset(x, SigOffsetDumpPath)) 
+			exit(1);
 	}
 	
 	return Err;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.