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