1From 42e892d96e47b1f6e29844cc705e148ec4856448 Mon Sep 17 00:00:00 2001 2From: Jessica Clarke <jrtc27@jrtc27.com> 3Date: Wed, 12 Jan 2022 21:27:16 +0000 4Subject: [PATCH] Use default rather than hard-coded 8 for maximum aggregate 5 member alignment (#1378) 6 7On CHERI, and thus Arm's Morello prototype, pointers are represented as 8hardware capabilities. These capabilities are comprised of not just an 9integer address, as is the representation for traditional pointers, but 10also bounds, permissions and other metadata, plus a tag bit used as the 11validity bit, which provides fine-grained spatial and referential safety 12for C and C++ in hardware. This tag bit is not part of the data itself 13and is instead kept on the side, flowing with the capability between 14registers and the memory subsystem, and any attempt to amplify the 15privilege of or corrupt a capability clears this tag (or, in some cases, 16traps), rendering them impossible to forge; you can only create 17capabilities that are (possibly trivial) subsets of existing ones. 18 19When the capability is stored in memory, this tag bit needs to be 20preserved, which is done through the use of tagged memory. Every 21capability-sized word gains an additional non-addressable (from the 22CPU's perspective; depending on the implementation the tag bits may be 23stored in a small block of memory carved out of normal DRAM that the CPU 24is blocked from accessing) bit. This means that capabilities can only be 25stored to aligned locations; attempting to store them to unaligned 26locations will trap with an alignment fault or, if you end up using a 27memcpy call, will copy the raw bytes of the capability's representation 28but lose the tag, so when it is eventually loaded back as a capability 29and dereferenced it will fault. 30 31Since, on 64-bit architectures, our capabilities, used to implement C 32language pointers, are 128-bit quantities, this means they need 16-byte 33alignment. Currently the various #pragma pack directives, used to work 34around (extremely broken and bogus) code that includes jsoncpp in a 35context where the maximum alignment has been overridden, hard-code 8 as 36the maximum alignment to use, and so do not sufficiently align CHERI / 37Morello capabilities on 64-bit architectures. On Windows x64, the 38default is also not 8 but 16 (ARM64 is supposedly 8), so this is 39slightly dodgy to do there too, but in practice likely not an issue so 40long as you don't use any 128-bit types there. 41 42Instead of hard-coding a width, use a directive that resets the packing 43back to the default. Unfortunately, whilst GCC and Clang both accept 44using #pragma pack(push, 0) as shorthand like for any non-zero value, 45MSVC does not, so this needs to be two directives. 46--- 47 include/json/allocator.h | 3 ++- 48 include/json/json_features.h | 3 ++- 49 include/json/reader.h | 3 ++- 50 include/json/value.h | 3 ++- 51 include/json/writer.h | 3 ++- 52 5 files changed, 10 insertions(+), 5 deletions(-) 53 54diff --git a/include/json/allocator.h b/include/json/allocator.h 55index 95ef8a5..7540642 100644 56--- a/include/json/allocator.h 57+++ b/include/json/allocator.h 58@@ -9,7 +9,8 @@ 59 #include <cstring> 60 #include <memory> 61 62-#pragma pack(push, 8) 63+#pragma pack(push) 64+#pragma pack() 65 66 namespace Json { 67 template <typename T> class SecureAllocator { 68diff --git a/include/json/json_features.h b/include/json/json_features.h 69index 7c7e9f5..e4a61d6 100644 70--- a/include/json/json_features.h 71+++ b/include/json/json_features.h 72@@ -10,7 +10,8 @@ 73 #include "forwards.h" 74 #endif // if !defined(JSON_IS_AMALGAMATION) 75 76-#pragma pack(push, 8) 77+#pragma pack(push) 78+#pragma pack() 79 80 namespace Json { 81 82diff --git a/include/json/reader.h b/include/json/reader.h 83index be0d767..46975d8 100644 84--- a/include/json/reader.h 85+++ b/include/json/reader.h 86@@ -23,7 +23,8 @@ 87 #pragma warning(disable : 4251) 88 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 89 90-#pragma pack(push, 8) 91+#pragma pack(push) 92+#pragma pack() 93 94 namespace Json { 95 96diff --git a/include/json/value.h b/include/json/value.h 97index 0edeb05..57ecb13 100644 98--- a/include/json/value.h 99+++ b/include/json/value.h 100@@ -53,7 +53,8 @@ 101 #pragma warning(disable : 4251 4275) 102 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 103 104-#pragma pack(push, 8) 105+#pragma pack(push) 106+#pragma pack() 107 108 /** \brief JSON (JavaScript Object Notation). 109 */ 110diff --git a/include/json/writer.h b/include/json/writer.h 111index 03f9906..7d8cf4d 100644 112--- a/include/json/writer.h 113+++ b/include/json/writer.h 114@@ -20,7 +20,8 @@ 115 #pragma warning(disable : 4251) 116 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 117 118-#pragma pack(push, 8) 119+#pragma pack(push) 120+#pragma pack() 121 122 namespace Json { 123 124-- 1252.42.0.windows.2 126 127