-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathU-Boot and memory permissions.html
More file actions
executable file
·271 lines (219 loc) · 23.7 KB
/
U-Boot and memory permissions.html
File metadata and controls
executable file
·271 lines (219 loc) · 23.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="" />
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,700;1,400&family=Source+Sans+Pro:ital,wght@0,300;0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://apalos.github.io/theme/stylesheet/style.min.css">
<link id="pygments-light-theme" rel="stylesheet" type="text/css"
href="https://apalos.github.io/theme/pygments/github.min.css">
<link rel="stylesheet" type="text/css" href="https://apalos.github.io/theme/font-awesome/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="https://apalos.github.io/theme/font-awesome/css/brands.css">
<link rel="stylesheet" type="text/css" href="https://apalos.github.io/theme/font-awesome/css/solid.css">
<meta name="author" content="Ilias Apalodimas" />
<meta name="description" content="U-Boot, in most of the supported architectures, relocates itself on top of DRAM but leaves the memory as RWX Arm64 is a notable exception" />
<meta name="keywords" content="Bootloaders, Security, U-Boot, UEFI">
<meta property="og:site_name" content="Volatile rumblings"/>
<meta property="og:title" content="U-Boot and memory permissions"/>
<meta property="og:description" content="U-Boot, in most of the supported architectures, relocates itself on top of DRAM but leaves the memory as RWX Arm64 is a notable exception"/>
<meta property="og:locale" content="en_US"/>
<meta property="og:url" content="https://apalos.github.io/U-Boot and memory permissions.html"/>
<meta property="og:type" content="article"/>
<meta property="article:published_time" content="2025-03-13 10:20:00+02:00"/>
<meta property="article:modified_time" content=""/>
<meta property="article:author" content="https://apalos.github.io/author/ilias-apalodimas.html">
<meta property="article:section" content="UEFI"/>
<meta property="article:tag" content="Bootloaders"/>
<meta property="article:tag" content="Security"/>
<meta property="article:tag" content="U-Boot"/>
<meta property="article:tag" content="UEFI"/>
<meta property="og:image" content="site_images/profile.png">
<title>Volatile rumblings – U-Boot and memory permissions</title>
</head>
<body class="light-theme">
<aside>
<div>
<a href="https://apalos.github.io">
<img src="site_images/profile.png" alt="" title="">
</a>
<h1>
<a href="https://apalos.github.io"></a>
</h1>
<p>Volatile rumblings</p>
<nav>
<ul class="list">
<li>
<a target="_self" href="http://github.com/Xdp-project" >XDP</a>
</li>
</ul>
</nav>
<ul class="social">
<li>
<a class="sc-github" href="https://github.com/apalos" target="_blank">
<i class="fab fa-github"></i>
</a>
</li>
<li>
<a class="sc-linkedin" href="https://www.linkedin.com/in/ilias-apalodimas-91891a34/" target="_blank">
<i class="fab fa-linkedin"></i>
</a>
</li>
<li>
<a class="sc-twitter" href="https://www.twitter.com/_apalos" target="_blank">
<i class="fab fa-twitter"></i>
</a>
</li>
</ul>
</div>
</aside>
<main>
<nav>
<a href="https://apalos.github.io">Home</a>
<a href="/archives.html">Archives</a>
<a href="/categories.html">Categories</a>
<a href="/tags.html">Tags</a>
</nav>
<article class="single">
<header>
<h1 id="U-Boot and memory permissions">U-Boot and memory permissions</h1>
<p>
Posted on Thu 13 March 2025 in <a href="https://apalos.github.io/category/uefi.html">UEFI</a>
• 3 min read
</p>
</header>
<div>
<h6></h6>
<p><link rel="stylesheet" href="overload.css"></p>
<h2><strong>Why not RWX</strong></h2>
<p>Explaining why is a complex topic and not within the scope of this blog, but generally speaking
mapping executables with specific permissions (RO, RX, and RW^X) instead of just RWX is crucial for security.
It greatly reduces the attack surface and makes vulnerabilities harder to exploit. The Arm
architecture has complex ways of configuring the MMU and it depends on the overall system
configuration.</p>
<p>For U-Boot we only care about <strong>"Stage 1 VMSAv8-64 Block and Page descriptor fields"</strong> found in
D8-6492 of the <a href="https://developer.arm.com/documentation/ddi0487/latest/">ARM ARM</a> version L.a</p>
<ul>
<li>XN: eXecute Never -- Prevents execution</li>
<li>PXN: Privileged eXecute Never -- Prevents execution from privileged mode</li>
<li>UXN: Unprivileged eXecute Never -- Prevents execution from unprivileged mode</li>
<li>RO: Read-only -- Prevents memory writes</li>
</ul>
<p>Which ones you have to set depends mainly on the translation regime. Running U-Boot in QEMU
without virtualization ends up running U-Boot in EL1&0 translation regime and both PXN/UXN need to
be set.</p>
<h2><strong>Current status</strong></h2>
<p>In U-Boot, memory is either normal memory which is mapped as RWX, or device memory
which is mapped as RW. When U-Boot relocates it self to the top of DRAM, it doesn't change
any of the memory permissions.</p>
<p>The output below is only available in the -next branch which includes
this <a href="https://lore.kernel.org/u-boot/[email protected]/">patchset</a>
by enabling <code>CMD_MEMINFO</code> && <code>CMD_CMD_MEMINFO_MAP</code> in the qemu_arm64_lwip_defconfig.</p>
<p>Booting up QEMU gives us this</p>
<div class="highlight"><pre><span></span><code>qemu-system-aarch64<span class="w"> </span>-m<span class="w"> </span><span class="m">8192</span><span class="w"> </span>-smp<span class="w"> </span><span class="m">2</span><span class="w"> </span>-nographic<span class="w"> </span>-cpu<span class="w"> </span>cortex-a57<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-bios<span class="w"> </span>u-boot.bin<span class="w"> </span>-machine<span class="w"> </span>virt,secure<span class="o">=</span>off<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-device<span class="w"> </span>virtio-rng-pci
U-Boot<span class="w"> </span><span class="m">2025</span>.04-rc4-00404-g0e1fc465fea6<span class="w"> </span><span class="o">(</span>Mar<span class="w"> </span><span class="m">16</span><span class="w"> </span><span class="m">2025</span><span class="w"> </span>-<span class="w"> </span><span class="m">23</span>:18:56<span class="w"> </span>+0200<span class="o">)</span>
DRAM:<span class="w"> </span><span class="m">8</span><span class="w"> </span>GiB
Core:<span class="w"> </span><span class="m">52</span><span class="w"> </span>devices,<span class="w"> </span><span class="m">15</span><span class="w"> </span>uclasses,<span class="w"> </span>devicetree:<span class="w"> </span>board
<span class="o">[</span>...<span class="o">]</span>
<span class="o">=</span>><span class="w"> </span>meminfo
DRAM:<span class="w"> </span><span class="m">8</span><span class="w"> </span>GiB
Walking<span class="w"> </span>pagetable<span class="w"> </span>at<span class="w"> </span>000000023ffe0000,<span class="w"> </span>va_bits:<span class="w"> </span><span class="m">40</span>.<span class="w"> </span>Using<span class="w"> </span><span class="m">4</span><span class="w"> </span>levels
<span class="o">[</span>0x0000023ffe1000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x0000023ffe2000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00000000000000<span class="w"> </span>-<span class="w"> </span>0x00000008000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x00000008000000<span class="w"> </span>-<span class="w"> </span>0x00000040000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Device-nGnRnE<span class="w"> </span><span class="p">|</span><span class="w"> </span>Non-shareable
<span class="w"> </span><span class="o">[</span>0x00000040000000<span class="w"> </span>-<span class="w"> </span>0x00004000000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023ffe3000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00004010000000<span class="w"> </span>-<span class="w"> </span>0x00004020000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Device-nGnRnE<span class="w"> </span><span class="p">|</span><span class="w"> </span>Non-shareable
<span class="o">[</span>0x0000023ffe4000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00008000000000<span class="w"> </span>-<span class="w"> </span>0x00010000000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Device-nGnRnE<span class="w"> </span><span class="p">|</span><span class="w"> </span>Non-shareable
</code></pre></div>
<ul>
<li><strong>PXN UXN</strong>: Read-Write memory</li>
<li><strong>RWX</strong>: Read-Write-Execute memory</li>
</ul>
<p>As you can see, only device mapped memory is not allowed to execute.</p>
<h2><strong>Enable memory permissions</strong></h2>
<p>The patchset above adds another interesting flag <code>CONFIG_MMU_PGPROT</code> which only applies to arm64.
Unfortunately we can't yet enable it by default for all arm64 boards, because bugs like <a href="https://lore.kernel.org/u-boot/[email protected]/">this</a>
and <a href="https://lore.kernel.org/u-boot/[email protected]/">this</a> will now lead to a crash.</p>
<p>With the above fixes we can enable the flag in QEMU and look into the new mappings</p>
<div class="highlight"><pre><span></span><code><span class="o">=</span>><span class="w"> </span>meminfo
DRAM:<span class="w"> </span><span class="m">8</span><span class="w"> </span>GiB
Walking<span class="w"> </span>pagetable<span class="w"> </span>at<span class="w"> </span>000000023ffe0000,<span class="w"> </span>va_bits:<span class="w"> </span><span class="m">40</span>.<span class="w"> </span>Using<span class="w"> </span><span class="m">4</span><span class="w"> </span>levels
<span class="o">[</span>0x0000023ffe1000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x0000023ffe2000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00000000000000<span class="w"> </span>-<span class="w"> </span>0x00000008000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x00000008000000<span class="w"> </span>-<span class="w"> </span>0x00000040000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Device-nGnRnE<span class="w"> </span><span class="p">|</span><span class="w"> </span>Non-shareable
<span class="w"> </span><span class="o">[</span>0x00000040000000<span class="w"> </span>-<span class="w"> </span>0x00000200000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023ffea000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00000200000000<span class="w"> </span>-<span class="w"> </span>0x0000023f600000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023ffeb000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x0000023f600000<span class="w"> </span>-<span class="w"> </span>0x0000023f6b9000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Pages<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023f6b9000<span class="w"> </span>-<span class="w"> </span>0x0000023f77d000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Pages<span class="w"> </span><span class="p">|</span><span class="w"> </span>RO<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023f77d000<span class="w"> </span>-<span class="w"> </span>0x0000023f77e000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Pages<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023f77e000<span class="w"> </span>-<span class="w"> </span>0x0000023f7c8000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Pages<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span>RO<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023f7c8000<span class="w"> </span>-<span class="w"> </span>0x0000023f7e0000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Pages<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023f7e0000<span class="w"> </span>-<span class="w"> </span>0x0000023f800000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Pages<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023f800000<span class="w"> </span>-<span class="w"> </span>0x00000240000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x00000240000000<span class="w"> </span>-<span class="w"> </span>0x00004000000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>RWX<span class="w"> </span><span class="p">|</span><span class="w"> </span>Normal<span class="w"> </span><span class="p">|</span><span class="w"> </span>Inner-shareable
<span class="w"> </span><span class="o">[</span>0x0000023ffe3000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00004010000000<span class="w"> </span>-<span class="w"> </span>0x00004020000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Device-nGnRnE<span class="w"> </span><span class="p">|</span><span class="w"> </span>Non-shareable
<span class="o">[</span>0x0000023ffe4000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Table<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">|</span>
<span class="w"> </span><span class="o">[</span>0x00008000000000<span class="w"> </span>-<span class="w"> </span>0x00010000000000<span class="o">]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>Block<span class="w"> </span><span class="p">|</span><span class="w"> </span>PXN<span class="w"> </span>UXN<span class="w"> </span><span class="p">|</span><span class="w"> </span>Device-nGnRnE<span class="w"> </span><span class="p">|</span><span class="w"> </span>Non-shareable
</code></pre></div>
<ul>
<li><strong>PXN UXN RO</strong>: Read-only memory</li>
<li><strong>PXN UXN</strong>: Read-Write memory</li>
<li><strong>RO</strong>: Read-Execute memory</li>
</ul>
<p>U-Boot has relocate to <code>[0x0000023f6b9000 - 0x0000023f77d000]</code> <code>[0x0000023f77e000 - 0x0000023f7c8000]</code> and <code>[0x0000023f7c8000 - 0x0000023f7e0000]</code>
which now have proper memory permissions!</p>
<h2><strong>But we still have RWX memory</strong></h2>
<p>There are several reasons that the rest of the memory is left as RWX. One of them is EFI runtime
services. U-Boot doesn't separate between EFI RO, RW and RX sections, instead it bundles all of the
in the .efi_runtime and places them right before .text. We end up mapping 64kb for runtime
services, which includes all the EFI related sections and .text. The linker script will need a bigger
rewrite to map EFI services properly.</p>
<p>Another reason is the SetVirtualAddressMap which allows the OS to remap EFI runtime services in a
VA of its choice. This is rarely called for the arm64 architecture (only when VA_BITS < 39) in Linux,
but when it's needed we need to switch any RX (which will now hold the runtime services) to RWX to
allow relocations.</p>
<p>So for now certain pages are left as RWX.</p>
<h2><strong>Future work</strong></h2>
<ul>
<li>Rework the linker scripts and decouple EFI memory from .text</li>
<li>Apply proper mapping to EFI runtime services as well</li>
</ul>
</div>
<div class="tag-cloud">
<p>
<a href="https://apalos.github.io/tag/bootloaders.html">Bootloaders</a>
<a href="https://apalos.github.io/tag/security.html">Security</a>
<a href="https://apalos.github.io/tag/u-boot.html">U-Boot</a>
<a href="https://apalos.github.io/tag/uefi.html">UEFI</a>
</p>
</div>
</article>
<footer>
<p>© </p>
<p>
Built with <a href="http://getpelican.com" target="_blank">Pelican</a> using <a href="http://bit.ly/flex-pelican" target="_blank">Flex</a> theme
</p> </footer>
</main>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "Blog",
"name": " Volatile rumblings ",
"url" : "https://apalos.github.io",
"image": "site_images/profile.png",
"description": ""
}
</script>
</body>
</html>