Changeset 96757 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Sep 16, 2022 12:41:19 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 153645
- Location:
- trunk/src/VBox/Runtime/common/ldr
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/ldr/ldrELF.cpp
r96407 r96757 43 43 #include "internal/iprt.h" 44 44 45 #include <iprt/alloc.h> 45 #include <iprt/alloca.h> 46 #include <iprt/asm.h> 46 47 #include <iprt/assert.h> 47 48 #include <iprt/dbg.h> 48 49 #include <iprt/string.h> 49 50 #include <iprt/log.h> 51 #include <iprt/mem.h> 50 52 #include <iprt/err.h> 53 #include <iprt/crypto/digest.h> 51 54 #include <iprt/formats/elf32.h> 52 55 #include <iprt/formats/elf64.h> … … 69 72 70 73 74 /********************************************************************************************************************************* 75 * Structures and Typedefs * 76 *********************************************************************************************************************************/ 77 /** Magic string for RTLDRLNXMODSIG::achMagic */ 78 #define RTLDRLNXMODSIG_MAGIC "~Module signature appended~\n" 79 AssertCompile(sizeof(RTLDRLNXMODSIG_MAGIC) == 29); 80 81 /** 82 * Linux kernel module signature footer - found at the end of the file. 83 */ 84 typedef struct RTLDRLNXMODSIG 85 { 86 /** Zero. */ 87 uint8_t bAlgo; 88 /** Zero. */ 89 uint8_t bHash; 90 /** Signature type (RTLDRLNXMODSIG_TYPE_PKCS7). */ 91 uint8_t bType; 92 /** Zero. */ 93 uint8_t cbSignerName; 94 /** Zero. */ 95 uint8_t cbKeyId; 96 /** Zero padding. */ 97 uint8_t abReserved[3]; 98 /** The length of the signature preceeding this footer structure. */ 99 uint32_t cbSignature; 100 /** Magic value identifying this structure. */ 101 char achMagic[sizeof(RTLDRLNXMODSIG_MAGIC) - 1]; 102 } RTLDRLNXMODSIG; 103 typedef RTLDRLNXMODSIG *PRTLDRLNXMODSIG; 104 typedef RTLDRLNXMODSIG const *PCRTLDRLNXMODSIG; 105 /** Signature type. */ 106 #define RTLDRLNXMODSIG_TYPE_PKCS7 2 107 108 71 109 72 110 /********************************************************************************************************************************* 73 111 * Internal Functions * 74 112 *********************************************************************************************************************************/ 113 static int rtLdrELFLnxKModQueryPropIsSigned(PRTLDRREADER pReader, bool *pfRet); 114 static int rtLdrELFLnxKModQueryPropPkcs7SignedData(PRTLDRREADER pReader, void *pvBuf, size_t cbBuf, size_t *pcbRet); 115 static DECLCALLBACK(int) rtldrELFLnxKModHashImage(PRTLDRMODINTERNAL pMod, RTDIGESTTYPE enmDigest, uint8_t *pabHash, size_t cbHash); 75 116 #ifdef LOG_ENABLED 76 117 static const char *rtldrElfGetShdrType(uint32_t iType); … … 152 193 #endif /* LOG_ENABLED*/ 153 194 195 /** 196 * Reads in what migt be a linux kernel module signature footer. 197 */ 198 static int rtLdrELFLnxKModReadFooter(PRTLDRREADER pReader, PRTLDRLNXMODSIG pSigFooter, uint64_t *pcbFile) 199 { 200 /* 201 * Look for the linux module signature at the end of the file. 202 * This should be safe to read w/o any size checking as it is smaller than the elf header. 203 */ 204 uint64_t cbFile = pReader->pfnSize(pReader); 205 *pcbFile = cbFile; 206 207 AssertCompile(sizeof(*pSigFooter) <= sizeof(Elf32_Ehdr)); 208 return pReader->pfnRead(pReader, pSigFooter, sizeof(*pSigFooter), cbFile - sizeof(*pSigFooter)); 209 } 210 211 212 /** 213 * Check that a linux kernel module signature footer is valid. 214 */ 215 static bool rtLdrELFLnxKModIsFooterValid(PCRTLDRLNXMODSIG pSigFooter, uint64_t cbFile) 216 { 217 if (memcmp(pSigFooter->achMagic, RTLDRLNXMODSIG_MAGIC, sizeof(pSigFooter->achMagic)) == 0) 218 { 219 uint32_t const cbSignature = RT_N2H_U32(pSigFooter->cbSignature); 220 if (cbSignature > 32 && cbSignature + sizeof(*pSigFooter) < cbFile) 221 return pSigFooter->bAlgo == 0 222 && pSigFooter->bHash == 0 223 && pSigFooter->cbSignerName == 0 224 && pSigFooter->cbKeyId == 0; 225 } 226 return false; 227 } 228 229 230 /** 231 * Handles the linux kernel module signature part of RTLDRPROP_IS_SIGNED 232 * queries. 233 */ 234 static int rtLdrELFLnxKModQueryPropIsSigned(PRTLDRREADER pReader, bool *pfRet) 235 { 236 *pfRet = false; 237 AssertReturn(pReader, VERR_INVALID_STATE); 238 239 uint64_t cbFile; 240 RTLDRLNXMODSIG SigFooter; 241 int rc = rtLdrELFLnxKModReadFooter(pReader, &SigFooter, &cbFile); 242 if (RT_SUCCESS(rc)) 243 *pfRet = rtLdrELFLnxKModIsFooterValid(&SigFooter, cbFile); 244 return rc; 245 } 246 247 248 /** 249 * Handles the linux kernel module signature part of RTLDRPROP_IS_SIGNED 250 * queries. 251 */ 252 static int rtLdrELFLnxKModQueryPropPkcs7SignedData(PRTLDRREADER pReader, void *pvBuf, size_t cbBuf, size_t *pcbRet) 253 { 254 AssertReturn(pReader, VERR_INVALID_STATE); 255 256 uint64_t cbFile; 257 RTLDRLNXMODSIG SigFooter; 258 int rc = rtLdrELFLnxKModReadFooter(pReader, &SigFooter, &cbFile); 259 if (RT_SUCCESS(rc)) 260 { 261 if ( rtLdrELFLnxKModIsFooterValid(&SigFooter, cbFile) 262 && SigFooter.bType == RTLDRLNXMODSIG_TYPE_PKCS7) 263 { 264 uint32_t const cbSignature = RT_N2H_U32(SigFooter.cbSignature); 265 *pcbRet = cbSignature; 266 if (cbSignature <= cbBuf) 267 rc = pReader->pfnRead(pReader, pvBuf, cbSignature, cbFile - sizeof(SigFooter) - cbSignature); 268 else 269 rc = VERR_BUFFER_OVERFLOW; 270 } 271 else 272 rc = VERR_NOT_FOUND; 273 } 274 return rc; 275 } 276 277 278 /** 279 * @interface_method_impl{,pfnHashImage, 280 * Handles the linux kernel module signatures.} 281 */ 282 static DECLCALLBACK(int) rtldrELFLnxKModHashImage(PRTLDRMODINTERNAL pMod, RTDIGESTTYPE enmDigest, uint8_t *pabHash, size_t cbHash) 283 { 284 PRTLDRREADER pReader = pMod->pReader; 285 AssertReturn(pReader, VERR_INVALID_STATE); 286 287 /* 288 * Get the file size and subtract any linux kernel module signature from it 289 * since it's not part of the hash. 290 */ 291 uint64_t cbFile; 292 RTLDRLNXMODSIG SigFooter; 293 int rc = rtLdrELFLnxKModReadFooter(pReader, &SigFooter, &cbFile); 294 if (RT_SUCCESS(rc)) 295 { 296 if (rtLdrELFLnxKModIsFooterValid(&SigFooter, cbFile)) 297 cbFile -= sizeof(SigFooter) - RT_N2H_U32(SigFooter.cbSignature); 298 299 /* 300 * Now hash the file. 301 */ 302 RTCRDIGEST hDigest; 303 rc = RTCrDigestCreateByType(&hDigest, enmDigest); 304 if (RT_SUCCESS(rc)) 305 { 306 uint32_t cbBuf = _64K; 307 void *pvBuf = RTMemTmpAlloc(_64K); 308 void *pvBufFree = pvBuf; 309 if (!pvBuf) 310 { 311 cbBuf = _4K; 312 pvBuf = alloca(_4K); 313 } 314 315 for (uint64_t offFile = 0; offFile < cbFile; ) 316 { 317 uint64_t cbLeft = cbFile - offFile; 318 uint32_t cbToRead = cbLeft >= cbBuf ? cbBuf : (uint32_t)cbLeft; 319 rc = pReader->pfnRead(pReader, pvBuf, cbToRead, offFile); 320 AssertRCBreak(rc); 321 322 rc = RTCrDigestUpdate(hDigest, pvBuf, cbToRead); 323 offFile += cbToRead; 324 AssertRCBreak(rc); 325 } 326 327 RTMemTmpFree(pvBufFree); 328 329 if (RT_SUCCESS(rc)) 330 rc = RTCrDigestFinal(hDigest, pabHash, cbHash); 331 RTCrDigestRelease(hDigest); 332 } 333 } 334 return rc; 335 } 336 154 337 155 338 /** -
trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
r96407 r96757 1711 1711 1712 1712 1713 /** @interface_method_impl{RTLDROPS,pfnQueryProp} */ 1714 static DECLCALLBACK(int) RTLDRELF_NAME(QueryProp)(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits, 1715 void *pvBuf, size_t cbBuf, size_t *pcbRet) 1716 { 1717 PRTLDRMODELF pThis = (PRTLDRMODELF)pMod; 1718 1719 if (enmProp != RTLDRPROP_BUILDID) 1720 return VERR_NOT_FOUND; 1721 1713 /** 1714 * Handles RTLDRPROP_BUILDID queries. 1715 */ 1716 static int RTLDRELF_NAME(QueryPropBuildId)(PRTLDRMODELF pThis, void *pvBuf, size_t cbBuf, size_t *pcbRet) 1717 { 1722 1718 /* 1723 1719 * Map the image bits if not already done and setup pointer into it. … … 1761 1757 } 1762 1758 1763 NOREF(cbBuf);1764 RT_NOREF_PV(pvBits);1765 1759 return VERR_NOT_FOUND; 1760 } 1761 1762 1763 /** @interface_method_impl{RTLDROPS,pfnQueryProp} */ 1764 static DECLCALLBACK(int) RTLDRELF_NAME(QueryProp)(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits, 1765 void *pvBuf, size_t cbBuf, size_t *pcbRet) 1766 { 1767 PRTLDRMODELF pThis = (PRTLDRMODELF)pMod; 1768 RT_NOREF(pvBits); 1769 switch (enmProp) 1770 { 1771 case RTLDRPROP_BUILDID: 1772 return RTLDRELF_NAME(QueryPropBuildId)(pThis, pvBuf, cbBuf, pcbRet); 1773 1774 case RTLDRPROP_IS_SIGNED: 1775 *pcbRet = sizeof(bool); 1776 return rtLdrELFLnxKModQueryPropIsSigned(pThis->Core.pReader, (bool *)pvBuf); 1777 1778 case RTLDRPROP_PKCS7_SIGNED_DATA: 1779 *pcbRet = sizeof(bool); 1780 return rtLdrELFLnxKModQueryPropPkcs7SignedData(pThis->Core.pReader, pvBuf, cbBuf, pcbRet); 1781 1782 default: 1783 return VERR_NOT_FOUND; 1784 } 1766 1785 } 1767 1786 … … 1877 1896 RTLDRELF_NAME(QueryProp), 1878 1897 NULL /*pfnVerifySignature*/, 1879 NULL /*pfnHashImage*/,1898 rtldrELFLnxKModHashImage, 1880 1899 RTLDRELF_NAME(UnwindFrame), 1881 1900 42
Note:
See TracChangeset
for help on using the changeset viewer.