]> git.saurik.com Git - apple/libsecurity_codesigning.git/commitdiff
libsecurity_codesigning-36591.tar.gz mac-os-x-1057 v36591
authorApple <opensource@apple.com>
Tue, 17 Mar 2009 23:56:37 +0000 (23:56 +0000)
committerApple <opensource@apple.com>
Tue, 17 Mar 2009 23:56:37 +0000 (23:56 +0000)
lib/CSCommon.h
lib/csgeneric.cpp
lib/filediskrep.cpp
lib/macho++.cpp
lib/macho++.h
lib/signer.cpp
lib/signerutils.cpp
libsecurity_codesigning.xcodeproj/project.pbxproj

index 5b24b602a2772e3305972ec4a5d12b0755c250c0..564165f4f95b849dde801db91d59af5b12ae53c3 100644 (file)
@@ -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 */
 };
 
 
index 0ea453e7248567dbc5a6b896fdb112041875696d..6840248380a6f41c7ec2c093f9a449e16b6e6c42 100644 (file)
@@ -65,7 +65,7 @@ SecCode *GenericCode::locateGuest(CFDictionaryRef attributes)
                CFRef<CFDataRef> 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);
                }
index 9fefe6a5575ac9d3b07577f5ddd5685096dd5a0b..f8a40324671828d365cb536e18959b70f030c7b8 100644 (file)
@@ -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;
+       }
 }
 
 
index 11eb33b669f3a8c502edde2bc9fa857f164caf97..012e0af04a3844082a812c88237ad85dca4c019d 100644 (file)
@@ -26,6 +26,8 @@
 //
 #include "macho++.h"
 #include <security_utilities/memutils.h>
+#include <security_utilities/endian.h>
+#include <mach/machine.h>
 
 namespace Security {
 
@@ -34,7 +36,7 @@ namespace Security {
 // Architecture values
 //
 Architecture::Architecture(const fat_arch &arch)
-       : pair<cpu_type_t, cpu_subtype_t>(ntohl(arch.cputype), ntohl(arch.cpusubtype))
+       : pair<cpu_type_t, cpu_subtype_t>(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<mach_header &>(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<mach_header &>(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;
 }
index 3c02c5fafc13ce95384fa5c7dbbf1a39c0cb4ea9..abf611865ee2e01d50b0de6ad8a1250ee568a6c4 100644 (file)
@@ -43,22 +43,30 @@ namespace Security {
 // Simply a pair or (cpu type, cpu subtype), really.
 //
 class Architecture : public std::pair<cpu_type_t, cpu_subtype_t> {
+       typedef std::pair<cpu_type_t, cpu_subtype_t> _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<cpu_type_t, cpu_subtype_t>(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<Architecture> Architectures;
        void architectures(Architectures &archs);
        
-       bool isUniversal() const { return mArchList; }
+       bool isUniversal() const { return mArchList != NULL; }
        Architecture bestNativeArch() const;
        
 public:
index 15003b3da5e3221114f8f87d54a80b49b9925e3e..9bc9c2b5df6ebf4f2e8b3a02671b65458483aa50 100644 (file)
@@ -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<CFDictionaryRef> infoDict;
index c270ed22cb7327c029b57c2af1de6d3aeebb5f41..6d3bc155364d343046ce683eddeec559c33c6c6e 100644 (file)
@@ -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
index 90450ad1ce9ad47ff76088b06a8b4c37da09d11a..1b01a287028af96d3a17290443edf88fc6382de1 100644 (file)
                        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,
                                        normal,
                                        debug,
                                );
-                               CURRENT_PROJECT_VERSION = 33803;
+                               CURRENT_PROJECT_VERSION = 36591;
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,
                                        normal,
                                        debug,
                                );
-                               CURRENT_PROJECT_VERSION = 33803;
+                               CURRENT_PROJECT_VERSION = 36591;
                                FRAMEWORK_SEARCH_PATHS = (
                                        /usr/local/SecurityPieces/Frameworks,
                                        /usr/local/SecurityPieces/Components/Security,