From: Apple Date: Tue, 17 Mar 2009 23:56:37 +0000 (+0000) Subject: libsecurity_codesigning-36591.tar.gz X-Git-Tag: mac-os-x-1057^0 X-Git-Url: https://git.saurik.com/apple/libsecurity_codesigning.git/commitdiff_plain/190556d136cc6fd0f3b12757e674c9430875f586?ds=inline libsecurity_codesigning-36591.tar.gz --- diff --git a/lib/CSCommon.h b/lib/CSCommon.h index 5b24b60..564165f 100644 --- a/lib/CSCommon.h +++ b/lib/CSCommon.h @@ -78,6 +78,7 @@ enum { errSecCSHostProtocolUnrelated, /* host protocol violation - the given guest is not a guest of the given host */ errSecCSInvalidOperation, /* requested operation is not valid */ errSecCSNotSupported, /* operation not supported for this type of code */ + errSecCSCMSTooLarge, /* signature too large to embed */ }; diff --git a/lib/csgeneric.cpp b/lib/csgeneric.cpp index 0ea453e..6840248 100644 --- a/lib/csgeneric.cpp +++ b/lib/csgeneric.cpp @@ -65,7 +65,7 @@ SecCode *GenericCode::locateGuest(CFDictionaryRef attributes) CFRef attrData; void *attrPtr = NULL; size_t attrLength = 0; if (attributes) { - attrData = CFPropertyListCreateXMLData(NULL, attributes); + attrData.take(CFPropertyListCreateXMLData(NULL, attributes)); attrPtr = (void *)CFDataGetBytePtr(attrData); attrLength = CFDataGetLength(attrData); } diff --git a/lib/filediskrep.cpp b/lib/filediskrep.cpp index 9fefe6a..f8a4032 100644 --- a/lib/filediskrep.cpp +++ b/lib/filediskrep.cpp @@ -141,8 +141,14 @@ DiskRep::Writer *FileDiskRep::writer() // void FileDiskRep::Writer::component(CodeDirectory::SpecialSlot slot, CFDataRef data) { + try { fd().setAttr(attrName(CodeDirectory::canonicalSlotName(slot)), CFDataGetBytePtr(data), CFDataGetLength(data)); + } catch (const UnixError &error) { + if (error.error == ERANGE) + MacOSError::throwMe(errSecCSCMSTooLarge); + throw; + } } diff --git a/lib/macho++.cpp b/lib/macho++.cpp index 11eb33b..012e0af 100644 --- a/lib/macho++.cpp +++ b/lib/macho++.cpp @@ -26,6 +26,8 @@ // #include "macho++.h" #include +#include +#include namespace Security { @@ -34,7 +36,7 @@ namespace Security { // Architecture values // Architecture::Architecture(const fat_arch &arch) - : pair(ntohl(arch.cputype), ntohl(arch.cpusubtype)) + : pair(arch.cputype, arch.cpusubtype) { } @@ -55,18 +57,30 @@ Architecture Architecture::local() } +#define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) + // // Translate between names and numbers // +static const char *uob(char *s) { if (*s != 'a') for (char *p = s; *p; p++) *p ^= 0x77; return s; } + const char *Architecture::name() const { if (const NXArchInfo *info = NXGetArchInfoFromCpuType(cpuType(), cpuSubtype())) return info->name; else if (cpuType() == CPU_TYPE_ARM) { // work-around for non-ARM Leopard systems - if (cpuSubtype() == CPU_SUBTYPE_ARM_V6) - return "armv6"; + static char arm5[] = "\026\005\032\001B"; + static char arm6[] = "\026\005\032\001A"; + static char arm7[] = "\026\005\032\001@"; + static char arm[] = "\026\005\032"; + if (cpuSubtype() == CPU_SUBTYPE_ARM_V5TEJ) + return uob(arm5); + else if (cpuSubtype() == CPU_SUBTYPE_ARM_V6) + return uob(arm6); + else if (cpuSubtype() == CPU_SUBTYPE_ARM_V7) + return uob(arm7); else - return "arm"; + return uob(arm); } else return NULL; } @@ -265,9 +279,12 @@ CFDataRef MachO::dataAt(size_t offset, size_t size) Universal::Universal(FileDesc fd) : FileDesc(fd) { - //@@@ we could save a read by using a heuristically sized combined buffer here - fat_header header; // note how in the thin-file case, we'll reinterpret the header below - if (fd.read(&header, sizeof(header), 0) != sizeof(header)) + union { + fat_header header; // if this is a fat file + mach_header mheader; // if this is a thin file + }; + const size_t size = max(sizeof(header), sizeof(mheader)); + if (fd.read(&header, size, 0) != size) UnixError::throwMe(ENOEXEC); switch (header.magic) { case FAT_MAGIC: @@ -282,6 +299,13 @@ Universal::Universal(FileDesc fd) ::free(mArchList); UnixError::throwMe(ENOEXEC); } + for (fat_arch *arch = mArchList; arch < mArchList + mArchCount; arch++) { + n2hi(arch->cputype); + n2hi(arch->cpusubtype); + n2hi(arch->offset); + n2hi(arch->size); + n2hi(arch->align); + } secdebug("macho", "%p is a fat file with %d architectures", this, mArchCount); break; @@ -290,14 +314,14 @@ Universal::Universal(FileDesc fd) case MH_MAGIC_64: mArchList = NULL; mArchCount = 0; - mThinArch = Architecture(reinterpret_cast(header).cputype); + mThinArch = Architecture(mheader.cputype, mheader.cpusubtype); secdebug("macho", "%p is a thin file (%s)", this, mThinArch.name()); break; case MH_CIGAM: case MH_CIGAM_64: mArchList = NULL; mArchCount = 0; - mThinArch = Architecture(ntohl(reinterpret_cast(header).cputype)); + mThinArch = Architecture(flip(mheader.cputype), flip(mheader.cpusubtype)); secdebug("macho", "%p is a thin file (%s)", this, mThinArch.name()); break; default: @@ -326,7 +350,7 @@ MachO *Universal::architecture() const size_t Universal::archOffset() const { if (isUniversal()) - return ntohl(findArch(bestNativeArch())->offset); + return findArch(bestNativeArch())->offset; else return 0; } @@ -340,7 +364,7 @@ MachO *Universal::architecture(const Architecture &arch) const { if (isUniversal()) return findImage(arch); - else if (arch == mThinArch) + else if (mThinArch.matches(arch)) return new MachO(*this); else UnixError::throwMe(ENOEXEC); @@ -349,8 +373,8 @@ MachO *Universal::architecture(const Architecture &arch) const size_t Universal::archOffset(const Architecture &arch) const { if (isUniversal()) - return ntohl(findArch(arch)->offset); - else if (arch == mThinArch) + return findArch(arch)->offset; + else if (mThinArch.matches(arch)) return 0; else UnixError::throwMe(ENOEXEC); @@ -365,16 +389,27 @@ const fat_arch *Universal::findArch(const Architecture &target) const { assert(isUniversal()); const fat_arch *end = mArchList + mArchCount; + // exact match for (const fat_arch *arch = mArchList; arch < end; ++arch) - if (cpu_type_t(ntohl(arch->cputype)) == target.cpuType()) //@@@ ignoring subarch + if (arch->cputype == target.cpuType() + && arch->cpusubtype == target.cpuSubtype()) return arch; + // match for generic model of main architecture + for (const fat_arch *arch = mArchList; arch < end; ++arch) + if (arch->cputype == target.cpuType() && arch->cpusubtype == 0) + return arch; + // match for any subarchitecture of the main architeture (questionable) + for (const fat_arch *arch = mArchList; arch < end; ++arch) + if (arch->cputype == target.cpuType()) + return arch; + // no match UnixError::throwMe(ENOEXEC); // not found } MachO *Universal::findImage(const Architecture &target) const { const fat_arch *arch = findArch(target); - return new MachO(*this, ntohl(arch->offset), ntohl(arch->size)); + return new MachO(*this, arch->offset, arch->size); } @@ -387,14 +422,12 @@ MachO *Universal::findImage(const Architecture &target) const Architecture Universal::bestNativeArch() const { if (isUniversal()) { - const cpu_type_t native = Architecture::local().cpuType(); - const fat_arch *end = mArchList + mArchCount; - for (const fat_arch *arch = mArchList; arch < end; ++arch) - if (cpu_type_t(ntohl(arch->cputype)) == native) // ignoring subarch - return Architecture(native); - if (mArchCount == 1) - return Architecture(ntohl(mArchList->cputype)); - UnixError::throwMe(ENOEXEC); + // ask the NXArch API for our native architecture + const Architecture native = Architecture::local(); + if (fat_arch *match = NXFindBestFatArch(native.cpuType(), native.cpuSubtype(), mArchList, mArchCount)) + return *match; + // if the system can't figure it out, pick (arbitrarily) the first one + return mArchList[0]; } else return mThinArch; } diff --git a/lib/macho++.h b/lib/macho++.h index 3c02c5f..abf6118 100644 --- a/lib/macho++.h +++ b/lib/macho++.h @@ -43,22 +43,30 @@ namespace Security { // Simply a pair or (cpu type, cpu subtype), really. // class Architecture : public std::pair { + typedef std::pair _Pair; public: Architecture() { } - explicit Architecture(cpu_type_t type, cpu_subtype_t sub = 0) + explicit Architecture(cpu_type_t type, cpu_subtype_t sub = CPU_SUBTYPE_MULTIPLE) : std::pair(type, sub) { } Architecture(const fat_arch &archInFile); cpu_type_t cpuType() const { return this->first; } cpu_subtype_t cpuSubtype() const { return this->second; } const char *name() const; + + static const cpu_type_t none = 0; + operator bool () const { return cpuType() != none; } + bool operator ! () const { return cpuType() == none; } public: friend bool operator == (const Architecture &a1, const Architecture &a2) - { return a1.cpuType() == a2.cpuType(); } + { return _Pair(a1) == _Pair(a2); } friend bool operator < (const Architecture &a1, const Architecture &a2) - { return a1.cpuType() < a2.cpuType(); } + { return _Pair(a1) < _Pair(a2); } + + bool matches(const Architecture &templ) const + { return first == templ.first && (second == templ.second || templ.second == 0 || templ.second == CPU_SUBTYPE_MULTIPLE); } public: static Architecture local(); @@ -136,7 +144,7 @@ public: typedef std::set Architectures; void architectures(Architectures &archs); - bool isUniversal() const { return mArchList; } + bool isUniversal() const { return mArchList != NULL; } Architecture bestNativeArch() const; public: diff --git a/lib/signer.cpp b/lib/signer.cpp index 15003b3..9bc9c2b 100644 --- a/lib/signer.cpp +++ b/lib/signer.cpp @@ -47,7 +47,7 @@ namespace CodeSigning { void SecCodeSigner::Signer::sign(SecCSFlags flags) { // set up access to the subject Code - rep = code->diskRep(); + rep = code->diskRep()->base(); // get the Info.plist out of the rep for some creative defaulting CFRef infoDict; diff --git a/lib/signerutils.cpp b/lib/signerutils.cpp index c270ed2..6d3bc15 100644 --- a/lib/signerutils.cpp +++ b/lib/signerutils.cpp @@ -272,11 +272,8 @@ void MachOEditor::write(Arch &arch, EmbeddedSignatureBlob *blob) size_t signingLength = arch.source->signingLength(); secdebug("codesign", "writing architecture %s at 0x%zx (%zd of %zd)", arch.architecture.name(), offset, blob->length(), signingLength); - if (signingLength < blob->length()) { - secdebug("codesign", "trying to write %zd bytes into %zd area", - blob->length(), signingLength); - MacOSError::throwMe(errSecCSInternalError); - } + if (signingLength < blob->length()) + MacOSError::throwMe(errSecCSCMSTooLarge); arch.source->seek(offset); arch.source->writeAll(*blob); ::free(blob); // done with it diff --git a/libsecurity_codesigning.xcodeproj/project.pbxproj b/libsecurity_codesigning.xcodeproj/project.pbxproj index 90450ad..1b01a28 100644 --- a/libsecurity_codesigning.xcodeproj/project.pbxproj +++ b/libsecurity_codesigning.xcodeproj/project.pbxproj @@ -999,7 +999,7 @@ isa = XCBuildConfiguration; buildSettings = { BUILD_VARIANTS = debug; - CURRENT_PROJECT_VERSION = 33803; + CURRENT_PROJECT_VERSION = 36591; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, /usr/local/SecurityPieces/Components/Security, @@ -1049,7 +1049,7 @@ normal, debug, ); - CURRENT_PROJECT_VERSION = 33803; + CURRENT_PROJECT_VERSION = 36591; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, /usr/local/SecurityPieces/Components/Security, @@ -1097,7 +1097,7 @@ normal, debug, ); - CURRENT_PROJECT_VERSION = 33803; + CURRENT_PROJECT_VERSION = 36591; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, /usr/local/SecurityPieces/Components/Security,