diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-04 17:46:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-04 17:46:04 -0500 |
commit | 42bd06e93d108a3ee5b8b4eaa350ec81853cb217 (patch) | |
tree | 857034936a2c29c79c5cfde47c660225007b060f | |
parent | 4710e78940d8d957f24b8f085f961f1279f8fbff (diff) | |
parent | 84db119f5a83e1bf9cffbc6d9cf16487eda1c056 (diff) |
Merge tag 'tags/upstream-4.20-rc1' of git://git.infradead.org/linux-ubifs
Pull UBIFS updates from Richard Weinberger:
- Full filesystem authentication feature, UBIFS is now able to have the
whole filesystem structure authenticated plus user data encrypted and
authenticated.
- Minor cleanups
* tag 'tags/upstream-4.20-rc1' of git://git.infradead.org/linux-ubifs: (26 commits)
ubifs: Remove unneeded semicolon
Documentation: ubifs: Add authentication whitepaper
ubifs: Enable authentication support
ubifs: Do not update inode size in-place in authenticated mode
ubifs: Add hashes and HMACs to default filesystem
ubifs: authentication: Authenticate super block node
ubifs: Create hash for default LPT
ubfis: authentication: Authenticate master node
ubifs: authentication: Authenticate LPT
ubifs: Authenticate replayed journal
ubifs: Add auth nodes to garbage collector journal head
ubifs: Add authentication nodes to journal
ubifs: authentication: Add hashes to index nodes
ubifs: Add hashes to the tree node cache
ubifs: Create functions to embed a HMAC in a node
ubifs: Add helper functions for authentication support
ubifs: Add separate functions to init/crc a node
ubifs: Format changes for authentication support
ubifs: Store read superblock node
ubifs: Drop write_node
...
-rw-r--r-- | Documentation/filesystems/ubifs-authentication.md | 426 | ||||
-rw-r--r-- | Documentation/filesystems/ubifs.txt | 7 | ||||
-rw-r--r-- | drivers/mtd/ubi/attach.c | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 2 | ||||
-rw-r--r-- | fs/ubifs/Kconfig | 11 | ||||
-rw-r--r-- | fs/ubifs/Makefile | 1 | ||||
-rw-r--r-- | fs/ubifs/auth.c | 502 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 6 | ||||
-rw-r--r-- | fs/ubifs/gc.c | 49 | ||||
-rw-r--r-- | fs/ubifs/io.c | 110 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 289 | ||||
-rw-r--r-- | fs/ubifs/log.c | 24 | ||||
-rw-r--r-- | fs/ubifs/lpt.c | 184 | ||||
-rw-r--r-- | fs/ubifs/lpt_commit.c | 44 | ||||
-rw-r--r-- | fs/ubifs/master.c | 64 | ||||
-rw-r--r-- | fs/ubifs/misc.h | 5 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 120 | ||||
-rw-r--r-- | fs/ubifs/replay.c | 177 | ||||
-rw-r--r-- | fs/ubifs/sb.c | 209 | ||||
-rw-r--r-- | fs/ubifs/super.c | 91 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 36 | ||||
-rw-r--r-- | fs/ubifs/tnc_commit.c | 27 | ||||
-rw-r--r-- | fs/ubifs/tnc_misc.c | 26 | ||||
-rw-r--r-- | fs/ubifs/ubifs-media.h | 46 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 253 |
25 files changed, 2418 insertions, 292 deletions
diff --git a/Documentation/filesystems/ubifs-authentication.md b/Documentation/filesystems/ubifs-authentication.md new file mode 100644 index 000000000000..028b3e2e25f9 --- /dev/null +++ b/Documentation/filesystems/ubifs-authentication.md | |||
@@ -0,0 +1,426 @@ | |||
1 | % UBIFS Authentication | ||
2 | % sigma star gmbh | ||
3 | % 2018 | ||
4 | |||
5 | # Introduction | ||
6 | |||
7 | UBIFS utilizes the fscrypt framework to provide confidentiality for file | ||
8 | contents and file names. This prevents attacks where an attacker is able to | ||
9 | read contents of the filesystem on a single point in time. A classic example | ||
10 | is a lost smartphone where the attacker is unable to read personal data stored | ||
11 | on the device without the filesystem decryption key. | ||
12 | |||
13 | At the current state, UBIFS encryption however does not prevent attacks where | ||
14 | the attacker is able to modify the filesystem contents and the user uses the | ||
15 | device afterwards. In such a scenario an attacker can modify filesystem | ||
16 | contents arbitrarily without the user noticing. One example is to modify a | ||
17 | binary to perform a malicious action when executed [DMC-CBC-ATTACK]. Since | ||
18 | most of the filesystem metadata of UBIFS is stored in plain, this makes it | ||
19 | fairly easy to swap files and replace their contents. | ||
20 | |||
21 | Other full disk encryption systems like dm-crypt cover all filesystem metadata, | ||
22 | which makes such kinds of attacks more complicated, but not impossible. | ||
23 | Especially, if the attacker is given access to the device multiple points in | ||
24 | time. For dm-crypt and other filesystems that build upon the Linux block IO | ||
25 | layer, the dm-integrity or dm-verity subsystems [DM-INTEGRITY, DM-VERITY] | ||
26 | can be used to get full data authentication at the block layer. | ||
27 | These can also be combined with dm-crypt [CRYPTSETUP2]. | ||
28 | |||
29 | This document describes an approach to get file contents _and_ full metadata | ||
30 | authentication for UBIFS. Since UBIFS uses fscrypt for file contents and file | ||
31 | name encryption, the authentication system could be tied into fscrypt such that | ||
32 | existing features like key derivation can be utilized. It should however also | ||
33 | be possible to use UBIFS authentication without using encryption. | ||
34 | |||
35 | |||
36 | ## MTD, UBI & UBIFS | ||
37 | |||
38 | On Linux, the MTD (Memory Technology Devices) subsystem provides a uniform | ||
39 | interface to access raw flash devices. One of the more prominent subsystems that | ||
40 | work on top of MTD is UBI (Unsorted Block Images). It provides volume management | ||
41 | for flash devices and is thus somewhat similar to LVM for block devices. In | ||
42 | addition, it deals with flash-specific wear-leveling and transparent I/O error | ||
43 | handling. UBI offers logical erase blocks (LEBs) to the layers on top of it | ||
44 | and maps them transparently to physical erase blocks (PEBs) on the flash. | ||
45 | |||
46 | UBIFS is a filesystem for raw flash which operates on top of UBI. Thus, wear | ||
47 | leveling and some flash specifics are left to UBI, while UBIFS focuses on | ||
48 | scalability, performance and recoverability. | ||
49 | |||
50 | |||
51 | |||
52 | +------------+ +*******+ +-----------+ +-----+ | ||
53 | | | * UBIFS * | UBI-BLOCK | | ... | | ||
54 | | JFFS/JFFS2 | +*******+ +-----------+ +-----+ | ||
55 | | | +-----------------------------+ +-----------+ +-----+ | ||
56 | | | | UBI | | MTD-BLOCK | | ... | | ||
57 | +------------+ +-----------------------------+ +-----------+ +-----+ | ||
58 | +------------------------------------------------------------------+ | ||
59 | | MEMORY TECHNOLOGY DEVICES (MTD) | | ||
60 | +------------------------------------------------------------------+ | ||
61 | +-----------------------------+ +--------------------------+ +-----+ | ||
62 | | NAND DRIVERS | | NOR DRIVERS | | ... | | ||
63 | +-----------------------------+ +--------------------------+ +-----+ | ||
64 | |||
65 | Figure 1: Linux kernel subsystems for dealing with raw flash | ||
66 | |||
67 | |||
68 | |||
69 | Internally, UBIFS maintains multiple data structures which are persisted on | ||
70 | the flash: | ||
71 | |||
72 | - *Index*: an on-flash B+ tree where the leaf nodes contain filesystem data | ||
73 | - *Journal*: an additional data structure to collect FS changes before updating | ||
74 | the on-flash index and reduce flash wear. | ||
75 | - *Tree Node Cache (TNC)*: an in-memory B+ tree that reflects the current FS | ||
76 | state to avoid frequent flash reads. It is basically the in-memory | ||
77 | representation of the index, but contains additional attributes. | ||
78 | - *LEB property tree (LPT)*: an on-flash B+ tree for free space accounting per | ||
79 | UBI LEB. | ||
80 | |||
81 | In the remainder of this section we will cover the on-flash UBIFS data | ||
82 | structures in more detail. The TNC is of less importance here since it is never | ||
83 | persisted onto the flash directly. More details on UBIFS can also be found in | ||
84 | [UBIFS-WP]. | ||
85 | |||
86 | |||
87 | ### UBIFS Index & Tree Node Cache | ||
88 | |||
89 | Basic on-flash UBIFS entities are called *nodes*. UBIFS knows different types | ||
90 | of nodes. Eg. data nodes (`struct ubifs_data_node`) which store chunks of file | ||
91 | contents or inode nodes (`struct ubifs_ino_node`) which represent VFS inodes. | ||
92 | Almost all types of nodes share a common header (`ubifs_ch`) containing basic | ||
93 | information like node type, node length, a sequence number, etc. (see | ||
94 | `fs/ubifs/ubifs-media.h`in kernel source). Exceptions are entries of the LPT | ||
95 | and some less important node types like padding nodes which are used to pad | ||
96 | unusable content at the end of LEBs. | ||
97 | |||
98 | To avoid re-writing the whole B+ tree on every single change, it is implemented | ||
99 | as *wandering tree*, where only the changed nodes are re-written and previous | ||
100 | versions of them are obsoleted without erasing them right away. As a result, | ||
101 | the index is not stored in a single place on the flash, but *wanders* around | ||
102 | and there are obsolete parts on the flash as long as the LEB containing them is | ||
103 | not reused by UBIFS. To find the most recent version of the index, UBIFS stores | ||
104 | a special node called *master node* into UBI LEB 1 which always points to the | ||
105 | most recent root node of the UBIFS index. For recoverability, the master node | ||
106 | is additionally duplicated to LEB 2. Mounting UBIFS is thus a simple read of | ||
107 | LEB 1 and 2 to get the current master node and from there get the location of | ||
108 | the most recent on-flash index. | ||
109 | |||
110 | The TNC is the in-memory representation of the on-flash index. It contains some | ||
111 | additional runtime attributes per node which are not persisted. One of these is | ||
112 | a dirty-flag which marks nodes that have to be persisted the next time the | ||
113 | index is written onto the flash. The TNC acts as a write-back cache and all | ||
114 | modifications of the on-flash index are done through the TNC. Like other caches, | ||
115 | the TNC does not have to mirror the full index into memory, but reads parts of | ||
116 | it from flash whenever needed. A *commit* is the UBIFS operation of updating the | ||
117 | on-flash filesystem structures like the index. On every commit, the TNC nodes | ||
118 | marked as dirty are written to the flash to update the persisted index. | ||
119 | |||
120 | |||
121 | ### Journal | ||
122 | |||
123 | To avoid wearing out the flash, the index is only persisted (*commited*) when | ||
124 | certain conditions are met (eg. `fsync(2)`). The journal is used to record | ||
125 | any changes (in form of inode nodes, data nodes etc.) between commits | ||
126 | of the index. During mount, the journal is read from the flash and replayed | ||
127 | onto the TNC (which will be created on-demand from the on-flash index). | ||
128 | |||
129 | UBIFS reserves a bunch of LEBs just for the journal called *log area*. The | ||
130 | amount of log area LEBs is configured on filesystem creation (using | ||
131 | `mkfs.ubifs`) and stored in the superblock node. The log area contains only | ||
132 | two types of nodes: *reference nodes* and *commit start nodes*. A commit start | ||
133 | node is written whenever an index commit is performed. Reference nodes are | ||
134 | written on every journal update. Each reference node points to the position of | ||
135 | other nodes (inode nodes, data nodes etc.) on the flash that are part of this | ||
136 | journal entry. These nodes are called *buds* and describe the actual filesystem | ||
137 | changes including their data. | ||
138 | |||
139 | The log area is maintained as a ring. Whenever the journal is almost full, | ||
140 | a commit is initiated. This also writes a commit start node so that during | ||
141 | mount, UBIFS will seek for the most recent commit start node and just replay | ||
142 | every reference node after that. Every reference node before the commit start | ||
143 | node will be ignored as they are already part of the on-flash index. | ||
144 | |||
145 | When writing a journal entry, UBIFS first ensures that enough space is | ||
146 | available to write the reference node and buds part of this entry. Then, the | ||
147 | reference node is written and afterwards the buds describing the file changes. | ||
148 | On replay, UBIFS will record every reference node and inspect the location of | ||
149 | the referenced LEBs to discover the buds. If these are corrupt or missing, | ||
150 | UBIFS will attempt to recover them by re-reading the LEB. This is however only | ||
151 | done for the last referenced LEB of the journal. Only this can become corrupt | ||
152 | because of a power cut. If the recovery fails, UBIFS will not mount. An error | ||
153 | for every other LEB will directly cause UBIFS to fail the mount operation. | ||
154 | |||
155 | |||
156 | | ---- LOG AREA ---- | ---------- MAIN AREA ------------ | | ||
157 | |||
158 | -----+------+-----+--------+---- ------+-----+-----+--------------- | ||
159 | \ | | | | / / | | | \ | ||
160 | / CS | REF | REF | | \ \ DENT | INO | INO | / | ||
161 | \ | | | | / / | | | \ | ||
162 | ----+------+-----+--------+--- -------+-----+-----+---------------- | ||
163 | | | ^ ^ | ||
164 | | | | | | ||
165 | +------------------------+ | | ||
166 | | | | ||
167 | +-------------------------------+ | ||
168 | |||
169 | |||
170 | Figure 2: UBIFS flash layout of log area with commit start nodes | ||
171 | (CS) and reference nodes (REF) pointing to main area | ||
172 | containing their buds | ||
173 | |||
174 | |||
175 | ### LEB Property Tree/Table | ||
176 | |||
177 | The LEB property tree is used to store per-LEB information. This includes the | ||
178 | LEB type and amount of free and *dirty* (old, obsolete content) space [1] on | ||
179 | the LEB. The type is important, because UBIFS never mixes index nodes with data | ||
180 | nodes on a single LEB and thus each LEB has a specific purpose. This again is | ||
181 | useful for free space calculations. See [UBIFS-WP] for more details. | ||
182 | |||
183 | The LEB property tree again is a B+ tree, but it is much smaller than the | ||
184 | index. Due to its smaller size it is always written as one chunk on every | ||
185 | commit. Thus, saving the LPT is an atomic operation. | ||
186 | |||
187 | |||
188 | [1] Since LEBs can only be appended and never overwritten, there is a | ||
189 | difference between free space ie. the remaining space left on the LEB to be | ||
190 | written to without erasing it and previously written content that is obsolete | ||
191 | but can't be overwritten without erasing the full LEB. | ||
192 | |||
193 | |||
194 | # UBIFS Authentication | ||
195 | |||
196 | This chapter introduces UBIFS authentication which enables UBIFS to verify | ||
197 | the authenticity and integrity of metadata and file contents stored on flash. | ||
198 | |||
199 | |||
200 | ## Threat Model | ||
201 | |||
202 | UBIFS authentication enables detection of offline data modification. While it | ||
203 | does not prevent it, it enables (trusted) code to check the integrity and | ||
204 | authenticity of on-flash file contents and filesystem metadata. This covers | ||
205 | attacks where file contents are swapped. | ||
206 | |||
207 | UBIFS authentication will not protect against rollback of full flash contents. | ||
208 | Ie. an attacker can still dump the flash and restore it at a later time without | ||
209 | detection. It will also not protect against partial rollback of individual | ||
210 | index commits. That means that an attacker is able to partially undo changes. | ||
211 | This is possible because UBIFS does not immediately overwrites obsolete | ||
212 | versions of the index tree or the journal, but instead marks them as obsolete | ||
213 | and garbage collection erases them at a later time. An attacker can use this by | ||
214 | erasing parts of the current tree and restoring old versions that are still on | ||
215 | the flash and have not yet been erased. This is possible, because every commit | ||
216 | will always write a new version of the index root node and the master node | ||
217 | without overwriting the previous version. This is further helped by the | ||
218 | wear-leveling operations of UBI which copies contents from one physical | ||
219 | eraseblock to another and does not atomically erase the first eraseblock. | ||
220 | |||
221 | UBIFS authentication does not cover attacks where an attacker is able to | ||
222 | execute code on the device after the authentication key was provided. | ||
223 | Additional measures like secure boot and trusted boot have to be taken to | ||
224 | ensure that only trusted code is executed on a device. | ||
225 | |||
226 | |||
227 | ## Authentication | ||
228 | |||
229 | To be able to fully trust data read from flash, all UBIFS data structures | ||
230 | stored on flash are authenticated. That is: | ||
231 | |||
232 | - The index which includes file contents, file metadata like extended | ||
233 | attributes, file length etc. | ||
234 | - The journal which also contains file contents and metadata by recording changes | ||
235 | to the filesystem | ||
236 | - The LPT which stores UBI LEB metadata which UBIFS uses for free space accounting | ||
237 | |||
238 | |||
239 | ### Index Authentication | ||
240 | |||
241 | Through UBIFS' concept of a wandering tree, it already takes care of only | ||
242 | updating and persisting changed parts from leaf node up to the root node | ||
243 | of the full B+ tree. This enables us to augment the index nodes of the tree | ||
244 | with a hash over each node's child nodes. As a result, the index basically also | ||
245 | a Merkle tree. Since the leaf nodes of the index contain the actual filesystem | ||
246 | data, the hashes of their parent index nodes thus cover all the file contents | ||
247 | and file metadata. When a file changes, the UBIFS index is updated accordingly | ||
248 | from the leaf nodes up to the root node including the master node. This process | ||
249 | can be hooked to recompute the hash only for each changed node at the same time. | ||
250 | Whenever a file is read, UBIFS can verify the hashes from each leaf node up to | ||
251 | the root node to ensure the node's integrity. | ||
252 | |||
253 | To ensure the authenticity of the whole index, the UBIFS master node stores a | ||
254 | keyed hash (HMAC) over its own contents and a hash of the root node of the index | ||
255 | tree. As mentioned above, the master node is always written to the flash whenever | ||
256 | the index is persisted (ie. on index commit). | ||
257 | |||
258 | Using this approach only UBIFS index nodes and the master node are changed to | ||
259 | include a hash. All other types of nodes will remain unchanged. This reduces | ||
260 | the storage overhead which is precious for users of UBIFS (ie. embedded | ||
261 | devices). | ||
262 | |||
263 | |||
264 | +---------------+ | ||
265 | | Master Node | | ||
266 | | (hash) | | ||
267 | +---------------+ | ||
268 | | | ||
269 | v | ||
270 | +-------------------+ | ||
271 | | Index Node #1 | | ||
272 | | | | ||
273 | | branch0 branchn | | ||
274 | | (hash) (hash) | | ||
275 | +-------------------+ | ||
276 | | ... | (fanout: 8) | ||
277 | | | | ||
278 | +-------+ +------+ | ||
279 | | | | ||
280 | v v | ||
281 | +-------------------+ +-------------------+ | ||
282 | | Index Node #2 | | Index Node #3 | | ||
283 | | | | | | ||
284 | | branch0 branchn | | branch0 branchn | | ||
285 | | (hash) (hash) | | (hash) (hash) | | ||
286 | +-------------------+ +-------------------+ | ||
287 | | ... | ... | | ||
288 | v v v | ||
289 | +-----------+ +----------+ +-----------+ | ||
290 | | Data Node | | INO Node | | DENT Node | | ||
291 | +-----------+ +----------+ +-----------+ | ||
292 | |||
293 | |||
294 | Figure 3: Coverage areas of index node hash and master node HMAC | ||
295 | |||
296 | |||
297 | |||
298 | The most important part for robustness and power-cut safety is to atomically | ||
299 | persist the hash and file contents. Here the existing UBIFS logic for how | ||
300 | changed nodes are persisted is already designed for this purpose such that | ||
301 | UBIFS can safely recover if a power-cut occurs while persisting. Adding | ||
302 | hashes to index nodes does not change this since each hash will be persisted | ||
303 | atomically together with its respective node. | ||
304 | |||
305 | |||
306 | ### Journal Authentication | ||
307 | |||
308 | The journal is authenticated too. Since the journal is continuously written | ||
309 | it is necessary to also add authentication information frequently to the | ||
310 | journal so that in case of a powercut not too much data can't be authenticated. | ||
311 | This is done by creating a continuous hash beginning from the commit start node | ||
312 | over the previous reference nodes, the current reference node, and the bud | ||
313 | nodes. From time to time whenever it is suitable authentication nodes are added | ||
314 | between the bud nodes. This new node type contains a HMAC over the current state | ||
315 | of the hash chain. That way a journal can be authenticated up to the last | ||
316 | authentication node. The tail of the journal which may not have a authentication | ||
317 | node cannot be authenticated and is skipped during journal replay. | ||
318 | |||
319 | We get this picture for journal authentication: | ||
320 | |||
321 | ,,,,,,,, | ||
322 | ,......,........................................... | ||
323 | ,. CS , hash1.----. hash2.----. | ||
324 | ,. | , . |hmac . |hmac | ||
325 | ,. v , . v . v | ||
326 | ,.REF#0,-> bud -> bud -> bud.-> auth -> bud -> bud.-> auth ... | ||
327 | ,..|...,........................................... | ||
328 | , | , | ||
329 | , | ,,,,,,,,,,,,,,, | ||
330 | . | hash3,----. | ||
331 | , | , |hmac | ||
332 | , v , v | ||
333 | , REF#1 -> bud -> bud,-> auth ... | ||
334 | ,,,|,,,,,,,,,,,,,,,,,, | ||
335 | v | ||
336 | REF#2 -> ... | ||
337 | | | ||
338 | V | ||
339 | ... | ||
340 | |||
341 | Since the hash also includes the reference nodes an attacker cannot reorder or | ||
342 | skip any journal heads for replay. An attacker can only remove bud nodes or | ||
343 | reference nodes from the end of the journal, effectively rewinding the | ||
344 | filesystem at maximum back to the last commit. | ||
345 | |||
346 | The location of the log area is stored in the master node. Since the master | ||
347 | node is authenticated with a HMAC as described above, it is not possible to | ||
348 | tamper with that without detection. The size of the log area is specified when | ||
349 | the filesystem is created using `mkfs.ubifs` and stored in the superblock node. | ||
350 | To avoid tampering with this and other values stored there, a HMAC is added to | ||
351 | the superblock struct. The superblock node is stored in LEB 0 and is only | ||
352 | modified on feature flag or similar changes, but never on file changes. | ||
353 | |||
354 | |||
355 | ### LPT Authentication | ||
356 | |||
357 | The location of the LPT root node on the flash is stored in the UBIFS master | ||
358 | node. Since the LPT is written and read atomically on every commit, there is | ||
359 | no need to authenticate individual nodes of the tree. It suffices to | ||
360 | protect the integrity of the full LPT by a simple hash stored in the master | ||
361 | node. Since the master node itself is authenticated, the LPTs authenticity can | ||
362 | be verified by verifying the authenticity of the master node and comparing the | ||
363 | LTP hash stored there with the hash computed from the read on-flash LPT. | ||
364 | |||
365 | |||
366 | ## Key Management | ||
367 | |||
368 | For simplicity, UBIFS authentication uses a single key to compute the HMACs | ||
369 | of superblock, master, commit start and reference nodes. This key has to be | ||
370 | available on creation of the filesystem (`mkfs.ubifs`) to authenticate the | ||
371 | superblock node. Further, it has to be available on mount of the filesystem | ||
372 | to verify authenticated nodes and generate new HMACs for changes. | ||
373 | |||
374 | UBIFS authentication is intended to operate side-by-side with UBIFS encryption | ||
375 | (fscrypt) to provide confidentiality and authenticity. Since UBIFS encryption | ||
376 | has a different approach of encryption policies per directory, there can be | ||
377 | multiple fscrypt master keys and there might be folders without encryption. | ||
378 | UBIFS authentication on the other hand has an all-or-nothing approach in the | ||
379 | sense that it either authenticates everything of the filesystem or nothing. | ||
380 | Because of this and because UBIFS authentication should also be usable without | ||
381 | encryption, it does not share the same master key with fscrypt, but manages | ||
382 | a dedicated authentication key. | ||
383 | |||
384 | The API for providing the authentication key has yet to be defined, but the | ||
385 | key can eg. be provided by userspace through a keyring similar to the way it | ||
386 | is currently done in fscrypt. It should however be noted that the current | ||
387 | fscrypt approach has shown its flaws and the userspace API will eventually | ||
388 | change [FSCRYPT-POLICY2]. | ||
389 | |||
390 | Nevertheless, it will be possible for a user to provide a single passphrase | ||
391 | or key in userspace that covers UBIFS authentication and encryption. This can | ||
392 | be solved by the corresponding userspace tools which derive a second key for | ||
393 | authentication in addition to the derived fscrypt master key used for | ||
394 | encryption. | ||
395 | |||
396 | To be able to check if the proper key is available on mount, the UBIFS | ||
397 | superblock node will additionally store a hash of the authentication key. This | ||
398 | approach is similar to the approach proposed for fscrypt encryption policy v2 | ||
399 | [FSCRYPT-POLICY2]. | ||
400 | |||
401 | |||
402 | # Future Extensions | ||
403 | |||
404 | In certain cases where a vendor wants to provide an authenticated filesystem | ||
405 | image to customers, it should be possible to do so without sharing the secret | ||
406 | UBIFS authentication key. Instead, in addition the each HMAC a digital | ||
407 | signature could be stored where the vendor shares the public key alongside the | ||
408 | filesystem image. In case this filesystem has to be modified afterwards, | ||
409 | UBIFS can exchange all digital signatures with HMACs on first mount similar | ||
410 | to the way the IMA/EVM subsystem deals with such situations. The HMAC key | ||
411 | will then have to be provided beforehand in the normal way. | ||
412 | |||
413 | |||
414 | # References | ||
415 | |||
416 | [CRYPTSETUP2] http://www.saout.de/pipermail/dm-crypt/2017-November/005745.html | ||
417 | |||
418 | [DMC-CBC-ATTACK] http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/ | ||
419 | |||
420 | [DM-INTEGRITY] https://www.kernel.org/doc/Documentation/device-mapper/dm-integrity.txt | ||
421 | |||
422 | [DM-VERITY] https://www.kernel.org/doc/Documentation/device-mapper/verity.txt | ||
423 | |||
424 | [FSCRYPT-POLICY2] https://www.spinics.net/lists/linux-ext4/msg58710.html | ||
425 | |||
426 | [UBIFS-WP] http://www.linux-mtd.infradead.org/doc/ubifs_whitepaper.pdf | ||
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt index a0a61d2f389f..acc80442a3bb 100644 --- a/Documentation/filesystems/ubifs.txt +++ b/Documentation/filesystems/ubifs.txt | |||
@@ -91,6 +91,13 @@ chk_data_crc do not skip checking CRCs on data nodes | |||
91 | compr=none override default compressor and set it to "none" | 91 | compr=none override default compressor and set it to "none" |
92 | compr=lzo override default compressor and set it to "lzo" | 92 | compr=lzo override default compressor and set it to "lzo" |
93 | compr=zlib override default compressor and set it to "zlib" | 93 | compr=zlib override default compressor and set it to "zlib" |
94 | auth_key= specify the key used for authenticating the filesystem. | ||
95 | Passing this option makes authentication mandatory. | ||
96 | The passed key must be present in the kernel keyring | ||
97 | and must be of type 'logon' | ||
98 | auth_hash_name= The hash algorithm used for authentication. Used for | ||
99 | both hashing and for creating HMACs. Typical values | ||
100 | include "sha256" or "sha512" | ||
94 | 101 | ||
95 | 102 | ||
96 | Quick usage instructions | 103 | Quick usage instructions |
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 93ceea4f27d5..e294d3986ba9 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c | |||
@@ -1072,6 +1072,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
1072 | * be a result of power cut during erasure. | 1072 | * be a result of power cut during erasure. |
1073 | */ | 1073 | */ |
1074 | ai->maybe_bad_peb_count += 1; | 1074 | ai->maybe_bad_peb_count += 1; |
1075 | /* fall through */ | ||
1075 | case UBI_IO_BAD_HDR: | 1076 | case UBI_IO_BAD_HDR: |
1076 | /* | 1077 | /* |
1077 | * If we're facing a bad VID header we have to drop *all* | 1078 | * If we're facing a bad VID header we have to drop *all* |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index d2a726654ff1..a4e3454133a4 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -1334,8 +1334,10 @@ static int bytes_str_to_int(const char *str) | |||
1334 | switch (*endp) { | 1334 | switch (*endp) { |
1335 | case 'G': | 1335 | case 'G': |
1336 | result *= 1024; | 1336 | result *= 1024; |
1337 | /* fall through */ | ||
1337 | case 'M': | 1338 | case 'M': |
1338 | result *= 1024; | 1339 | result *= 1024; |
1340 | /* fall through */ | ||
1339 | case 'K': | 1341 | case 'K': |
1340 | result *= 1024; | 1342 | result *= 1024; |
1341 | if (endp[1] == 'i' && endp[2] == 'B') | 1343 | if (endp[1] == 'i' && endp[2] == 'B') |
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig index bbc78549be4c..529856fbccd0 100644 --- a/fs/ubifs/Kconfig +++ b/fs/ubifs/Kconfig | |||
@@ -7,6 +7,7 @@ config UBIFS_FS | |||
7 | select CRYPTO if UBIFS_FS_ZLIB | 7 | select CRYPTO if UBIFS_FS_ZLIB |
8 | select CRYPTO_LZO if UBIFS_FS_LZO | 8 | select CRYPTO_LZO if UBIFS_FS_LZO |
9 | select CRYPTO_DEFLATE if UBIFS_FS_ZLIB | 9 | select CRYPTO_DEFLATE if UBIFS_FS_ZLIB |
10 | select CRYPTO_HASH_INFO | ||
10 | depends on MTD_UBI | 11 | depends on MTD_UBI |
11 | help | 12 | help |
12 | UBIFS is a file system for flash devices which works on top of UBI. | 13 | UBIFS is a file system for flash devices which works on top of UBI. |
@@ -85,3 +86,13 @@ config UBIFS_FS_SECURITY | |||
85 | the extended attribute support in advance. | 86 | the extended attribute support in advance. |
86 | 87 | ||
87 | If you are not using a security module, say N. | 88 | If you are not using a security module, say N. |
89 | |||
90 | config UBIFS_FS_AUTHENTICATION | ||
91 | bool "UBIFS authentication support" | ||
92 | select CRYPTO_HMAC | ||
93 | help | ||
94 | Enable authentication support for UBIFS. This feature offers protection | ||
95 | against offline changes for both data and metadata of the filesystem. | ||
96 | If you say yes here you should also select a hashing algorithm such as | ||
97 | sha256, these are not selected automatically since there are many | ||
98 | different options. | ||
diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile index 6197d7e539e4..5f838319c8d5 100644 --- a/fs/ubifs/Makefile +++ b/fs/ubifs/Makefile | |||
@@ -8,3 +8,4 @@ ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o | |||
8 | ubifs-y += misc.o | 8 | ubifs-y += misc.o |
9 | ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o | 9 | ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o |
10 | ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o | 10 | ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o |
11 | ubifs-$(CONFIG_UBIFS_FS_AUTHENTICATION) += auth.o | ||
diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c new file mode 100644 index 000000000000..124e965a28b3 --- /dev/null +++ b/fs/ubifs/auth.c | |||
@@ -0,0 +1,502 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * This file is part of UBIFS. | ||
4 | * | ||
5 | * Copyright (C) 2018 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This file implements various helper functions for UBIFS authentication support | ||
10 | */ | ||
11 | |||
12 | #include <linux/crypto.h> | ||
13 | #include <crypto/hash.h> | ||
14 | #include <crypto/sha.h> | ||
15 | #include <crypto/algapi.h> | ||
16 | #include <keys/user-type.h> | ||
17 | |||
18 | #include "ubifs.h" | ||
19 | |||
20 | /** | ||
21 | * ubifs_node_calc_hash - calculate the hash of a UBIFS node | ||
22 | * @c: UBIFS file-system description object | ||
23 | * @node: the node to calculate a hash for | ||
24 | * @hash: the returned hash | ||
25 | * | ||
26 | * Returns 0 for success or a negative error code otherwise. | ||
27 | */ | ||
28 | int __ubifs_node_calc_hash(const struct ubifs_info *c, const void *node, | ||
29 | u8 *hash) | ||
30 | { | ||
31 | const struct ubifs_ch *ch = node; | ||
32 | SHASH_DESC_ON_STACK(shash, c->hash_tfm); | ||
33 | int err; | ||
34 | |||
35 | shash->tfm = c->hash_tfm; | ||
36 | shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
37 | |||
38 | err = crypto_shash_digest(shash, node, le32_to_cpu(ch->len), hash); | ||
39 | if (err < 0) | ||
40 | return err; | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * ubifs_hash_calc_hmac - calculate a HMAC from a hash | ||
46 | * @c: UBIFS file-system description object | ||
47 | * @hash: the node to calculate a HMAC for | ||
48 | * @hmac: the returned HMAC | ||
49 | * | ||
50 | * Returns 0 for success or a negative error code otherwise. | ||
51 | */ | ||
52 | static int ubifs_hash_calc_hmac(const struct ubifs_info *c, const u8 *hash, | ||
53 | u8 *hmac) | ||
54 | { | ||
55 | SHASH_DESC_ON_STACK(shash, c->hmac_tfm); | ||
56 | int err; | ||
57 | |||
58 | shash->tfm = c->hmac_tfm; | ||
59 | shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
60 | |||
61 | err = crypto_shash_digest(shash, hash, c->hash_len, hmac); | ||
62 | if (err < 0) | ||
63 | return err; | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * ubifs_prepare_auth_node - Prepare an authentication node | ||
69 | * @c: UBIFS file-system description object | ||
70 | * @node: the node to calculate a hash for | ||
71 | * @hash: input hash of previous nodes | ||
72 | * | ||
73 | * This function prepares an authentication node for writing onto flash. | ||
74 | * It creates a HMAC from the given input hash and writes it to the node. | ||
75 | * | ||
76 | * Returns 0 for success or a negative error code otherwise. | ||
77 | */ | ||
78 | int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, | ||
79 | struct shash_desc *inhash) | ||
80 | { | ||
81 | SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm); | ||
82 | struct ubifs_auth_node *auth = node; | ||
83 | u8 *hash; | ||
84 | int err; | ||
85 | |||
86 | hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS); | ||
87 | if (!hash) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | hash_desc->tfm = c->hash_tfm; | ||
91 | hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
92 | ubifs_shash_copy_state(c, inhash, hash_desc); | ||
93 | |||
94 | err = crypto_shash_final(hash_desc, hash); | ||
95 | if (err) | ||
96 | goto out; | ||
97 | |||
98 | err = ubifs_hash_calc_hmac(c, hash, auth->hmac); | ||
99 | if (err) | ||
100 | goto out; | ||
101 | |||
102 | auth->ch.node_type = UBIFS_AUTH_NODE; | ||
103 | ubifs_prepare_node(c, auth, ubifs_auth_node_sz(c), 0); | ||
104 | |||
105 | err = 0; | ||
106 | out: | ||
107 | kfree(hash); | ||
108 | |||
109 | return err; | ||
110 | } | ||
111 | |||
112 | static struct shash_desc *ubifs_get_desc(const struct ubifs_info *c, | ||
113 | struct crypto_shash *tfm) | ||
114 | { | ||
115 | struct shash_desc *desc; | ||
116 | int err; | ||
117 | |||
118 | if (!ubifs_authenticated(c)) | ||
119 | return NULL; | ||
120 | |||
121 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); | ||
122 | if (!desc) | ||
123 | return ERR_PTR(-ENOMEM); | ||
124 | |||
125 | desc->tfm = tfm; | ||
126 | desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
127 | |||
128 | err = crypto_shash_init(desc); | ||
129 | if (err) { | ||
130 | kfree(desc); | ||
131 | return ERR_PTR(err); | ||
132 | } | ||
133 | |||
134 | return desc; | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * __ubifs_hash_get_desc - get a descriptor suitable for hashing a node | ||
139 | * @c: UBIFS file-system description object | ||
140 | * | ||
141 | * This function returns a descriptor suitable for hashing a node. Free after use | ||
142 | * with kfree. | ||
143 | */ | ||
144 | struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c) | ||
145 | { | ||
146 | return ubifs_get_desc(c, c->hash_tfm); | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * __ubifs_shash_final - finalize shash | ||
151 | * @c: UBIFS file-system description object | ||
152 | * @desc: the descriptor | ||
153 | * @out: the output hash | ||
154 | * | ||
155 | * Simple wrapper around crypto_shash_final(), safe to be called with | ||
156 | * disabled authentication. | ||
157 | */ | ||
158 | int __ubifs_shash_final(const struct ubifs_info *c, struct shash_desc *desc, | ||
159 | u8 *out) | ||
160 | { | ||
161 | if (ubifs_authenticated(c)) | ||
162 | return crypto_shash_final(desc, out); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * ubifs_bad_hash - Report hash mismatches | ||
169 | * @c: UBIFS file-system description object | ||
170 | * @node: the node | ||
171 | * @hash: the expected hash | ||
172 | * @lnum: the LEB @node was read from | ||
173 | * @offs: offset in LEB @node was read from | ||
174 | * | ||
175 | * This function reports a hash mismatch when a node has a different hash than | ||
176 | * expected. | ||
177 | */ | ||
178 | void ubifs_bad_hash(const struct ubifs_info *c, const void *node, const u8 *hash, | ||
179 | int lnum, int offs) | ||
180 | { | ||
181 | int len = min(c->hash_len, 20); | ||
182 | int cropped = len != c->hash_len; | ||
183 | const char *cont = cropped ? "..." : ""; | ||
184 | |||
185 | u8 calc[UBIFS_HASH_ARR_SZ]; | ||
186 | |||
187 | __ubifs_node_calc_hash(c, node, calc); | ||
188 | |||
189 | ubifs_err(c, "hash mismatch on node at LEB %d:%d", lnum, offs); | ||
190 | ubifs_err(c, "hash expected: %*ph%s", len, hash, cont); | ||
191 | ubifs_err(c, "hash calculated: %*ph%s", len, calc, cont); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * __ubifs_node_check_hash - check the hash of a node against given hash | ||
196 | * @c: UBIFS file-system description object | ||
197 | * @node: the node | ||
198 | * @expected: the expected hash | ||
199 | * | ||
200 | * This function calculates a hash over a node and compares it to the given hash. | ||
201 | * Returns 0 if both hashes are equal or authentication is disabled, otherwise a | ||
202 | * negative error code is returned. | ||
203 | */ | ||
204 | int __ubifs_node_check_hash(const struct ubifs_info *c, const void *node, | ||
205 | const u8 *expected) | ||
206 | { | ||
207 | u8 calc[UBIFS_HASH_ARR_SZ]; | ||
208 | int err; | ||
209 | |||
210 | err = __ubifs_node_calc_hash(c, node, calc); | ||
211 | if (err) | ||
212 | return err; | ||
213 | |||
214 | if (ubifs_check_hash(c, expected, calc)) | ||
215 | return -EPERM; | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * ubifs_init_authentication - initialize UBIFS authentication support | ||
222 | * @c: UBIFS file-system description object | ||
223 | * | ||
224 | * This function returns 0 for success or a negative error code otherwise. | ||
225 | */ | ||
226 | int ubifs_init_authentication(struct ubifs_info *c) | ||
227 | { | ||
228 | struct key *keyring_key; | ||
229 | const struct user_key_payload *ukp; | ||
230 | int err; | ||
231 | char hmac_name[CRYPTO_MAX_ALG_NAME]; | ||
232 | |||
233 | if (!c->auth_hash_name) { | ||
234 | ubifs_err(c, "authentication hash name needed with authentication"); | ||
235 | return -EINVAL; | ||
236 | } | ||
237 | |||
238 | c->auth_hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST, | ||
239 | c->auth_hash_name); | ||
240 | if ((int)c->auth_hash_algo < 0) { | ||
241 | ubifs_err(c, "Unknown hash algo %s specified", | ||
242 | c->auth_hash_name); | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | |||
246 | snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)", | ||
247 | c->auth_hash_name); | ||
248 | |||
249 | keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL); | ||
250 | |||
251 | if (IS_ERR(keyring_key)) { | ||
252 | ubifs_err(c, "Failed to request key: %ld", | ||
253 | PTR_ERR(keyring_key)); | ||
254 | return PTR_ERR(keyring_key); | ||
255 | } | ||
256 | |||
257 | down_read(&keyring_key->sem); | ||
258 | |||
259 | if (keyring_key->type != &key_type_logon) { | ||
260 | ubifs_err(c, "key type must be logon"); | ||
261 | err = -ENOKEY; | ||
262 | goto out; | ||
263 | } | ||
264 | |||
265 | ukp = user_key_payload_locked(keyring_key); | ||
266 | if (!ukp) { | ||
267 | /* key was revoked before we acquired its semaphore */ | ||
268 | err = -EKEYREVOKED; | ||
269 | goto out; | ||
270 | } | ||
271 | |||
272 | c->hash_tfm = crypto_alloc_shash(c->auth_hash_name, 0, | ||
273 | CRYPTO_ALG_ASYNC); | ||
274 | if (IS_ERR(c->hash_tfm)) { | ||
275 | err = PTR_ERR(c->hash_tfm); | ||
276 | ubifs_err(c, "Can not allocate %s: %d", | ||
277 | c->auth_hash_name, err); | ||
278 | goto out; | ||
279 | } | ||
280 | |||
281 | c->hash_len = crypto_shash_digestsize(c->hash_tfm); | ||
282 | if (c->hash_len > UBIFS_HASH_ARR_SZ) { | ||
283 | ubifs_err(c, "hash %s is bigger than maximum allowed hash size (%d > %d)", | ||
284 | c->auth_hash_name, c->hash_len, UBIFS_HASH_ARR_SZ); | ||
285 | err = -EINVAL; | ||
286 | goto out_free_hash; | ||
287 | } | ||
288 | |||
289 | c->hmac_tfm = crypto_alloc_shash(hmac_name, 0, CRYPTO_ALG_ASYNC); | ||
290 | if (IS_ERR(c->hmac_tfm)) { | ||
291 | err = PTR_ERR(c->hmac_tfm); | ||
292 | ubifs_err(c, "Can not allocate %s: %d", hmac_name, err); | ||
293 | goto out_free_hash; | ||
294 | } | ||
295 | |||
296 | c->hmac_desc_len = crypto_shash_digestsize(c->hmac_tfm); | ||
297 | if (c->hmac_desc_len > UBIFS_HMAC_ARR_SZ) { | ||
298 | ubifs_err(c, "hmac %s is bigger than maximum allowed hmac size (%d > %d)", | ||
299 | hmac_name, c->hmac_desc_len, UBIFS_HMAC_ARR_SZ); | ||
300 | err = -EINVAL; | ||
301 | goto out_free_hash; | ||
302 | } | ||
303 | |||
304 | err = crypto_shash_setkey(c->hmac_tfm, ukp->data, ukp->datalen); | ||
305 | if (err) | ||
306 | goto out_free_hmac; | ||
307 | |||
308 | c->authenticated = true; | ||
309 | |||
310 | c->log_hash = ubifs_hash_get_desc(c); | ||
311 | if (IS_ERR(c->log_hash)) | ||
312 | goto out_free_hmac; | ||
313 | |||
314 | err = 0; | ||
315 | |||
316 | out_free_hmac: | ||
317 | if (err) | ||
318 | crypto_free_shash(c->hmac_tfm); | ||
319 | out_free_hash: | ||
320 | if (err) | ||
321 | crypto_free_shash(c->hash_tfm); | ||
322 | out: | ||
323 | up_read(&keyring_key->sem); | ||
324 | key_put(keyring_key); | ||
325 | |||
326 | return err; | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * __ubifs_exit_authentication - release resource | ||
331 | * @c: UBIFS file-system description object | ||
332 | * | ||
333 | * This function releases the authentication related resources. | ||
334 | */ | ||
335 | void __ubifs_exit_authentication(struct ubifs_info *c) | ||
336 | { | ||
337 | if (!ubifs_authenticated(c)) | ||
338 | return; | ||
339 | |||
340 | crypto_free_shash(c->hmac_tfm); | ||
341 | crypto_free_shash(c->hash_tfm); | ||
342 | kfree(c->log_hash); | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * ubifs_node_calc_hmac - calculate the HMAC of a UBIFS node | ||
347 | * @c: UBIFS file-system description object | ||
348 | * @node: the node to insert a HMAC into. | ||
349 | * @len: the length of the node | ||
350 | * @ofs_hmac: the offset in the node where the HMAC is inserted | ||
351 | * @hmac: returned HMAC | ||
352 | * | ||
353 | * This function calculates a HMAC of a UBIFS node. The HMAC is expected to be | ||
354 | * embedded into the node, so this area is not covered by the HMAC. Also not | ||
355 | * covered is the UBIFS_NODE_MAGIC and the CRC of the node. | ||
356 | */ | ||
357 | static int ubifs_node_calc_hmac(const struct ubifs_info *c, const void *node, | ||
358 | int len, int ofs_hmac, void *hmac) | ||
359 | { | ||
360 | SHASH_DESC_ON_STACK(shash, c->hmac_tfm); | ||
361 | int hmac_len = c->hmac_desc_len; | ||
362 | int err; | ||
363 | |||
364 | ubifs_assert(c, ofs_hmac > 8); | ||
365 | ubifs_assert(c, ofs_hmac + hmac_len < len); | ||
366 | |||
367 | shash->tfm = c->hmac_tfm; | ||
368 | shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
369 | |||
370 | err = crypto_shash_init(shash); | ||
371 | if (err) | ||
372 | return err; | ||
373 | |||
374 | /* behind common node header CRC up to HMAC begin */ | ||
375 | err = crypto_shash_update(shash, node + 8, ofs_hmac - 8); | ||
376 | if (err < 0) | ||
377 | return err; | ||
378 | |||
379 | /* behind HMAC, if any */ | ||
380 | if (len - ofs_hmac - hmac_len > 0) { | ||
381 | err = crypto_shash_update(shash, node + ofs_hmac + hmac_len, | ||
382 | len - ofs_hmac - hmac_len); | ||
383 | if (err < 0) | ||
384 | return err; | ||
385 | } | ||
386 | |||
387 | return crypto_shash_final(shash, hmac); | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * __ubifs_node_insert_hmac - insert a HMAC into a UBIFS node | ||
392 | * @c: UBIFS file-system description object | ||
393 | * @node: the node to insert a HMAC into. | ||
394 | * @len: the length of the node | ||
395 | * @ofs_hmac: the offset in the node where the HMAC is inserted | ||
396 | * | ||
397 | * This function inserts a HMAC at offset @ofs_hmac into the node given in | ||
398 | * @node. | ||
399 | * | ||
400 | * This function returns 0 for success or a negative error code otherwise. | ||
401 | */ | ||
402 | int __ubifs_node_insert_hmac(const struct ubifs_info *c, void *node, int len, | ||
403 | int ofs_hmac) | ||
404 | { | ||
405 | return ubifs_node_calc_hmac(c, node, len, ofs_hmac, node + ofs_hmac); | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * __ubifs_node_verify_hmac - verify the HMAC of UBIFS node | ||
410 | * @c: UBIFS file-system description object | ||
411 | * @node: the node to insert a HMAC into. | ||
412 | * @len: the length of the node | ||
413 | * @ofs_hmac: the offset in the node where the HMAC is inserted | ||
414 | * | ||
415 | * This function verifies the HMAC at offset @ofs_hmac of the node given in | ||
416 | * @node. Returns 0 if successful or a negative error code otherwise. | ||
417 | */ | ||
418 | int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *node, | ||
419 | int len, int ofs_hmac) | ||
420 | { | ||
421 | int hmac_len = c->hmac_desc_len; | ||
422 | u8 *hmac; | ||
423 | int err; | ||
424 | |||
425 | hmac = kmalloc(hmac_len, GFP_NOFS); | ||
426 | if (!hmac) | ||
427 | return -ENOMEM; | ||
428 | |||
429 | err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac); | ||
430 | if (err) | ||
431 | return err; | ||
432 | |||
433 | err = crypto_memneq(hmac, node + ofs_hmac, hmac_len); | ||
434 | |||
435 | kfree(hmac); | ||
436 | |||
437 | if (!err) | ||
438 | return 0; | ||
439 | |||
440 | return -EPERM; | ||
441 | } | ||
442 | |||
443 | int __ubifs_shash_copy_state(const struct ubifs_info *c, struct shash_desc *src, | ||
444 | struct shash_desc *target) | ||
445 | { | ||
446 | u8 *state; | ||
447 | int err; | ||
448 | |||
449 | state = kmalloc(crypto_shash_descsize(src->tfm), GFP_NOFS); | ||
450 | if (!state) | ||
451 | return -ENOMEM; | ||
452 | |||
453 | err = crypto_shash_export(src, state); | ||
454 | if (err) | ||
455 | goto out; | ||
456 | |||
457 | err = crypto_shash_import(target, state); | ||
458 | |||
459 | out: | ||
460 | kfree(state); | ||
461 | |||
462 | return err; | ||
463 | } | ||
464 | |||
465 | /** | ||
466 | * ubifs_hmac_wkm - Create a HMAC of the well known message | ||
467 | * @c: UBIFS file-system description object | ||
468 | * @hmac: The HMAC of the well known message | ||
469 | * | ||
470 | * This function creates a HMAC of a well known message. This is used | ||
471 | * to check if the provided key is suitable to authenticate a UBIFS | ||
472 | * image. This is only a convenience to the user to provide a better | ||
473 | * error message when the wrong key is provided. | ||
474 | * | ||
475 | * This function returns 0 for success or a negative error code otherwise. | ||
476 | */ | ||
477 | int ubifs_hmac_wkm(struct ubifs_info *c, u8 *hmac) | ||
478 | { | ||
479 | SHASH_DESC_ON_STACK(shash, c->hmac_tfm); | ||
480 | int err; | ||
481 | const char well_known_message[] = "UBIFS"; | ||
482 | |||
483 | if (!ubifs_authenticated(c)) | ||
484 | return 0; | ||
485 | |||
486 | shash->tfm = c->hmac_tfm; | ||
487 | shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
488 | |||
489 | err = crypto_shash_init(shash); | ||
490 | if (err) | ||
491 | return err; | ||
492 | |||
493 | err = crypto_shash_update(shash, well_known_message, | ||
494 | sizeof(well_known_message) - 1); | ||
495 | if (err < 0) | ||
496 | return err; | ||
497 | |||
498 | err = crypto_shash_final(shash, hmac); | ||
499 | if (err) | ||
500 | return err; | ||
501 | return 0; | ||
502 | } | ||
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 564e330d05b1..c49ff50fdceb 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -165,6 +165,8 @@ const char *dbg_ntype(int type) | |||
165 | return "commit start node"; | 165 | return "commit start node"; |
166 | case UBIFS_ORPH_NODE: | 166 | case UBIFS_ORPH_NODE: |
167 | return "orphan node"; | 167 | return "orphan node"; |
168 | case UBIFS_AUTH_NODE: | ||
169 | return "auth node"; | ||
168 | default: | 170 | default: |
169 | return "unknown node"; | 171 | return "unknown node"; |
170 | } | 172 | } |
@@ -542,6 +544,10 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node) | |||
542 | (unsigned long long)le64_to_cpu(orph->inos[i])); | 544 | (unsigned long long)le64_to_cpu(orph->inos[i])); |
543 | break; | 545 | break; |
544 | } | 546 | } |
547 | case UBIFS_AUTH_NODE: | ||
548 | { | ||
549 | break; | ||
550 | } | ||
545 | default: | 551 | default: |
546 | pr_err("node type %d was not recognized\n", | 552 | pr_err("node type %d was not recognized\n", |
547 | (int)ch->node_type); | 553 | (int)ch->node_type); |
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index d2680e0b4a36..bf75fdc76fc3 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
@@ -254,7 +254,8 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb, | |||
254 | snod->type == UBIFS_DATA_NODE || | 254 | snod->type == UBIFS_DATA_NODE || |
255 | snod->type == UBIFS_DENT_NODE || | 255 | snod->type == UBIFS_DENT_NODE || |
256 | snod->type == UBIFS_XENT_NODE || | 256 | snod->type == UBIFS_XENT_NODE || |
257 | snod->type == UBIFS_TRUN_NODE); | 257 | snod->type == UBIFS_TRUN_NODE || |
258 | snod->type == UBIFS_AUTH_NODE); | ||
258 | 259 | ||
259 | if (snod->type != UBIFS_INO_NODE && | 260 | if (snod->type != UBIFS_INO_NODE && |
260 | snod->type != UBIFS_DATA_NODE && | 261 | snod->type != UBIFS_DATA_NODE && |
@@ -364,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
364 | 365 | ||
365 | /* Write nodes to their new location. Use the first-fit strategy */ | 366 | /* Write nodes to their new location. Use the first-fit strategy */ |
366 | while (1) { | 367 | while (1) { |
367 | int avail; | 368 | int avail, moved = 0; |
368 | struct ubifs_scan_node *snod, *tmp; | 369 | struct ubifs_scan_node *snod, *tmp; |
369 | 370 | ||
370 | /* Move data nodes */ | 371 | /* Move data nodes */ |
371 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { | 372 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { |
372 | avail = c->leb_size - wbuf->offs - wbuf->used; | 373 | avail = c->leb_size - wbuf->offs - wbuf->used - |
374 | ubifs_auth_node_sz(c); | ||
373 | if (snod->len > avail) | 375 | if (snod->len > avail) |
374 | /* | 376 | /* |
375 | * Do not skip data nodes in order to optimize | 377 | * Do not skip data nodes in order to optimize |
@@ -377,14 +379,21 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
377 | */ | 379 | */ |
378 | break; | 380 | break; |
379 | 381 | ||
382 | err = ubifs_shash_update(c, c->jheads[GCHD].log_hash, | ||
383 | snod->node, snod->len); | ||
384 | if (err) | ||
385 | goto out; | ||
386 | |||
380 | err = move_node(c, sleb, snod, wbuf); | 387 | err = move_node(c, sleb, snod, wbuf); |
381 | if (err) | 388 | if (err) |
382 | goto out; | 389 | goto out; |
390 | moved = 1; | ||
383 | } | 391 | } |
384 | 392 | ||
385 | /* Move non-data nodes */ | 393 | /* Move non-data nodes */ |
386 | list_for_each_entry_safe(snod, tmp, &nondata, list) { | 394 | list_for_each_entry_safe(snod, tmp, &nondata, list) { |
387 | avail = c->leb_size - wbuf->offs - wbuf->used; | 395 | avail = c->leb_size - wbuf->offs - wbuf->used - |
396 | ubifs_auth_node_sz(c); | ||
388 | if (avail < min) | 397 | if (avail < min) |
389 | break; | 398 | break; |
390 | 399 | ||
@@ -402,9 +411,41 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
402 | continue; | 411 | continue; |
403 | } | 412 | } |
404 | 413 | ||
414 | err = ubifs_shash_update(c, c->jheads[GCHD].log_hash, | ||
415 | snod->node, snod->len); | ||
416 | if (err) | ||
417 | goto out; | ||
418 | |||
405 | err = move_node(c, sleb, snod, wbuf); | 419 | err = move_node(c, sleb, snod, wbuf); |
406 | if (err) | 420 | if (err) |
407 | goto out; | 421 | goto out; |
422 | moved = 1; | ||
423 | } | ||
424 | |||
425 | if (ubifs_authenticated(c) && moved) { | ||
426 | struct ubifs_auth_node *auth; | ||
427 | |||
428 | auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); | ||
429 | if (!auth) { | ||
430 | err = -ENOMEM; | ||
431 | goto out; | ||
432 | } | ||
433 | |||
434 | err = ubifs_prepare_auth_node(c, auth, | ||
435 | c->jheads[GCHD].log_hash); | ||
436 | if (err) { | ||
437 | kfree(auth); | ||
438 | goto out; | ||
439 | } | ||
440 | |||
441 | err = ubifs_wbuf_write_nolock(wbuf, auth, | ||
442 | ubifs_auth_node_sz(c)); | ||
443 | if (err) { | ||
444 | kfree(auth); | ||
445 | goto out; | ||
446 | } | ||
447 | |||
448 | ubifs_add_dirt(c, wbuf->lnum, ubifs_auth_node_sz(c)); | ||
408 | } | 449 | } |
409 | 450 | ||
410 | if (list_empty(&sleb->nodes) && list_empty(&nondata)) | 451 | if (list_empty(&sleb->nodes) && list_empty(&nondata)) |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 099bec94b820..d124117efd42 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -365,20 +365,8 @@ static unsigned long long next_sqnum(struct ubifs_info *c) | |||
365 | return sqnum; | 365 | return sqnum; |
366 | } | 366 | } |
367 | 367 | ||
368 | /** | 368 | void ubifs_init_node(struct ubifs_info *c, void *node, int len, int pad) |
369 | * ubifs_prepare_node - prepare node to be written to flash. | ||
370 | * @c: UBIFS file-system description object | ||
371 | * @node: the node to pad | ||
372 | * @len: node length | ||
373 | * @pad: if the buffer has to be padded | ||
374 | * | ||
375 | * This function prepares node at @node to be written to the media - it | ||
376 | * calculates node CRC, fills the common header, and adds proper padding up to | ||
377 | * the next minimum I/O unit if @pad is not zero. | ||
378 | */ | ||
379 | void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad) | ||
380 | { | 369 | { |
381 | uint32_t crc; | ||
382 | struct ubifs_ch *ch = node; | 370 | struct ubifs_ch *ch = node; |
383 | unsigned long long sqnum = next_sqnum(c); | 371 | unsigned long long sqnum = next_sqnum(c); |
384 | 372 | ||
@@ -389,8 +377,6 @@ void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad) | |||
389 | ch->group_type = UBIFS_NO_NODE_GROUP; | 377 | ch->group_type = UBIFS_NO_NODE_GROUP; |
390 | ch->sqnum = cpu_to_le64(sqnum); | 378 | ch->sqnum = cpu_to_le64(sqnum); |
391 | ch->padding[0] = ch->padding[1] = 0; | 379 | ch->padding[0] = ch->padding[1] = 0; |
392 | crc = crc32(UBIFS_CRC32_INIT, node + 8, len - 8); | ||
393 | ch->crc = cpu_to_le32(crc); | ||
394 | 380 | ||
395 | if (pad) { | 381 | if (pad) { |
396 | len = ALIGN(len, 8); | 382 | len = ALIGN(len, 8); |
@@ -399,6 +385,68 @@ void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad) | |||
399 | } | 385 | } |
400 | } | 386 | } |
401 | 387 | ||
388 | void ubifs_crc_node(struct ubifs_info *c, void *node, int len) | ||
389 | { | ||
390 | struct ubifs_ch *ch = node; | ||
391 | uint32_t crc; | ||
392 | |||
393 | crc = crc32(UBIFS_CRC32_INIT, node + 8, len - 8); | ||
394 | ch->crc = cpu_to_le32(crc); | ||
395 | } | ||
396 | |||
397 | /** | ||
398 | * ubifs_prepare_node_hmac - prepare node to be written to flash. | ||
399 | * @c: UBIFS file-system description object | ||
400 | * @node: the node to pad | ||
401 | * @len: node length | ||
402 | * @hmac_offs: offset of the HMAC in the node | ||
403 | * @pad: if the buffer has to be padded | ||
404 | * | ||
405 | * This function prepares node at @node to be written to the media - it | ||
406 | * calculates node CRC, fills the common header, and adds proper padding up to | ||
407 | * the next minimum I/O unit if @pad is not zero. if @hmac_offs is positive then | ||
408 | * a HMAC is inserted into the node at the given offset. | ||
409 | * | ||
410 | * This function returns 0 for success or a negative error code otherwise. | ||
411 | */ | ||
412 | int ubifs_prepare_node_hmac(struct ubifs_info *c, void *node, int len, | ||
413 | int hmac_offs, int pad) | ||
414 | { | ||
415 | int err; | ||
416 | |||
417 | ubifs_init_node(c, node, len, pad); | ||
418 | |||
419 | if (hmac_offs > 0) { | ||
420 | err = ubifs_node_insert_hmac(c, node, len, hmac_offs); | ||
421 | if (err) | ||
422 | return err; | ||
423 | } | ||
424 | |||
425 | ubifs_crc_node(c, node, len); | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | /** | ||
431 | * ubifs_prepare_node - prepare node to be written to flash. | ||
432 | * @c: UBIFS file-system description object | ||
433 | * @node: the node to pad | ||
434 | * @len: node length | ||
435 | * @pad: if the buffer has to be padded | ||
436 | * | ||
437 | * This function prepares node at @node to be written to the media - it | ||
438 | * calculates node CRC, fills the common header, and adds proper padding up to | ||
439 | * the next minimum I/O unit if @pad is not zero. | ||
440 | */ | ||
441 | void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad) | ||
442 | { | ||
443 | /* | ||
444 | * Deliberately ignore return value since this function can only fail | ||
445 | * when a hmac offset is given. | ||
446 | */ | ||
447 | ubifs_prepare_node_hmac(c, node, len, 0, pad); | ||
448 | } | ||
449 | |||
402 | /** | 450 | /** |
403 | * ubifs_prep_grp_node - prepare node of a group to be written to flash. | 451 | * ubifs_prep_grp_node - prepare node of a group to be written to flash. |
404 | * @c: UBIFS file-system description object | 452 | * @c: UBIFS file-system description object |
@@ -849,12 +897,13 @@ out: | |||
849 | } | 897 | } |
850 | 898 | ||
851 | /** | 899 | /** |
852 | * ubifs_write_node - write node to the media. | 900 | * ubifs_write_node_hmac - write node to the media. |
853 | * @c: UBIFS file-system description object | 901 | * @c: UBIFS file-system description object |
854 | * @buf: the node to write | 902 | * @buf: the node to write |
855 | * @len: node length | 903 | * @len: node length |
856 | * @lnum: logical eraseblock number | 904 | * @lnum: logical eraseblock number |
857 | * @offs: offset within the logical eraseblock | 905 | * @offs: offset within the logical eraseblock |
906 | * @hmac_offs: offset of the HMAC within the node | ||
858 | * | 907 | * |
859 | * This function automatically fills node magic number, assigns sequence | 908 | * This function automatically fills node magic number, assigns sequence |
860 | * number, and calculates node CRC checksum. The length of the @buf buffer has | 909 | * number, and calculates node CRC checksum. The length of the @buf buffer has |
@@ -862,8 +911,8 @@ out: | |||
862 | * appends padding node and padding bytes if needed. Returns zero in case of | 911 | * appends padding node and padding bytes if needed. Returns zero in case of |
863 | * success and a negative error code in case of failure. | 912 | * success and a negative error code in case of failure. |
864 | */ | 913 | */ |
865 | int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, | 914 | int ubifs_write_node_hmac(struct ubifs_info *c, void *buf, int len, int lnum, |
866 | int offs) | 915 | int offs, int hmac_offs) |
867 | { | 916 | { |
868 | int err, buf_len = ALIGN(len, c->min_io_size); | 917 | int err, buf_len = ALIGN(len, c->min_io_size); |
869 | 918 | ||
@@ -878,7 +927,10 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, | |||
878 | if (c->ro_error) | 927 | if (c->ro_error) |
879 | return -EROFS; | 928 | return -EROFS; |
880 | 929 | ||
881 | ubifs_prepare_node(c, buf, len, 1); | 930 | err = ubifs_prepare_node_hmac(c, buf, len, hmac_offs, 1); |
931 | if (err) | ||
932 | return err; | ||
933 | |||
882 | err = ubifs_leb_write(c, lnum, buf, offs, buf_len); | 934 | err = ubifs_leb_write(c, lnum, buf, offs, buf_len); |
883 | if (err) | 935 | if (err) |
884 | ubifs_dump_node(c, buf); | 936 | ubifs_dump_node(c, buf); |
@@ -887,6 +939,26 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, | |||
887 | } | 939 | } |
888 | 940 | ||
889 | /** | 941 | /** |
942 | * ubifs_write_node - write node to the media. | ||
943 | * @c: UBIFS file-system description object | ||
944 | * @buf: the node to write | ||
945 | * @len: node length | ||
946 | * @lnum: logical eraseblock number | ||
947 | * @offs: offset within the logical eraseblock | ||
948 | * | ||
949 | * This function automatically fills node magic number, assigns sequence | ||
950 | * number, and calculates node CRC checksum. The length of the @buf buffer has | ||
951 | * to be aligned to the minimal I/O unit size. This function automatically | ||
952 | * appends padding node and padding bytes if needed. Returns zero in case of | ||
953 | * success and a negative error code in case of failure. | ||
954 | */ | ||
955 | int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, | ||
956 | int offs) | ||
957 | { | ||
958 | return ubifs_write_node_hmac(c, buf, len, lnum, offs, -1); | ||
959 | } | ||
960 | |||
961 | /** | ||
890 | * ubifs_read_node_wbuf - read node from the media or write-buffer. | 962 | * ubifs_read_node_wbuf - read node from the media or write-buffer. |
891 | * @wbuf: wbuf to check for un-written data | 963 | * @wbuf: wbuf to check for un-written data |
892 | * @buf: buffer to read to | 964 | * @buf: buffer to read to |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 802565a17733..729dc76c83df 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -90,6 +90,12 @@ static inline void zero_trun_node_unused(struct ubifs_trun_node *trun) | |||
90 | memset(trun->padding, 0, 12); | 90 | memset(trun->padding, 0, 12); |
91 | } | 91 | } |
92 | 92 | ||
93 | static void ubifs_add_auth_dirt(struct ubifs_info *c, int lnum) | ||
94 | { | ||
95 | if (ubifs_authenticated(c)) | ||
96 | ubifs_add_dirt(c, lnum, ubifs_auth_node_sz(c)); | ||
97 | } | ||
98 | |||
93 | /** | 99 | /** |
94 | * reserve_space - reserve space in the journal. | 100 | * reserve_space - reserve space in the journal. |
95 | * @c: UBIFS file-system description object | 101 | * @c: UBIFS file-system description object |
@@ -228,34 +234,33 @@ out_return: | |||
228 | return err; | 234 | return err; |
229 | } | 235 | } |
230 | 236 | ||
231 | /** | 237 | static int ubifs_hash_nodes(struct ubifs_info *c, void *node, |
232 | * write_node - write node to a journal head. | 238 | int len, struct shash_desc *hash) |
233 | * @c: UBIFS file-system description object | ||
234 | * @jhead: journal head | ||
235 | * @node: node to write | ||
236 | * @len: node length | ||
237 | * @lnum: LEB number written is returned here | ||
238 | * @offs: offset written is returned here | ||
239 | * | ||
240 | * This function writes a node to reserved space of journal head @jhead. | ||
241 | * Returns zero in case of success and a negative error code in case of | ||
242 | * failure. | ||
243 | */ | ||
244 | static int write_node(struct ubifs_info *c, int jhead, void *node, int len, | ||
245 | int *lnum, int *offs) | ||
246 | { | 239 | { |
247 | struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; | 240 | int auth_node_size = ubifs_auth_node_sz(c); |
241 | int err; | ||
248 | 242 | ||
249 | ubifs_assert(c, jhead != GCHD); | 243 | while (1) { |
244 | const struct ubifs_ch *ch = node; | ||
245 | int nodelen = le32_to_cpu(ch->len); | ||
250 | 246 | ||
251 | *lnum = c->jheads[jhead].wbuf.lnum; | 247 | ubifs_assert(c, len >= auth_node_size); |
252 | *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; | ||
253 | 248 | ||
254 | dbg_jnl("jhead %s, LEB %d:%d, len %d", | 249 | if (len == auth_node_size) |
255 | dbg_jhead(jhead), *lnum, *offs, len); | 250 | break; |
256 | ubifs_prepare_node(c, node, len, 0); | 251 | |
252 | ubifs_assert(c, len > nodelen); | ||
253 | ubifs_assert(c, ch->magic == cpu_to_le32(UBIFS_NODE_MAGIC)); | ||
257 | 254 | ||
258 | return ubifs_wbuf_write_nolock(wbuf, node, len); | 255 | err = ubifs_shash_update(c, hash, (void *)node, nodelen); |
256 | if (err) | ||
257 | return err; | ||
258 | |||
259 | node += ALIGN(nodelen, 8); | ||
260 | len -= ALIGN(nodelen, 8); | ||
261 | } | ||
262 | |||
263 | return ubifs_prepare_auth_node(c, node, hash); | ||
259 | } | 264 | } |
260 | 265 | ||
261 | /** | 266 | /** |
@@ -268,9 +273,9 @@ static int write_node(struct ubifs_info *c, int jhead, void *node, int len, | |||
268 | * @offs: offset written is returned here | 273 | * @offs: offset written is returned here |
269 | * @sync: non-zero if the write-buffer has to by synchronized | 274 | * @sync: non-zero if the write-buffer has to by synchronized |
270 | * | 275 | * |
271 | * This function is the same as 'write_node()' but it does not assume the | 276 | * This function writes data to the reserved space of journal head @jhead. |
272 | * buffer it is writing is a node, so it does not prepare it (which means | 277 | * Returns zero in case of success and a negative error code in case of |
273 | * initializing common header and calculating CRC). | 278 | * failure. |
274 | */ | 279 | */ |
275 | static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, | 280 | static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, |
276 | int *lnum, int *offs, int sync) | 281 | int *lnum, int *offs, int sync) |
@@ -285,6 +290,12 @@ static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, | |||
285 | dbg_jnl("jhead %s, LEB %d:%d, len %d", | 290 | dbg_jnl("jhead %s, LEB %d:%d, len %d", |
286 | dbg_jhead(jhead), *lnum, *offs, len); | 291 | dbg_jhead(jhead), *lnum, *offs, len); |
287 | 292 | ||
293 | if (ubifs_authenticated(c)) { | ||
294 | err = ubifs_hash_nodes(c, buf, len, c->jheads[jhead].log_hash); | ||
295 | if (err) | ||
296 | return err; | ||
297 | } | ||
298 | |||
288 | err = ubifs_wbuf_write_nolock(wbuf, buf, len); | 299 | err = ubifs_wbuf_write_nolock(wbuf, buf, len); |
289 | if (err) | 300 | if (err) |
290 | return err; | 301 | return err; |
@@ -548,6 +559,9 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
548 | struct ubifs_dent_node *dent; | 559 | struct ubifs_dent_node *dent; |
549 | struct ubifs_ino_node *ino; | 560 | struct ubifs_ino_node *ino; |
550 | union ubifs_key dent_key, ino_key; | 561 | union ubifs_key dent_key, ino_key; |
562 | u8 hash_dent[UBIFS_HASH_ARR_SZ]; | ||
563 | u8 hash_ino[UBIFS_HASH_ARR_SZ]; | ||
564 | u8 hash_ino_host[UBIFS_HASH_ARR_SZ]; | ||
551 | 565 | ||
552 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 566 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); |
553 | 567 | ||
@@ -570,7 +584,10 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
570 | 584 | ||
571 | len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; | 585 | len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; |
572 | /* Make sure to also account for extended attributes */ | 586 | /* Make sure to also account for extended attributes */ |
573 | len += host_ui->data_len; | 587 | if (ubifs_authenticated(c)) |
588 | len += ALIGN(host_ui->data_len, 8) + ubifs_auth_node_sz(c); | ||
589 | else | ||
590 | len += host_ui->data_len; | ||
574 | 591 | ||
575 | dent = kzalloc(len, GFP_NOFS); | 592 | dent = kzalloc(len, GFP_NOFS); |
576 | if (!dent) | 593 | if (!dent) |
@@ -602,11 +619,21 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
602 | 619 | ||
603 | zero_dent_node_unused(dent); | 620 | zero_dent_node_unused(dent); |
604 | ubifs_prep_grp_node(c, dent, dlen, 0); | 621 | ubifs_prep_grp_node(c, dent, dlen, 0); |
622 | err = ubifs_node_calc_hash(c, dent, hash_dent); | ||
623 | if (err) | ||
624 | goto out_release; | ||
605 | 625 | ||
606 | ino = (void *)dent + aligned_dlen; | 626 | ino = (void *)dent + aligned_dlen; |
607 | pack_inode(c, ino, inode, 0); | 627 | pack_inode(c, ino, inode, 0); |
628 | err = ubifs_node_calc_hash(c, ino, hash_ino); | ||
629 | if (err) | ||
630 | goto out_release; | ||
631 | |||
608 | ino = (void *)ino + aligned_ilen; | 632 | ino = (void *)ino + aligned_ilen; |
609 | pack_inode(c, ino, dir, 1); | 633 | pack_inode(c, ino, dir, 1); |
634 | err = ubifs_node_calc_hash(c, ino, hash_ino_host); | ||
635 | if (err) | ||
636 | goto out_release; | ||
610 | 637 | ||
611 | if (last_reference) { | 638 | if (last_reference) { |
612 | err = ubifs_add_orphan(c, inode->i_ino); | 639 | err = ubifs_add_orphan(c, inode->i_ino); |
@@ -628,6 +655,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
628 | } | 655 | } |
629 | release_head(c, BASEHD); | 656 | release_head(c, BASEHD); |
630 | kfree(dent); | 657 | kfree(dent); |
658 | ubifs_add_auth_dirt(c, lnum); | ||
631 | 659 | ||
632 | if (deletion) { | 660 | if (deletion) { |
633 | if (nm->hash) | 661 | if (nm->hash) |
@@ -638,7 +666,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
638 | goto out_ro; | 666 | goto out_ro; |
639 | err = ubifs_add_dirt(c, lnum, dlen); | 667 | err = ubifs_add_dirt(c, lnum, dlen); |
640 | } else | 668 | } else |
641 | err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, nm); | 669 | err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, |
670 | hash_dent, nm); | ||
642 | if (err) | 671 | if (err) |
643 | goto out_ro; | 672 | goto out_ro; |
644 | 673 | ||
@@ -650,14 +679,14 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
650 | */ | 679 | */ |
651 | ino_key_init(c, &ino_key, inode->i_ino); | 680 | ino_key_init(c, &ino_key, inode->i_ino); |
652 | ino_offs = dent_offs + aligned_dlen; | 681 | ino_offs = dent_offs + aligned_dlen; |
653 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen); | 682 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen, hash_ino); |
654 | if (err) | 683 | if (err) |
655 | goto out_ro; | 684 | goto out_ro; |
656 | 685 | ||
657 | ino_key_init(c, &ino_key, dir->i_ino); | 686 | ino_key_init(c, &ino_key, dir->i_ino); |
658 | ino_offs += aligned_ilen; | 687 | ino_offs += aligned_ilen; |
659 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, | 688 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, |
660 | UBIFS_INO_NODE_SZ + host_ui->data_len); | 689 | UBIFS_INO_NODE_SZ + host_ui->data_len, hash_ino_host); |
661 | if (err) | 690 | if (err) |
662 | goto out_ro; | 691 | goto out_ro; |
663 | 692 | ||
@@ -706,10 +735,12 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
706 | const union ubifs_key *key, const void *buf, int len) | 735 | const union ubifs_key *key, const void *buf, int len) |
707 | { | 736 | { |
708 | struct ubifs_data_node *data; | 737 | struct ubifs_data_node *data; |
709 | int err, lnum, offs, compr_type, out_len, compr_len; | 738 | int err, lnum, offs, compr_type, out_len, compr_len, auth_len; |
710 | int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; | 739 | int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; |
740 | int write_len; | ||
711 | struct ubifs_inode *ui = ubifs_inode(inode); | 741 | struct ubifs_inode *ui = ubifs_inode(inode); |
712 | bool encrypted = ubifs_crypt_is_encrypted(inode); | 742 | bool encrypted = ubifs_crypt_is_encrypted(inode); |
743 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
713 | 744 | ||
714 | dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", | 745 | dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", |
715 | (unsigned long)key_inum(c, key), key_block(c, key), len); | 746 | (unsigned long)key_inum(c, key), key_block(c, key), len); |
@@ -718,7 +749,9 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
718 | if (encrypted) | 749 | if (encrypted) |
719 | dlen += UBIFS_CIPHER_BLOCK_SIZE; | 750 | dlen += UBIFS_CIPHER_BLOCK_SIZE; |
720 | 751 | ||
721 | data = kmalloc(dlen, GFP_NOFS | __GFP_NOWARN); | 752 | auth_len = ubifs_auth_node_sz(c); |
753 | |||
754 | data = kmalloc(dlen + auth_len, GFP_NOFS | __GFP_NOWARN); | ||
722 | if (!data) { | 755 | if (!data) { |
723 | /* | 756 | /* |
724 | * Fall-back to the write reserve buffer. Note, we might be | 757 | * Fall-back to the write reserve buffer. Note, we might be |
@@ -757,20 +790,33 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
757 | } | 790 | } |
758 | 791 | ||
759 | dlen = UBIFS_DATA_NODE_SZ + out_len; | 792 | dlen = UBIFS_DATA_NODE_SZ + out_len; |
793 | if (ubifs_authenticated(c)) | ||
794 | write_len = ALIGN(dlen, 8) + auth_len; | ||
795 | else | ||
796 | write_len = dlen; | ||
797 | |||
760 | data->compr_type = cpu_to_le16(compr_type); | 798 | data->compr_type = cpu_to_le16(compr_type); |
761 | 799 | ||
762 | /* Make reservation before allocating sequence numbers */ | 800 | /* Make reservation before allocating sequence numbers */ |
763 | err = make_reservation(c, DATAHD, dlen); | 801 | err = make_reservation(c, DATAHD, write_len); |
764 | if (err) | 802 | if (err) |
765 | goto out_free; | 803 | goto out_free; |
766 | 804 | ||
767 | err = write_node(c, DATAHD, data, dlen, &lnum, &offs); | 805 | ubifs_prepare_node(c, data, dlen, 0); |
806 | err = write_head(c, DATAHD, data, write_len, &lnum, &offs, 0); | ||
807 | if (err) | ||
808 | goto out_release; | ||
809 | |||
810 | err = ubifs_node_calc_hash(c, data, hash); | ||
768 | if (err) | 811 | if (err) |
769 | goto out_release; | 812 | goto out_release; |
813 | |||
770 | ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); | 814 | ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); |
771 | release_head(c, DATAHD); | 815 | release_head(c, DATAHD); |
772 | 816 | ||
773 | err = ubifs_tnc_add(c, key, lnum, offs, dlen); | 817 | ubifs_add_auth_dirt(c, lnum); |
818 | |||
819 | err = ubifs_tnc_add(c, key, lnum, offs, dlen, hash); | ||
774 | if (err) | 820 | if (err) |
775 | goto out_ro; | 821 | goto out_ro; |
776 | 822 | ||
@@ -808,7 +854,9 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
808 | int err, lnum, offs; | 854 | int err, lnum, offs; |
809 | struct ubifs_ino_node *ino; | 855 | struct ubifs_ino_node *ino; |
810 | struct ubifs_inode *ui = ubifs_inode(inode); | 856 | struct ubifs_inode *ui = ubifs_inode(inode); |
811 | int sync = 0, len = UBIFS_INO_NODE_SZ, last_reference = !inode->i_nlink; | 857 | int sync = 0, write_len, ilen = UBIFS_INO_NODE_SZ; |
858 | int last_reference = !inode->i_nlink; | ||
859 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
812 | 860 | ||
813 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); | 861 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); |
814 | 862 | ||
@@ -817,20 +865,30 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
817 | * need to synchronize the write-buffer either. | 865 | * need to synchronize the write-buffer either. |
818 | */ | 866 | */ |
819 | if (!last_reference) { | 867 | if (!last_reference) { |
820 | len += ui->data_len; | 868 | ilen += ui->data_len; |
821 | sync = IS_SYNC(inode); | 869 | sync = IS_SYNC(inode); |
822 | } | 870 | } |
823 | ino = kmalloc(len, GFP_NOFS); | 871 | |
872 | if (ubifs_authenticated(c)) | ||
873 | write_len = ALIGN(ilen, 8) + ubifs_auth_node_sz(c); | ||
874 | else | ||
875 | write_len = ilen; | ||
876 | |||
877 | ino = kmalloc(write_len, GFP_NOFS); | ||
824 | if (!ino) | 878 | if (!ino) |
825 | return -ENOMEM; | 879 | return -ENOMEM; |
826 | 880 | ||
827 | /* Make reservation before allocating sequence numbers */ | 881 | /* Make reservation before allocating sequence numbers */ |
828 | err = make_reservation(c, BASEHD, len); | 882 | err = make_reservation(c, BASEHD, write_len); |
829 | if (err) | 883 | if (err) |
830 | goto out_free; | 884 | goto out_free; |
831 | 885 | ||
832 | pack_inode(c, ino, inode, 1); | 886 | pack_inode(c, ino, inode, 1); |
833 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); | 887 | err = ubifs_node_calc_hash(c, ino, hash); |
888 | if (err) | ||
889 | goto out_release; | ||
890 | |||
891 | err = write_head(c, BASEHD, ino, write_len, &lnum, &offs, sync); | ||
834 | if (err) | 892 | if (err) |
835 | goto out_release; | 893 | goto out_release; |
836 | if (!sync) | 894 | if (!sync) |
@@ -838,17 +896,19 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
838 | inode->i_ino); | 896 | inode->i_ino); |
839 | release_head(c, BASEHD); | 897 | release_head(c, BASEHD); |
840 | 898 | ||
899 | ubifs_add_auth_dirt(c, lnum); | ||
900 | |||
841 | if (last_reference) { | 901 | if (last_reference) { |
842 | err = ubifs_tnc_remove_ino(c, inode->i_ino); | 902 | err = ubifs_tnc_remove_ino(c, inode->i_ino); |
843 | if (err) | 903 | if (err) |
844 | goto out_ro; | 904 | goto out_ro; |
845 | ubifs_delete_orphan(c, inode->i_ino); | 905 | ubifs_delete_orphan(c, inode->i_ino); |
846 | err = ubifs_add_dirt(c, lnum, len); | 906 | err = ubifs_add_dirt(c, lnum, ilen); |
847 | } else { | 907 | } else { |
848 | union ubifs_key key; | 908 | union ubifs_key key; |
849 | 909 | ||
850 | ino_key_init(c, &key, inode->i_ino); | 910 | ino_key_init(c, &key, inode->i_ino); |
851 | err = ubifs_tnc_add(c, &key, lnum, offs, len); | 911 | err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash); |
852 | } | 912 | } |
853 | if (err) | 913 | if (err) |
854 | goto out_ro; | 914 | goto out_ro; |
@@ -958,6 +1018,10 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
958 | int aligned_dlen1, aligned_dlen2; | 1018 | int aligned_dlen1, aligned_dlen2; |
959 | int twoparents = (fst_dir != snd_dir); | 1019 | int twoparents = (fst_dir != snd_dir); |
960 | void *p; | 1020 | void *p; |
1021 | u8 hash_dent1[UBIFS_HASH_ARR_SZ]; | ||
1022 | u8 hash_dent2[UBIFS_HASH_ARR_SZ]; | ||
1023 | u8 hash_p1[UBIFS_HASH_ARR_SZ]; | ||
1024 | u8 hash_p2[UBIFS_HASH_ARR_SZ]; | ||
961 | 1025 | ||
962 | ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0); | 1026 | ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0); |
963 | ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0); | 1027 | ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0); |
@@ -973,6 +1037,8 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
973 | if (twoparents) | 1037 | if (twoparents) |
974 | len += plen; | 1038 | len += plen; |
975 | 1039 | ||
1040 | len += ubifs_auth_node_sz(c); | ||
1041 | |||
976 | dent1 = kzalloc(len, GFP_NOFS); | 1042 | dent1 = kzalloc(len, GFP_NOFS); |
977 | if (!dent1) | 1043 | if (!dent1) |
978 | return -ENOMEM; | 1044 | return -ENOMEM; |
@@ -993,6 +1059,9 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
993 | set_dent_cookie(c, dent1); | 1059 | set_dent_cookie(c, dent1); |
994 | zero_dent_node_unused(dent1); | 1060 | zero_dent_node_unused(dent1); |
995 | ubifs_prep_grp_node(c, dent1, dlen1, 0); | 1061 | ubifs_prep_grp_node(c, dent1, dlen1, 0); |
1062 | err = ubifs_node_calc_hash(c, dent1, hash_dent1); | ||
1063 | if (err) | ||
1064 | goto out_release; | ||
996 | 1065 | ||
997 | /* Make new dent for 2nd entry */ | 1066 | /* Make new dent for 2nd entry */ |
998 | dent2 = (void *)dent1 + aligned_dlen1; | 1067 | dent2 = (void *)dent1 + aligned_dlen1; |
@@ -1006,14 +1075,26 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
1006 | set_dent_cookie(c, dent2); | 1075 | set_dent_cookie(c, dent2); |
1007 | zero_dent_node_unused(dent2); | 1076 | zero_dent_node_unused(dent2); |
1008 | ubifs_prep_grp_node(c, dent2, dlen2, 0); | 1077 | ubifs_prep_grp_node(c, dent2, dlen2, 0); |
1078 | err = ubifs_node_calc_hash(c, dent2, hash_dent2); | ||
1079 | if (err) | ||
1080 | goto out_release; | ||
1009 | 1081 | ||
1010 | p = (void *)dent2 + aligned_dlen2; | 1082 | p = (void *)dent2 + aligned_dlen2; |
1011 | if (!twoparents) | 1083 | if (!twoparents) { |
1012 | pack_inode(c, p, fst_dir, 1); | 1084 | pack_inode(c, p, fst_dir, 1); |
1013 | else { | 1085 | err = ubifs_node_calc_hash(c, p, hash_p1); |
1086 | if (err) | ||
1087 | goto out_release; | ||
1088 | } else { | ||
1014 | pack_inode(c, p, fst_dir, 0); | 1089 | pack_inode(c, p, fst_dir, 0); |
1090 | err = ubifs_node_calc_hash(c, p, hash_p1); | ||
1091 | if (err) | ||
1092 | goto out_release; | ||
1015 | p += ALIGN(plen, 8); | 1093 | p += ALIGN(plen, 8); |
1016 | pack_inode(c, p, snd_dir, 1); | 1094 | pack_inode(c, p, snd_dir, 1); |
1095 | err = ubifs_node_calc_hash(c, p, hash_p2); | ||
1096 | if (err) | ||
1097 | goto out_release; | ||
1017 | } | 1098 | } |
1018 | 1099 | ||
1019 | err = write_head(c, BASEHD, dent1, len, &lnum, &offs, sync); | 1100 | err = write_head(c, BASEHD, dent1, len, &lnum, &offs, sync); |
@@ -1027,28 +1108,30 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
1027 | } | 1108 | } |
1028 | release_head(c, BASEHD); | 1109 | release_head(c, BASEHD); |
1029 | 1110 | ||
1111 | ubifs_add_auth_dirt(c, lnum); | ||
1112 | |||
1030 | dent_key_init(c, &key, snd_dir->i_ino, snd_nm); | 1113 | dent_key_init(c, &key, snd_dir->i_ino, snd_nm); |
1031 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, snd_nm); | 1114 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, snd_nm); |
1032 | if (err) | 1115 | if (err) |
1033 | goto out_ro; | 1116 | goto out_ro; |
1034 | 1117 | ||
1035 | offs += aligned_dlen1; | 1118 | offs += aligned_dlen1; |
1036 | dent_key_init(c, &key, fst_dir->i_ino, fst_nm); | 1119 | dent_key_init(c, &key, fst_dir->i_ino, fst_nm); |
1037 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, fst_nm); | 1120 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, fst_nm); |
1038 | if (err) | 1121 | if (err) |
1039 | goto out_ro; | 1122 | goto out_ro; |
1040 | 1123 | ||
1041 | offs += aligned_dlen2; | 1124 | offs += aligned_dlen2; |
1042 | 1125 | ||
1043 | ino_key_init(c, &key, fst_dir->i_ino); | 1126 | ino_key_init(c, &key, fst_dir->i_ino); |
1044 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1127 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p1); |
1045 | if (err) | 1128 | if (err) |
1046 | goto out_ro; | 1129 | goto out_ro; |
1047 | 1130 | ||
1048 | if (twoparents) { | 1131 | if (twoparents) { |
1049 | offs += ALIGN(plen, 8); | 1132 | offs += ALIGN(plen, 8); |
1050 | ino_key_init(c, &key, snd_dir->i_ino); | 1133 | ino_key_init(c, &key, snd_dir->i_ino); |
1051 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1134 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p2); |
1052 | if (err) | 1135 | if (err) |
1053 | goto out_ro; | 1136 | goto out_ro; |
1054 | } | 1137 | } |
@@ -1101,6 +1184,11 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1101 | int last_reference = !!(new_inode && new_inode->i_nlink == 0); | 1184 | int last_reference = !!(new_inode && new_inode->i_nlink == 0); |
1102 | int move = (old_dir != new_dir); | 1185 | int move = (old_dir != new_dir); |
1103 | struct ubifs_inode *uninitialized_var(new_ui); | 1186 | struct ubifs_inode *uninitialized_var(new_ui); |
1187 | u8 hash_old_dir[UBIFS_HASH_ARR_SZ]; | ||
1188 | u8 hash_new_dir[UBIFS_HASH_ARR_SZ]; | ||
1189 | u8 hash_new_inode[UBIFS_HASH_ARR_SZ]; | ||
1190 | u8 hash_dent1[UBIFS_HASH_ARR_SZ]; | ||
1191 | u8 hash_dent2[UBIFS_HASH_ARR_SZ]; | ||
1104 | 1192 | ||
1105 | ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0); | 1193 | ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0); |
1106 | ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0); | 1194 | ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0); |
@@ -1123,6 +1211,9 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1123 | len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); | 1211 | len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); |
1124 | if (move) | 1212 | if (move) |
1125 | len += plen; | 1213 | len += plen; |
1214 | |||
1215 | len += ubifs_auth_node_sz(c); | ||
1216 | |||
1126 | dent = kzalloc(len, GFP_NOFS); | 1217 | dent = kzalloc(len, GFP_NOFS); |
1127 | if (!dent) | 1218 | if (!dent) |
1128 | return -ENOMEM; | 1219 | return -ENOMEM; |
@@ -1143,6 +1234,9 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1143 | set_dent_cookie(c, dent); | 1234 | set_dent_cookie(c, dent); |
1144 | zero_dent_node_unused(dent); | 1235 | zero_dent_node_unused(dent); |
1145 | ubifs_prep_grp_node(c, dent, dlen1, 0); | 1236 | ubifs_prep_grp_node(c, dent, dlen1, 0); |
1237 | err = ubifs_node_calc_hash(c, dent, hash_dent1); | ||
1238 | if (err) | ||
1239 | goto out_release; | ||
1146 | 1240 | ||
1147 | dent2 = (void *)dent + aligned_dlen1; | 1241 | dent2 = (void *)dent + aligned_dlen1; |
1148 | dent2->ch.node_type = UBIFS_DENT_NODE; | 1242 | dent2->ch.node_type = UBIFS_DENT_NODE; |
@@ -1162,19 +1256,36 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1162 | set_dent_cookie(c, dent2); | 1256 | set_dent_cookie(c, dent2); |
1163 | zero_dent_node_unused(dent2); | 1257 | zero_dent_node_unused(dent2); |
1164 | ubifs_prep_grp_node(c, dent2, dlen2, 0); | 1258 | ubifs_prep_grp_node(c, dent2, dlen2, 0); |
1259 | err = ubifs_node_calc_hash(c, dent2, hash_dent2); | ||
1260 | if (err) | ||
1261 | goto out_release; | ||
1165 | 1262 | ||
1166 | p = (void *)dent2 + aligned_dlen2; | 1263 | p = (void *)dent2 + aligned_dlen2; |
1167 | if (new_inode) { | 1264 | if (new_inode) { |
1168 | pack_inode(c, p, new_inode, 0); | 1265 | pack_inode(c, p, new_inode, 0); |
1266 | err = ubifs_node_calc_hash(c, p, hash_new_inode); | ||
1267 | if (err) | ||
1268 | goto out_release; | ||
1269 | |||
1169 | p += ALIGN(ilen, 8); | 1270 | p += ALIGN(ilen, 8); |
1170 | } | 1271 | } |
1171 | 1272 | ||
1172 | if (!move) | 1273 | if (!move) { |
1173 | pack_inode(c, p, old_dir, 1); | 1274 | pack_inode(c, p, old_dir, 1); |
1174 | else { | 1275 | err = ubifs_node_calc_hash(c, p, hash_old_dir); |
1276 | if (err) | ||
1277 | goto out_release; | ||
1278 | } else { | ||
1175 | pack_inode(c, p, old_dir, 0); | 1279 | pack_inode(c, p, old_dir, 0); |
1280 | err = ubifs_node_calc_hash(c, p, hash_old_dir); | ||
1281 | if (err) | ||
1282 | goto out_release; | ||
1283 | |||
1176 | p += ALIGN(plen, 8); | 1284 | p += ALIGN(plen, 8); |
1177 | pack_inode(c, p, new_dir, 1); | 1285 | pack_inode(c, p, new_dir, 1); |
1286 | err = ubifs_node_calc_hash(c, p, hash_new_dir); | ||
1287 | if (err) | ||
1288 | goto out_release; | ||
1178 | } | 1289 | } |
1179 | 1290 | ||
1180 | if (last_reference) { | 1291 | if (last_reference) { |
@@ -1200,15 +1311,17 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1200 | } | 1311 | } |
1201 | release_head(c, BASEHD); | 1312 | release_head(c, BASEHD); |
1202 | 1313 | ||
1314 | ubifs_add_auth_dirt(c, lnum); | ||
1315 | |||
1203 | dent_key_init(c, &key, new_dir->i_ino, new_nm); | 1316 | dent_key_init(c, &key, new_dir->i_ino, new_nm); |
1204 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, new_nm); | 1317 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, new_nm); |
1205 | if (err) | 1318 | if (err) |
1206 | goto out_ro; | 1319 | goto out_ro; |
1207 | 1320 | ||
1208 | offs += aligned_dlen1; | 1321 | offs += aligned_dlen1; |
1209 | if (whiteout) { | 1322 | if (whiteout) { |
1210 | dent_key_init(c, &key, old_dir->i_ino, old_nm); | 1323 | dent_key_init(c, &key, old_dir->i_ino, old_nm); |
1211 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, old_nm); | 1324 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, old_nm); |
1212 | if (err) | 1325 | if (err) |
1213 | goto out_ro; | 1326 | goto out_ro; |
1214 | 1327 | ||
@@ -1227,21 +1340,21 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1227 | offs += aligned_dlen2; | 1340 | offs += aligned_dlen2; |
1228 | if (new_inode) { | 1341 | if (new_inode) { |
1229 | ino_key_init(c, &key, new_inode->i_ino); | 1342 | ino_key_init(c, &key, new_inode->i_ino); |
1230 | err = ubifs_tnc_add(c, &key, lnum, offs, ilen); | 1343 | err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash_new_inode); |
1231 | if (err) | 1344 | if (err) |
1232 | goto out_ro; | 1345 | goto out_ro; |
1233 | offs += ALIGN(ilen, 8); | 1346 | offs += ALIGN(ilen, 8); |
1234 | } | 1347 | } |
1235 | 1348 | ||
1236 | ino_key_init(c, &key, old_dir->i_ino); | 1349 | ino_key_init(c, &key, old_dir->i_ino); |
1237 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1350 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_old_dir); |
1238 | if (err) | 1351 | if (err) |
1239 | goto out_ro; | 1352 | goto out_ro; |
1240 | 1353 | ||
1241 | if (move) { | 1354 | if (move) { |
1242 | offs += ALIGN(plen, 8); | 1355 | offs += ALIGN(plen, 8); |
1243 | ino_key_init(c, &key, new_dir->i_ino); | 1356 | ino_key_init(c, &key, new_dir->i_ino); |
1244 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1357 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_new_dir); |
1245 | if (err) | 1358 | if (err) |
1246 | goto out_ro; | 1359 | goto out_ro; |
1247 | } | 1360 | } |
@@ -1360,6 +1473,8 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1360 | struct ubifs_inode *ui = ubifs_inode(inode); | 1473 | struct ubifs_inode *ui = ubifs_inode(inode); |
1361 | ino_t inum = inode->i_ino; | 1474 | ino_t inum = inode->i_ino; |
1362 | unsigned int blk; | 1475 | unsigned int blk; |
1476 | u8 hash_ino[UBIFS_HASH_ARR_SZ]; | ||
1477 | u8 hash_dn[UBIFS_HASH_ARR_SZ]; | ||
1363 | 1478 | ||
1364 | dbg_jnl("ino %lu, size %lld -> %lld", | 1479 | dbg_jnl("ino %lu, size %lld -> %lld", |
1365 | (unsigned long)inum, old_size, new_size); | 1480 | (unsigned long)inum, old_size, new_size); |
@@ -1369,6 +1484,9 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1369 | 1484 | ||
1370 | sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + | 1485 | sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + |
1371 | UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; | 1486 | UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; |
1487 | |||
1488 | sz += ubifs_auth_node_sz(c); | ||
1489 | |||
1372 | ino = kmalloc(sz, GFP_NOFS); | 1490 | ino = kmalloc(sz, GFP_NOFS); |
1373 | if (!ino) | 1491 | if (!ino) |
1374 | return -ENOMEM; | 1492 | return -ENOMEM; |
@@ -1414,16 +1532,28 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1414 | 1532 | ||
1415 | /* Must make reservation before allocating sequence numbers */ | 1533 | /* Must make reservation before allocating sequence numbers */ |
1416 | len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ; | 1534 | len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ; |
1417 | if (dlen) | 1535 | |
1536 | if (ubifs_authenticated(c)) | ||
1537 | len += ALIGN(dlen, 8) + ubifs_auth_node_sz(c); | ||
1538 | else | ||
1418 | len += dlen; | 1539 | len += dlen; |
1540 | |||
1419 | err = make_reservation(c, BASEHD, len); | 1541 | err = make_reservation(c, BASEHD, len); |
1420 | if (err) | 1542 | if (err) |
1421 | goto out_free; | 1543 | goto out_free; |
1422 | 1544 | ||
1423 | pack_inode(c, ino, inode, 0); | 1545 | pack_inode(c, ino, inode, 0); |
1546 | err = ubifs_node_calc_hash(c, ino, hash_ino); | ||
1547 | if (err) | ||
1548 | goto out_release; | ||
1549 | |||
1424 | ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); | 1550 | ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); |
1425 | if (dlen) | 1551 | if (dlen) { |
1426 | ubifs_prep_grp_node(c, dn, dlen, 1); | 1552 | ubifs_prep_grp_node(c, dn, dlen, 1); |
1553 | err = ubifs_node_calc_hash(c, dn, hash_dn); | ||
1554 | if (err) | ||
1555 | goto out_release; | ||
1556 | } | ||
1427 | 1557 | ||
1428 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); | 1558 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); |
1429 | if (err) | 1559 | if (err) |
@@ -1432,15 +1562,17 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1432 | ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); | 1562 | ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); |
1433 | release_head(c, BASEHD); | 1563 | release_head(c, BASEHD); |
1434 | 1564 | ||
1565 | ubifs_add_auth_dirt(c, lnum); | ||
1566 | |||
1435 | if (dlen) { | 1567 | if (dlen) { |
1436 | sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; | 1568 | sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; |
1437 | err = ubifs_tnc_add(c, &key, lnum, sz, dlen); | 1569 | err = ubifs_tnc_add(c, &key, lnum, sz, dlen, hash_dn); |
1438 | if (err) | 1570 | if (err) |
1439 | goto out_ro; | 1571 | goto out_ro; |
1440 | } | 1572 | } |
1441 | 1573 | ||
1442 | ino_key_init(c, &key, inum); | 1574 | ino_key_init(c, &key, inum); |
1443 | err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ); | 1575 | err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ, hash_ino); |
1444 | if (err) | 1576 | if (err) |
1445 | goto out_ro; | 1577 | goto out_ro; |
1446 | 1578 | ||
@@ -1495,12 +1627,13 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1495 | const struct inode *inode, | 1627 | const struct inode *inode, |
1496 | const struct fscrypt_name *nm) | 1628 | const struct fscrypt_name *nm) |
1497 | { | 1629 | { |
1498 | int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen; | 1630 | int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen, write_len; |
1499 | struct ubifs_dent_node *xent; | 1631 | struct ubifs_dent_node *xent; |
1500 | struct ubifs_ino_node *ino; | 1632 | struct ubifs_ino_node *ino; |
1501 | union ubifs_key xent_key, key1, key2; | 1633 | union ubifs_key xent_key, key1, key2; |
1502 | int sync = IS_DIRSYNC(host); | 1634 | int sync = IS_DIRSYNC(host); |
1503 | struct ubifs_inode *host_ui = ubifs_inode(host); | 1635 | struct ubifs_inode *host_ui = ubifs_inode(host); |
1636 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
1504 | 1637 | ||
1505 | ubifs_assert(c, inode->i_nlink == 0); | 1638 | ubifs_assert(c, inode->i_nlink == 0); |
1506 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 1639 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); |
@@ -1514,12 +1647,14 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1514 | hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; | 1647 | hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; |
1515 | len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); | 1648 | len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); |
1516 | 1649 | ||
1517 | xent = kzalloc(len, GFP_NOFS); | 1650 | write_len = len + ubifs_auth_node_sz(c); |
1651 | |||
1652 | xent = kzalloc(write_len, GFP_NOFS); | ||
1518 | if (!xent) | 1653 | if (!xent) |
1519 | return -ENOMEM; | 1654 | return -ENOMEM; |
1520 | 1655 | ||
1521 | /* Make reservation before allocating sequence numbers */ | 1656 | /* Make reservation before allocating sequence numbers */ |
1522 | err = make_reservation(c, BASEHD, len); | 1657 | err = make_reservation(c, BASEHD, write_len); |
1523 | if (err) { | 1658 | if (err) { |
1524 | kfree(xent); | 1659 | kfree(xent); |
1525 | return err; | 1660 | return err; |
@@ -1540,11 +1675,16 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1540 | pack_inode(c, ino, inode, 0); | 1675 | pack_inode(c, ino, inode, 0); |
1541 | ino = (void *)ino + UBIFS_INO_NODE_SZ; | 1676 | ino = (void *)ino + UBIFS_INO_NODE_SZ; |
1542 | pack_inode(c, ino, host, 1); | 1677 | pack_inode(c, ino, host, 1); |
1678 | err = ubifs_node_calc_hash(c, ino, hash); | ||
1679 | if (err) | ||
1680 | goto out_release; | ||
1543 | 1681 | ||
1544 | err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); | 1682 | err = write_head(c, BASEHD, xent, write_len, &lnum, &xent_offs, sync); |
1545 | if (!sync && !err) | 1683 | if (!sync && !err) |
1546 | ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); | 1684 | ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); |
1547 | release_head(c, BASEHD); | 1685 | release_head(c, BASEHD); |
1686 | |||
1687 | ubifs_add_auth_dirt(c, lnum); | ||
1548 | kfree(xent); | 1688 | kfree(xent); |
1549 | if (err) | 1689 | if (err) |
1550 | goto out_ro; | 1690 | goto out_ro; |
@@ -1572,7 +1712,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1572 | 1712 | ||
1573 | /* And update TNC with the new host inode position */ | 1713 | /* And update TNC with the new host inode position */ |
1574 | ino_key_init(c, &key1, host->i_ino); | 1714 | ino_key_init(c, &key1, host->i_ino); |
1575 | err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen); | 1715 | err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen, hash); |
1576 | if (err) | 1716 | if (err) |
1577 | goto out_ro; | 1717 | goto out_ro; |
1578 | 1718 | ||
@@ -1583,6 +1723,9 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1583 | mark_inode_clean(c, host_ui); | 1723 | mark_inode_clean(c, host_ui); |
1584 | return 0; | 1724 | return 0; |
1585 | 1725 | ||
1726 | out_release: | ||
1727 | kfree(xent); | ||
1728 | release_head(c, BASEHD); | ||
1586 | out_ro: | 1729 | out_ro: |
1587 | ubifs_ro_mode(c, err); | 1730 | ubifs_ro_mode(c, err); |
1588 | finish_reservation(c); | 1731 | finish_reservation(c); |
@@ -1610,6 +1753,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1610 | struct ubifs_ino_node *ino; | 1753 | struct ubifs_ino_node *ino; |
1611 | union ubifs_key key; | 1754 | union ubifs_key key; |
1612 | int sync = IS_DIRSYNC(host); | 1755 | int sync = IS_DIRSYNC(host); |
1756 | u8 hash_host[UBIFS_HASH_ARR_SZ]; | ||
1757 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
1613 | 1758 | ||
1614 | dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); | 1759 | dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); |
1615 | ubifs_assert(c, host->i_nlink > 0); | 1760 | ubifs_assert(c, host->i_nlink > 0); |
@@ -1621,6 +1766,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1621 | aligned_len1 = ALIGN(len1, 8); | 1766 | aligned_len1 = ALIGN(len1, 8); |
1622 | aligned_len = aligned_len1 + ALIGN(len2, 8); | 1767 | aligned_len = aligned_len1 + ALIGN(len2, 8); |
1623 | 1768 | ||
1769 | aligned_len += ubifs_auth_node_sz(c); | ||
1770 | |||
1624 | ino = kzalloc(aligned_len, GFP_NOFS); | 1771 | ino = kzalloc(aligned_len, GFP_NOFS); |
1625 | if (!ino) | 1772 | if (!ino) |
1626 | return -ENOMEM; | 1773 | return -ENOMEM; |
@@ -1631,7 +1778,13 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1631 | goto out_free; | 1778 | goto out_free; |
1632 | 1779 | ||
1633 | pack_inode(c, ino, host, 0); | 1780 | pack_inode(c, ino, host, 0); |
1781 | err = ubifs_node_calc_hash(c, ino, hash_host); | ||
1782 | if (err) | ||
1783 | goto out_release; | ||
1634 | pack_inode(c, (void *)ino + aligned_len1, inode, 1); | 1784 | pack_inode(c, (void *)ino + aligned_len1, inode, 1); |
1785 | err = ubifs_node_calc_hash(c, (void *)ino + aligned_len1, hash); | ||
1786 | if (err) | ||
1787 | goto out_release; | ||
1635 | 1788 | ||
1636 | err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); | 1789 | err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); |
1637 | if (!sync && !err) { | 1790 | if (!sync && !err) { |
@@ -1644,13 +1797,15 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1644 | if (err) | 1797 | if (err) |
1645 | goto out_ro; | 1798 | goto out_ro; |
1646 | 1799 | ||
1800 | ubifs_add_auth_dirt(c, lnum); | ||
1801 | |||
1647 | ino_key_init(c, &key, host->i_ino); | 1802 | ino_key_init(c, &key, host->i_ino); |
1648 | err = ubifs_tnc_add(c, &key, lnum, offs, len1); | 1803 | err = ubifs_tnc_add(c, &key, lnum, offs, len1, hash_host); |
1649 | if (err) | 1804 | if (err) |
1650 | goto out_ro; | 1805 | goto out_ro; |
1651 | 1806 | ||
1652 | ino_key_init(c, &key, inode->i_ino); | 1807 | ino_key_init(c, &key, inode->i_ino); |
1653 | err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2); | 1808 | err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2, hash); |
1654 | if (err) | 1809 | if (err) |
1655 | goto out_ro; | 1810 | goto out_ro; |
1656 | 1811 | ||
@@ -1662,6 +1817,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1662 | kfree(ino); | 1817 | kfree(ino); |
1663 | return 0; | 1818 | return 0; |
1664 | 1819 | ||
1820 | out_release: | ||
1821 | release_head(c, BASEHD); | ||
1665 | out_ro: | 1822 | out_ro: |
1666 | ubifs_ro_mode(c, err); | 1823 | ubifs_ro_mode(c, err); |
1667 | finish_reservation(c); | 1824 | finish_reservation(c); |
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index 86b0828f5499..15fd854149bb 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c | |||
@@ -236,6 +236,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) | |||
236 | bud->lnum = lnum; | 236 | bud->lnum = lnum; |
237 | bud->start = offs; | 237 | bud->start = offs; |
238 | bud->jhead = jhead; | 238 | bud->jhead = jhead; |
239 | bud->log_hash = NULL; | ||
239 | 240 | ||
240 | ref->ch.node_type = UBIFS_REF_NODE; | 241 | ref->ch.node_type = UBIFS_REF_NODE; |
241 | ref->lnum = cpu_to_le32(bud->lnum); | 242 | ref->lnum = cpu_to_le32(bud->lnum); |
@@ -275,6 +276,14 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) | |||
275 | if (err) | 276 | if (err) |
276 | goto out_unlock; | 277 | goto out_unlock; |
277 | 278 | ||
279 | err = ubifs_shash_update(c, c->log_hash, ref, UBIFS_REF_NODE_SZ); | ||
280 | if (err) | ||
281 | goto out_unlock; | ||
282 | |||
283 | err = ubifs_shash_copy_state(c, c->log_hash, c->jheads[jhead].log_hash); | ||
284 | if (err) | ||
285 | goto out_unlock; | ||
286 | |||
278 | c->lhead_offs += c->ref_node_alsz; | 287 | c->lhead_offs += c->ref_node_alsz; |
279 | 288 | ||
280 | ubifs_add_bud(c, bud); | 289 | ubifs_add_bud(c, bud); |
@@ -377,6 +386,14 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) | |||
377 | cs->cmt_no = cpu_to_le64(c->cmt_no); | 386 | cs->cmt_no = cpu_to_le64(c->cmt_no); |
378 | ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); | 387 | ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); |
379 | 388 | ||
389 | err = ubifs_shash_init(c, c->log_hash); | ||
390 | if (err) | ||
391 | goto out; | ||
392 | |||
393 | err = ubifs_shash_update(c, c->log_hash, cs, UBIFS_CS_NODE_SZ); | ||
394 | if (err < 0) | ||
395 | goto out; | ||
396 | |||
380 | /* | 397 | /* |
381 | * Note, we do not lock 'c->log_mutex' because this is the commit start | 398 | * Note, we do not lock 'c->log_mutex' because this is the commit start |
382 | * phase and we are exclusively using the log. And we do not lock | 399 | * phase and we are exclusively using the log. And we do not lock |
@@ -402,6 +419,12 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) | |||
402 | 419 | ||
403 | ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); | 420 | ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); |
404 | len += UBIFS_REF_NODE_SZ; | 421 | len += UBIFS_REF_NODE_SZ; |
422 | |||
423 | err = ubifs_shash_update(c, c->log_hash, ref, | ||
424 | UBIFS_REF_NODE_SZ); | ||
425 | if (err) | ||
426 | goto out; | ||
427 | ubifs_shash_copy_state(c, c->log_hash, c->jheads[i].log_hash); | ||
405 | } | 428 | } |
406 | 429 | ||
407 | ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len); | 430 | ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len); |
@@ -516,6 +539,7 @@ int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum) | |||
516 | if (err) | 539 | if (err) |
517 | return err; | 540 | return err; |
518 | list_del(&bud->list); | 541 | list_del(&bud->list); |
542 | kfree(bud->log_hash); | ||
519 | kfree(bud); | 543 | kfree(bud); |
520 | } | 544 | } |
521 | mutex_lock(&c->log_mutex); | 545 | mutex_lock(&c->log_mutex); |
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index 31393370e334..d1d5e96350dd 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c | |||
@@ -604,11 +604,12 @@ static int calc_pnode_num_from_parent(const struct ubifs_info *c, | |||
604 | * @lpt_first: LEB number of first LPT LEB | 604 | * @lpt_first: LEB number of first LPT LEB |
605 | * @lpt_lebs: number of LEBs for LPT is passed and returned here | 605 | * @lpt_lebs: number of LEBs for LPT is passed and returned here |
606 | * @big_lpt: use big LPT model is passed and returned here | 606 | * @big_lpt: use big LPT model is passed and returned here |
607 | * @hash: hash of the LPT is returned here | ||
607 | * | 608 | * |
608 | * This function returns %0 on success and a negative error code on failure. | 609 | * This function returns %0 on success and a negative error code on failure. |
609 | */ | 610 | */ |
610 | int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | 611 | int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, |
611 | int *lpt_lebs, int *big_lpt) | 612 | int *lpt_lebs, int *big_lpt, u8 *hash) |
612 | { | 613 | { |
613 | int lnum, err = 0, node_sz, iopos, i, j, cnt, len, alen, row; | 614 | int lnum, err = 0, node_sz, iopos, i, j, cnt, len, alen, row; |
614 | int blnum, boffs, bsz, bcnt; | 615 | int blnum, boffs, bsz, bcnt; |
@@ -617,6 +618,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | |||
617 | void *buf = NULL, *p; | 618 | void *buf = NULL, *p; |
618 | struct ubifs_lpt_lprops *ltab = NULL; | 619 | struct ubifs_lpt_lprops *ltab = NULL; |
619 | int *lsave = NULL; | 620 | int *lsave = NULL; |
621 | struct shash_desc *desc; | ||
620 | 622 | ||
621 | err = calc_dflt_lpt_geom(c, main_lebs, big_lpt); | 623 | err = calc_dflt_lpt_geom(c, main_lebs, big_lpt); |
622 | if (err) | 624 | if (err) |
@@ -630,6 +632,10 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | |||
630 | /* Needed by 'ubifs_pack_lsave()' */ | 632 | /* Needed by 'ubifs_pack_lsave()' */ |
631 | c->main_first = c->leb_cnt - *main_lebs; | 633 | c->main_first = c->leb_cnt - *main_lebs; |
632 | 634 | ||
635 | desc = ubifs_hash_get_desc(c); | ||
636 | if (IS_ERR(desc)) | ||
637 | return PTR_ERR(desc); | ||
638 | |||
633 | lsave = kmalloc_array(c->lsave_cnt, sizeof(int), GFP_KERNEL); | 639 | lsave = kmalloc_array(c->lsave_cnt, sizeof(int), GFP_KERNEL); |
634 | pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_KERNEL); | 640 | pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_KERNEL); |
635 | nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_KERNEL); | 641 | nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_KERNEL); |
@@ -677,6 +683,10 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | |||
677 | 683 | ||
678 | /* Add first pnode */ | 684 | /* Add first pnode */ |
679 | ubifs_pack_pnode(c, p, pnode); | 685 | ubifs_pack_pnode(c, p, pnode); |
686 | err = ubifs_shash_update(c, desc, p, c->pnode_sz); | ||
687 | if (err) | ||
688 | goto out; | ||
689 | |||
680 | p += c->pnode_sz; | 690 | p += c->pnode_sz; |
681 | len = c->pnode_sz; | 691 | len = c->pnode_sz; |
682 | pnode->num += 1; | 692 | pnode->num += 1; |
@@ -711,6 +721,10 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | |||
711 | len = 0; | 721 | len = 0; |
712 | } | 722 | } |
713 | ubifs_pack_pnode(c, p, pnode); | 723 | ubifs_pack_pnode(c, p, pnode); |
724 | err = ubifs_shash_update(c, desc, p, c->pnode_sz); | ||
725 | if (err) | ||
726 | goto out; | ||
727 | |||
714 | p += c->pnode_sz; | 728 | p += c->pnode_sz; |
715 | len += c->pnode_sz; | 729 | len += c->pnode_sz; |
716 | /* | 730 | /* |
@@ -830,6 +844,10 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | |||
830 | if (err) | 844 | if (err) |
831 | goto out; | 845 | goto out; |
832 | 846 | ||
847 | err = ubifs_shash_final(c, desc, hash); | ||
848 | if (err) | ||
849 | goto out; | ||
850 | |||
833 | c->nhead_lnum = lnum; | 851 | c->nhead_lnum = lnum; |
834 | c->nhead_offs = ALIGN(len, c->min_io_size); | 852 | c->nhead_offs = ALIGN(len, c->min_io_size); |
835 | 853 | ||
@@ -853,6 +871,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | |||
853 | dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs); | 871 | dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs); |
854 | out: | 872 | out: |
855 | c->ltab = NULL; | 873 | c->ltab = NULL; |
874 | kfree(desc); | ||
856 | kfree(lsave); | 875 | kfree(lsave); |
857 | vfree(ltab); | 876 | vfree(ltab); |
858 | vfree(buf); | 877 | vfree(buf); |
@@ -1439,26 +1458,25 @@ struct ubifs_pnode *ubifs_get_pnode(struct ubifs_info *c, | |||
1439 | } | 1458 | } |
1440 | 1459 | ||
1441 | /** | 1460 | /** |
1442 | * ubifs_lpt_lookup - lookup LEB properties in the LPT. | 1461 | * ubifs_pnode_lookup - lookup a pnode in the LPT. |
1443 | * @c: UBIFS file-system description object | 1462 | * @c: UBIFS file-system description object |
1444 | * @lnum: LEB number to lookup | 1463 | * @i: pnode number (0 to (main_lebs - 1) / UBIFS_LPT_FANOUT) |
1445 | * | 1464 | * |
1446 | * This function returns a pointer to the LEB properties on success or a | 1465 | * This function returns a pointer to the pnode on success or a negative |
1447 | * negative error code on failure. | 1466 | * error code on failure. |
1448 | */ | 1467 | */ |
1449 | struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) | 1468 | struct ubifs_pnode *ubifs_pnode_lookup(struct ubifs_info *c, int i) |
1450 | { | 1469 | { |
1451 | int err, i, h, iip, shft; | 1470 | int err, h, iip, shft; |
1452 | struct ubifs_nnode *nnode; | 1471 | struct ubifs_nnode *nnode; |
1453 | struct ubifs_pnode *pnode; | ||
1454 | 1472 | ||
1455 | if (!c->nroot) { | 1473 | if (!c->nroot) { |
1456 | err = ubifs_read_nnode(c, NULL, 0); | 1474 | err = ubifs_read_nnode(c, NULL, 0); |
1457 | if (err) | 1475 | if (err) |
1458 | return ERR_PTR(err); | 1476 | return ERR_PTR(err); |
1459 | } | 1477 | } |
1478 | i <<= UBIFS_LPT_FANOUT_SHIFT; | ||
1460 | nnode = c->nroot; | 1479 | nnode = c->nroot; |
1461 | i = lnum - c->main_first; | ||
1462 | shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; | 1480 | shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; |
1463 | for (h = 1; h < c->lpt_hght; h++) { | 1481 | for (h = 1; h < c->lpt_hght; h++) { |
1464 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | 1482 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); |
@@ -1468,7 +1486,24 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) | |||
1468 | return ERR_CAST(nnode); | 1486 | return ERR_CAST(nnode); |
1469 | } | 1487 | } |
1470 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | 1488 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); |
1471 | pnode = ubifs_get_pnode(c, nnode, iip); | 1489 | return ubifs_get_pnode(c, nnode, iip); |
1490 | } | ||
1491 | |||
1492 | /** | ||
1493 | * ubifs_lpt_lookup - lookup LEB properties in the LPT. | ||
1494 | * @c: UBIFS file-system description object | ||
1495 | * @lnum: LEB number to lookup | ||
1496 | * | ||
1497 | * This function returns a pointer to the LEB properties on success or a | ||
1498 | * negative error code on failure. | ||
1499 | */ | ||
1500 | struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) | ||
1501 | { | ||
1502 | int i, iip; | ||
1503 | struct ubifs_pnode *pnode; | ||
1504 | |||
1505 | i = lnum - c->main_first; | ||
1506 | pnode = ubifs_pnode_lookup(c, i >> UBIFS_LPT_FANOUT_SHIFT); | ||
1472 | if (IS_ERR(pnode)) | 1507 | if (IS_ERR(pnode)) |
1473 | return ERR_CAST(pnode); | 1508 | return ERR_CAST(pnode); |
1474 | iip = (i & (UBIFS_LPT_FANOUT - 1)); | 1509 | iip = (i & (UBIFS_LPT_FANOUT - 1)); |
@@ -1620,6 +1655,131 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) | |||
1620 | } | 1655 | } |
1621 | 1656 | ||
1622 | /** | 1657 | /** |
1658 | * ubifs_lpt_calc_hash - Calculate hash of the LPT pnodes | ||
1659 | * @c: UBIFS file-system description object | ||
1660 | * @hash: the returned hash of the LPT pnodes | ||
1661 | * | ||
1662 | * This function iterates over the LPT pnodes and creates a hash over them. | ||
1663 | * Returns 0 for success or a negative error code otherwise. | ||
1664 | */ | ||
1665 | int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash) | ||
1666 | { | ||
1667 | struct ubifs_nnode *nnode, *nn; | ||
1668 | struct ubifs_cnode *cnode; | ||
1669 | struct shash_desc *desc; | ||
1670 | int iip = 0, i; | ||
1671 | int bufsiz = max_t(int, c->nnode_sz, c->pnode_sz); | ||
1672 | void *buf; | ||
1673 | int err; | ||
1674 | |||
1675 | if (!ubifs_authenticated(c)) | ||
1676 | return 0; | ||
1677 | |||
1678 | desc = ubifs_hash_get_desc(c); | ||
1679 | if (IS_ERR(desc)) | ||
1680 | return PTR_ERR(desc); | ||
1681 | |||
1682 | buf = kmalloc(bufsiz, GFP_NOFS); | ||
1683 | if (!buf) { | ||
1684 | err = -ENOMEM; | ||
1685 | goto out; | ||
1686 | } | ||
1687 | |||
1688 | if (!c->nroot) { | ||
1689 | err = ubifs_read_nnode(c, NULL, 0); | ||
1690 | if (err) | ||
1691 | return err; | ||
1692 | } | ||
1693 | |||
1694 | cnode = (struct ubifs_cnode *)c->nroot; | ||
1695 | |||
1696 | while (cnode) { | ||
1697 | nnode = cnode->parent; | ||
1698 | nn = (struct ubifs_nnode *)cnode; | ||
1699 | if (cnode->level > 1) { | ||
1700 | while (iip < UBIFS_LPT_FANOUT) { | ||
1701 | if (nn->nbranch[iip].lnum == 0) { | ||
1702 | /* Go right */ | ||
1703 | iip++; | ||
1704 | continue; | ||
1705 | } | ||
1706 | |||
1707 | nnode = ubifs_get_nnode(c, nn, iip); | ||
1708 | if (IS_ERR(nnode)) { | ||
1709 | err = PTR_ERR(nnode); | ||
1710 | goto out; | ||
1711 | } | ||
1712 | |||
1713 | /* Go down */ | ||
1714 | iip = 0; | ||
1715 | cnode = (struct ubifs_cnode *)nnode; | ||
1716 | break; | ||
1717 | } | ||
1718 | if (iip < UBIFS_LPT_FANOUT) | ||
1719 | continue; | ||
1720 | } else { | ||
1721 | struct ubifs_pnode *pnode; | ||
1722 | |||
1723 | for (i = 0; i < UBIFS_LPT_FANOUT; i++) { | ||
1724 | if (nn->nbranch[i].lnum == 0) | ||
1725 | continue; | ||
1726 | pnode = ubifs_get_pnode(c, nn, i); | ||
1727 | if (IS_ERR(pnode)) { | ||
1728 | err = PTR_ERR(pnode); | ||
1729 | goto out; | ||
1730 | } | ||
1731 | |||
1732 | ubifs_pack_pnode(c, buf, pnode); | ||
1733 | err = ubifs_shash_update(c, desc, buf, | ||
1734 | c->pnode_sz); | ||
1735 | if (err) | ||
1736 | goto out; | ||
1737 | } | ||
1738 | } | ||
1739 | /* Go up and to the right */ | ||
1740 | iip = cnode->iip + 1; | ||
1741 | cnode = (struct ubifs_cnode *)nnode; | ||
1742 | } | ||
1743 | |||
1744 | err = ubifs_shash_final(c, desc, hash); | ||
1745 | out: | ||
1746 | kfree(desc); | ||
1747 | kfree(buf); | ||
1748 | |||
1749 | return err; | ||
1750 | } | ||
1751 | |||
1752 | /** | ||
1753 | * lpt_check_hash - check the hash of the LPT. | ||
1754 | * @c: UBIFS file-system description object | ||
1755 | * | ||
1756 | * This function calculates a hash over all pnodes in the LPT and compares it with | ||
1757 | * the hash stored in the master node. Returns %0 on success and a negative error | ||
1758 | * code on failure. | ||
1759 | */ | ||
1760 | static int lpt_check_hash(struct ubifs_info *c) | ||
1761 | { | ||
1762 | int err; | ||
1763 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
1764 | |||
1765 | if (!ubifs_authenticated(c)) | ||
1766 | return 0; | ||
1767 | |||
1768 | err = ubifs_lpt_calc_hash(c, hash); | ||
1769 | if (err) | ||
1770 | return err; | ||
1771 | |||
1772 | if (ubifs_check_hash(c, c->mst_node->hash_lpt, hash)) { | ||
1773 | err = -EPERM; | ||
1774 | ubifs_err(c, "Failed to authenticate LPT"); | ||
1775 | } else { | ||
1776 | err = 0; | ||
1777 | } | ||
1778 | |||
1779 | return err; | ||
1780 | } | ||
1781 | |||
1782 | /** | ||
1623 | * lpt_init_rd - initialize the LPT for reading. | 1783 | * lpt_init_rd - initialize the LPT for reading. |
1624 | * @c: UBIFS file-system description object | 1784 | * @c: UBIFS file-system description object |
1625 | * | 1785 | * |
@@ -1660,6 +1820,10 @@ static int lpt_init_rd(struct ubifs_info *c) | |||
1660 | if (err) | 1820 | if (err) |
1661 | return err; | 1821 | return err; |
1662 | 1822 | ||
1823 | err = lpt_check_hash(c); | ||
1824 | if (err) | ||
1825 | return err; | ||
1826 | |||
1663 | dbg_lp("space_bits %d", c->space_bits); | 1827 | dbg_lp("space_bits %d", c->space_bits); |
1664 | dbg_lp("lpt_lnum_bits %d", c->lpt_lnum_bits); | 1828 | dbg_lp("lpt_lnum_bits %d", c->lpt_lnum_bits); |
1665 | dbg_lp("lpt_offs_bits %d", c->lpt_offs_bits); | 1829 | dbg_lp("lpt_offs_bits %d", c->lpt_offs_bits); |
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index 7ce30994bbba..1f88caffdf2a 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c | |||
@@ -619,38 +619,6 @@ static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, | |||
619 | } | 619 | } |
620 | 620 | ||
621 | /** | 621 | /** |
622 | * pnode_lookup - lookup a pnode in the LPT. | ||
623 | * @c: UBIFS file-system description object | ||
624 | * @i: pnode number (0 to (main_lebs - 1) / UBIFS_LPT_FANOUT)) | ||
625 | * | ||
626 | * This function returns a pointer to the pnode on success or a negative | ||
627 | * error code on failure. | ||
628 | */ | ||
629 | static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i) | ||
630 | { | ||
631 | int err, h, iip, shft; | ||
632 | struct ubifs_nnode *nnode; | ||
633 | |||
634 | if (!c->nroot) { | ||
635 | err = ubifs_read_nnode(c, NULL, 0); | ||
636 | if (err) | ||
637 | return ERR_PTR(err); | ||
638 | } | ||
639 | i <<= UBIFS_LPT_FANOUT_SHIFT; | ||
640 | nnode = c->nroot; | ||
641 | shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; | ||
642 | for (h = 1; h < c->lpt_hght; h++) { | ||
643 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | ||
644 | shft -= UBIFS_LPT_FANOUT_SHIFT; | ||
645 | nnode = ubifs_get_nnode(c, nnode, iip); | ||
646 | if (IS_ERR(nnode)) | ||
647 | return ERR_CAST(nnode); | ||
648 | } | ||
649 | iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); | ||
650 | return ubifs_get_pnode(c, nnode, iip); | ||
651 | } | ||
652 | |||
653 | /** | ||
654 | * add_pnode_dirt - add dirty space to LPT LEB properties. | 622 | * add_pnode_dirt - add dirty space to LPT LEB properties. |
655 | * @c: UBIFS file-system description object | 623 | * @c: UBIFS file-system description object |
656 | * @pnode: pnode for which to add dirt | 624 | * @pnode: pnode for which to add dirt |
@@ -702,7 +670,7 @@ static int make_tree_dirty(struct ubifs_info *c) | |||
702 | { | 670 | { |
703 | struct ubifs_pnode *pnode; | 671 | struct ubifs_pnode *pnode; |
704 | 672 | ||
705 | pnode = pnode_lookup(c, 0); | 673 | pnode = ubifs_pnode_lookup(c, 0); |
706 | if (IS_ERR(pnode)) | 674 | if (IS_ERR(pnode)) |
707 | return PTR_ERR(pnode); | 675 | return PTR_ERR(pnode); |
708 | 676 | ||
@@ -956,7 +924,7 @@ static int make_pnode_dirty(struct ubifs_info *c, int node_num, int lnum, | |||
956 | struct ubifs_pnode *pnode; | 924 | struct ubifs_pnode *pnode; |
957 | struct ubifs_nbranch *branch; | 925 | struct ubifs_nbranch *branch; |
958 | 926 | ||
959 | pnode = pnode_lookup(c, node_num); | 927 | pnode = ubifs_pnode_lookup(c, node_num); |
960 | if (IS_ERR(pnode)) | 928 | if (IS_ERR(pnode)) |
961 | return PTR_ERR(pnode); | 929 | return PTR_ERR(pnode); |
962 | branch = &pnode->parent->nbranch[pnode->iip]; | 930 | branch = &pnode->parent->nbranch[pnode->iip]; |
@@ -1279,6 +1247,10 @@ int ubifs_lpt_start_commit(struct ubifs_info *c) | |||
1279 | if (err) | 1247 | if (err) |
1280 | goto out; | 1248 | goto out; |
1281 | 1249 | ||
1250 | err = ubifs_lpt_calc_hash(c, c->mst_node->hash_lpt); | ||
1251 | if (err) | ||
1252 | goto out; | ||
1253 | |||
1282 | /* Copy the LPT's own lprops for end commit to write */ | 1254 | /* Copy the LPT's own lprops for end commit to write */ |
1283 | memcpy(c->ltab_cmt, c->ltab, | 1255 | memcpy(c->ltab_cmt, c->ltab, |
1284 | sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); | 1256 | sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); |
@@ -1558,7 +1530,7 @@ static int dbg_is_pnode_dirty(struct ubifs_info *c, int lnum, int offs) | |||
1558 | struct ubifs_nbranch *branch; | 1530 | struct ubifs_nbranch *branch; |
1559 | 1531 | ||
1560 | cond_resched(); | 1532 | cond_resched(); |
1561 | pnode = pnode_lookup(c, i); | 1533 | pnode = ubifs_pnode_lookup(c, i); |
1562 | if (IS_ERR(pnode)) | 1534 | if (IS_ERR(pnode)) |
1563 | return PTR_ERR(pnode); | 1535 | return PTR_ERR(pnode); |
1564 | branch = &pnode->parent->nbranch[pnode->iip]; | 1536 | branch = &pnode->parent->nbranch[pnode->iip]; |
@@ -1710,7 +1682,7 @@ int dbg_check_ltab(struct ubifs_info *c) | |||
1710 | for (i = 0; i < cnt; i++) { | 1682 | for (i = 0; i < cnt; i++) { |
1711 | struct ubifs_pnode *pnode; | 1683 | struct ubifs_pnode *pnode; |
1712 | 1684 | ||
1713 | pnode = pnode_lookup(c, i); | 1685 | pnode = ubifs_pnode_lookup(c, i); |
1714 | if (IS_ERR(pnode)) | 1686 | if (IS_ERR(pnode)) |
1715 | return PTR_ERR(pnode); | 1687 | return PTR_ERR(pnode); |
1716 | cond_resched(); | 1688 | cond_resched(); |
diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c index 9df4a41bba52..5ea51bbd14c7 100644 --- a/fs/ubifs/master.c +++ b/fs/ubifs/master.c | |||
@@ -25,6 +25,42 @@ | |||
25 | #include "ubifs.h" | 25 | #include "ubifs.h" |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * ubifs_compare_master_node - compare two UBIFS master nodes | ||
29 | * @c: UBIFS file-system description object | ||
30 | * @m1: the first node | ||
31 | * @m2: the second node | ||
32 | * | ||
33 | * This function compares two UBIFS master nodes. Returns 0 if they are equal | ||
34 | * and nonzero if not. | ||
35 | */ | ||
36 | int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2) | ||
37 | { | ||
38 | int ret; | ||
39 | int behind; | ||
40 | int hmac_offs = offsetof(struct ubifs_mst_node, hmac); | ||
41 | |||
42 | /* | ||
43 | * Do not compare the common node header since the sequence number and | ||
44 | * hence the CRC are different. | ||
45 | */ | ||
46 | ret = memcmp(m1 + UBIFS_CH_SZ, m2 + UBIFS_CH_SZ, | ||
47 | hmac_offs - UBIFS_CH_SZ); | ||
48 | if (ret) | ||
49 | return ret; | ||
50 | |||
51 | /* | ||
52 | * Do not compare the embedded HMAC aswell which also must be different | ||
53 | * due to the different common node header. | ||
54 | */ | ||
55 | behind = hmac_offs + UBIFS_MAX_HMAC_LEN; | ||
56 | |||
57 | if (UBIFS_MST_NODE_SZ > behind) | ||
58 | return memcmp(m1 + behind, m2 + behind, UBIFS_MST_NODE_SZ - behind); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | /** | ||
28 | * scan_for_master - search the valid master node. | 64 | * scan_for_master - search the valid master node. |
29 | * @c: UBIFS file-system description object | 65 | * @c: UBIFS file-system description object |
30 | * | 66 | * |
@@ -37,7 +73,7 @@ static int scan_for_master(struct ubifs_info *c) | |||
37 | { | 73 | { |
38 | struct ubifs_scan_leb *sleb; | 74 | struct ubifs_scan_leb *sleb; |
39 | struct ubifs_scan_node *snod; | 75 | struct ubifs_scan_node *snod; |
40 | int lnum, offs = 0, nodes_cnt; | 76 | int lnum, offs = 0, nodes_cnt, err; |
41 | 77 | ||
42 | lnum = UBIFS_MST_LNUM; | 78 | lnum = UBIFS_MST_LNUM; |
43 | 79 | ||
@@ -69,12 +105,23 @@ static int scan_for_master(struct ubifs_info *c) | |||
69 | goto out_dump; | 105 | goto out_dump; |
70 | if (snod->offs != offs) | 106 | if (snod->offs != offs) |
71 | goto out; | 107 | goto out; |
72 | if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, | 108 | if (ubifs_compare_master_node(c, c->mst_node, snod->node)) |
73 | (void *)snod->node + UBIFS_CH_SZ, | ||
74 | UBIFS_MST_NODE_SZ - UBIFS_CH_SZ)) | ||
75 | goto out; | 109 | goto out; |
110 | |||
76 | c->mst_offs = offs; | 111 | c->mst_offs = offs; |
77 | ubifs_scan_destroy(sleb); | 112 | ubifs_scan_destroy(sleb); |
113 | |||
114 | if (!ubifs_authenticated(c)) | ||
115 | return 0; | ||
116 | |||
117 | err = ubifs_node_verify_hmac(c, c->mst_node, | ||
118 | sizeof(struct ubifs_mst_node), | ||
119 | offsetof(struct ubifs_mst_node, hmac)); | ||
120 | if (err) { | ||
121 | ubifs_err(c, "Failed to verify master node HMAC"); | ||
122 | return -EPERM; | ||
123 | } | ||
124 | |||
78 | return 0; | 125 | return 0; |
79 | 126 | ||
80 | out: | 127 | out: |
@@ -305,6 +352,8 @@ int ubifs_read_master(struct ubifs_info *c) | |||
305 | c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead); | 352 | c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead); |
306 | c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark); | 353 | c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark); |
307 | 354 | ||
355 | ubifs_copy_hash(c, c->mst_node->hash_root_idx, c->zroot.hash); | ||
356 | |||
308 | c->calc_idx_sz = c->bi.old_idx_sz; | 357 | c->calc_idx_sz = c->bi.old_idx_sz; |
309 | 358 | ||
310 | if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS)) | 359 | if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS)) |
@@ -378,7 +427,9 @@ int ubifs_write_master(struct ubifs_info *c) | |||
378 | c->mst_offs = offs; | 427 | c->mst_offs = offs; |
379 | c->mst_node->highest_inum = cpu_to_le64(c->highest_inum); | 428 | c->mst_node->highest_inum = cpu_to_le64(c->highest_inum); |
380 | 429 | ||
381 | err = ubifs_write_node(c, c->mst_node, len, lnum, offs); | 430 | ubifs_copy_hash(c, c->zroot.hash, c->mst_node->hash_root_idx); |
431 | err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs, | ||
432 | offsetof(struct ubifs_mst_node, hmac)); | ||
382 | if (err) | 433 | if (err) |
383 | return err; | 434 | return err; |
384 | 435 | ||
@@ -389,7 +440,8 @@ int ubifs_write_master(struct ubifs_info *c) | |||
389 | if (err) | 440 | if (err) |
390 | return err; | 441 | return err; |
391 | } | 442 | } |
392 | err = ubifs_write_node(c, c->mst_node, len, lnum, offs); | 443 | err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs, |
444 | offsetof(struct ubifs_mst_node, hmac)); | ||
393 | 445 | ||
394 | return err; | 446 | return err; |
395 | } | 447 | } |
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h index 21d35d7dd975..6f87237fdbf4 100644 --- a/fs/ubifs/misc.h +++ b/fs/ubifs/misc.h | |||
@@ -197,7 +197,8 @@ static inline int ubifs_return_leb(struct ubifs_info *c, int lnum) | |||
197 | */ | 197 | */ |
198 | static inline int ubifs_idx_node_sz(const struct ubifs_info *c, int child_cnt) | 198 | static inline int ubifs_idx_node_sz(const struct ubifs_info *c, int child_cnt) |
199 | { | 199 | { |
200 | return UBIFS_IDX_NODE_SZ + (UBIFS_BRANCH_SZ + c->key_len) * child_cnt; | 200 | return UBIFS_IDX_NODE_SZ + (UBIFS_BRANCH_SZ + c->key_len + c->hash_len) |
201 | * child_cnt; | ||
201 | } | 202 | } |
202 | 203 | ||
203 | /** | 204 | /** |
@@ -212,7 +213,7 @@ struct ubifs_branch *ubifs_idx_branch(const struct ubifs_info *c, | |||
212 | int bnum) | 213 | int bnum) |
213 | { | 214 | { |
214 | return (struct ubifs_branch *)((void *)idx->branches + | 215 | return (struct ubifs_branch *)((void *)idx->branches + |
215 | (UBIFS_BRANCH_SZ + c->key_len) * bnum); | 216 | (UBIFS_BRANCH_SZ + c->key_len + c->hash_len) * bnum); |
216 | } | 217 | } |
217 | 218 | ||
218 | /** | 219 | /** |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 984e30e83c0b..8526b7ec4707 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -212,7 +212,10 @@ static int write_rcvrd_mst_node(struct ubifs_info *c, | |||
212 | save_flags = mst->flags; | 212 | save_flags = mst->flags; |
213 | mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY); | 213 | mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY); |
214 | 214 | ||
215 | ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1); | 215 | err = ubifs_prepare_node_hmac(c, mst, UBIFS_MST_NODE_SZ, |
216 | offsetof(struct ubifs_mst_node, hmac), 1); | ||
217 | if (err) | ||
218 | goto out; | ||
216 | err = ubifs_leb_change(c, lnum, mst, sz); | 219 | err = ubifs_leb_change(c, lnum, mst, sz); |
217 | if (err) | 220 | if (err) |
218 | goto out; | 221 | goto out; |
@@ -264,9 +267,7 @@ int ubifs_recover_master_node(struct ubifs_info *c) | |||
264 | offs2 = (void *)mst2 - buf2; | 267 | offs2 = (void *)mst2 - buf2; |
265 | if (offs1 == offs2) { | 268 | if (offs1 == offs2) { |
266 | /* Same offset, so must be the same */ | 269 | /* Same offset, so must be the same */ |
267 | if (memcmp((void *)mst1 + UBIFS_CH_SZ, | 270 | if (ubifs_compare_master_node(c, mst1, mst2)) |
268 | (void *)mst2 + UBIFS_CH_SZ, | ||
269 | UBIFS_MST_NODE_SZ - UBIFS_CH_SZ)) | ||
270 | goto out_err; | 271 | goto out_err; |
271 | mst = mst1; | 272 | mst = mst1; |
272 | } else if (offs2 + sz == offs1) { | 273 | } else if (offs2 + sz == offs1) { |
@@ -1462,15 +1463,81 @@ out: | |||
1462 | } | 1463 | } |
1463 | 1464 | ||
1464 | /** | 1465 | /** |
1466 | * inode_fix_size - fix inode size | ||
1467 | * @c: UBIFS file-system description object | ||
1468 | * @e: inode size information for recovery | ||
1469 | */ | ||
1470 | static int inode_fix_size(struct ubifs_info *c, struct size_entry *e) | ||
1471 | { | ||
1472 | struct inode *inode; | ||
1473 | struct ubifs_inode *ui; | ||
1474 | int err; | ||
1475 | |||
1476 | if (c->ro_mount) | ||
1477 | ubifs_assert(c, !e->inode); | ||
1478 | |||
1479 | if (e->inode) { | ||
1480 | /* Remounting rw, pick up inode we stored earlier */ | ||
1481 | inode = e->inode; | ||
1482 | } else { | ||
1483 | inode = ubifs_iget(c->vfs_sb, e->inum); | ||
1484 | if (IS_ERR(inode)) | ||
1485 | return PTR_ERR(inode); | ||
1486 | |||
1487 | if (inode->i_size >= e->d_size) { | ||
1488 | /* | ||
1489 | * The original inode in the index already has a size | ||
1490 | * big enough, nothing to do | ||
1491 | */ | ||
1492 | iput(inode); | ||
1493 | return 0; | ||
1494 | } | ||
1495 | |||
1496 | dbg_rcvry("ino %lu size %lld -> %lld", | ||
1497 | (unsigned long)e->inum, | ||
1498 | inode->i_size, e->d_size); | ||
1499 | |||
1500 | ui = ubifs_inode(inode); | ||
1501 | |||
1502 | inode->i_size = e->d_size; | ||
1503 | ui->ui_size = e->d_size; | ||
1504 | ui->synced_i_size = e->d_size; | ||
1505 | |||
1506 | e->inode = inode; | ||
1507 | } | ||
1508 | |||
1509 | /* | ||
1510 | * In readonly mode just keep the inode pinned in memory until we go | ||
1511 | * readwrite. In readwrite mode write the inode to the journal with the | ||
1512 | * fixed size. | ||
1513 | */ | ||
1514 | if (c->ro_mount) | ||
1515 | return 0; | ||
1516 | |||
1517 | err = ubifs_jnl_write_inode(c, inode); | ||
1518 | |||
1519 | iput(inode); | ||
1520 | |||
1521 | if (err) | ||
1522 | return err; | ||
1523 | |||
1524 | rb_erase(&e->rb, &c->size_tree); | ||
1525 | kfree(e); | ||
1526 | |||
1527 | return 0; | ||
1528 | } | ||
1529 | |||
1530 | /** | ||
1465 | * ubifs_recover_size - recover inode size. | 1531 | * ubifs_recover_size - recover inode size. |
1466 | * @c: UBIFS file-system description object | 1532 | * @c: UBIFS file-system description object |
1533 | * @in_place: If true, do a in-place size fixup | ||
1467 | * | 1534 | * |
1468 | * This function attempts to fix inode size discrepancies identified by the | 1535 | * This function attempts to fix inode size discrepancies identified by the |
1469 | * 'ubifs_recover_size_accum()' function. | 1536 | * 'ubifs_recover_size_accum()' function. |
1470 | * | 1537 | * |
1471 | * This functions returns %0 on success and a negative error code on failure. | 1538 | * This functions returns %0 on success and a negative error code on failure. |
1472 | */ | 1539 | */ |
1473 | int ubifs_recover_size(struct ubifs_info *c) | 1540 | int ubifs_recover_size(struct ubifs_info *c, bool in_place) |
1474 | { | 1541 | { |
1475 | struct rb_node *this = rb_first(&c->size_tree); | 1542 | struct rb_node *this = rb_first(&c->size_tree); |
1476 | 1543 | ||
@@ -1479,6 +1546,9 @@ int ubifs_recover_size(struct ubifs_info *c) | |||
1479 | int err; | 1546 | int err; |
1480 | 1547 | ||
1481 | e = rb_entry(this, struct size_entry, rb); | 1548 | e = rb_entry(this, struct size_entry, rb); |
1549 | |||
1550 | this = rb_next(this); | ||
1551 | |||
1482 | if (!e->exists) { | 1552 | if (!e->exists) { |
1483 | union ubifs_key key; | 1553 | union ubifs_key key; |
1484 | 1554 | ||
@@ -1502,40 +1572,26 @@ int ubifs_recover_size(struct ubifs_info *c) | |||
1502 | } | 1572 | } |
1503 | 1573 | ||
1504 | if (e->exists && e->i_size < e->d_size) { | 1574 | if (e->exists && e->i_size < e->d_size) { |
1505 | if (c->ro_mount) { | 1575 | ubifs_assert(c, !(c->ro_mount && in_place)); |
1506 | /* Fix the inode size and pin it in memory */ | 1576 | |
1507 | struct inode *inode; | 1577 | /* |
1508 | struct ubifs_inode *ui; | 1578 | * We found data that is outside the found inode size, |
1509 | 1579 | * fixup the inode size | |
1510 | ubifs_assert(c, !e->inode); | 1580 | */ |
1511 | 1581 | ||
1512 | inode = ubifs_iget(c->vfs_sb, e->inum); | 1582 | if (in_place) { |
1513 | if (IS_ERR(inode)) | ||
1514 | return PTR_ERR(inode); | ||
1515 | |||
1516 | ui = ubifs_inode(inode); | ||
1517 | if (inode->i_size < e->d_size) { | ||
1518 | dbg_rcvry("ino %lu size %lld -> %lld", | ||
1519 | (unsigned long)e->inum, | ||
1520 | inode->i_size, e->d_size); | ||
1521 | inode->i_size = e->d_size; | ||
1522 | ui->ui_size = e->d_size; | ||
1523 | ui->synced_i_size = e->d_size; | ||
1524 | e->inode = inode; | ||
1525 | this = rb_next(this); | ||
1526 | continue; | ||
1527 | } | ||
1528 | iput(inode); | ||
1529 | } else { | ||
1530 | /* Fix the size in place */ | ||
1531 | err = fix_size_in_place(c, e); | 1583 | err = fix_size_in_place(c, e); |
1532 | if (err) | 1584 | if (err) |
1533 | return err; | 1585 | return err; |
1534 | iput(e->inode); | 1586 | iput(e->inode); |
1587 | } else { | ||
1588 | err = inode_fix_size(c, e); | ||
1589 | if (err) | ||
1590 | return err; | ||
1591 | continue; | ||
1535 | } | 1592 | } |
1536 | } | 1593 | } |
1537 | 1594 | ||
1538 | this = rb_next(this); | ||
1539 | rb_erase(&e->rb, &c->size_tree); | 1595 | rb_erase(&e->rb, &c->size_tree); |
1540 | kfree(e); | 1596 | kfree(e); |
1541 | } | 1597 | } |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 4844538eb926..75f961c4c044 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #include "ubifs.h" | 35 | #include "ubifs.h" |
36 | #include <linux/list_sort.h> | 36 | #include <linux/list_sort.h> |
37 | #include <crypto/hash.h> | ||
38 | #include <crypto/algapi.h> | ||
37 | 39 | ||
38 | /** | 40 | /** |
39 | * struct replay_entry - replay list entry. | 41 | * struct replay_entry - replay list entry. |
@@ -56,6 +58,7 @@ struct replay_entry { | |||
56 | int lnum; | 58 | int lnum; |
57 | int offs; | 59 | int offs; |
58 | int len; | 60 | int len; |
61 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
59 | unsigned int deletion:1; | 62 | unsigned int deletion:1; |
60 | unsigned long long sqnum; | 63 | unsigned long long sqnum; |
61 | struct list_head list; | 64 | struct list_head list; |
@@ -228,7 +231,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) | |||
228 | err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); | 231 | err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); |
229 | else | 232 | else |
230 | err = ubifs_tnc_add_nm(c, &r->key, r->lnum, r->offs, | 233 | err = ubifs_tnc_add_nm(c, &r->key, r->lnum, r->offs, |
231 | r->len, &r->nm); | 234 | r->len, r->hash, &r->nm); |
232 | } else { | 235 | } else { |
233 | if (r->deletion) | 236 | if (r->deletion) |
234 | switch (key_type(c, &r->key)) { | 237 | switch (key_type(c, &r->key)) { |
@@ -248,7 +251,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) | |||
248 | } | 251 | } |
249 | else | 252 | else |
250 | err = ubifs_tnc_add(c, &r->key, r->lnum, r->offs, | 253 | err = ubifs_tnc_add(c, &r->key, r->lnum, r->offs, |
251 | r->len); | 254 | r->len, r->hash); |
252 | if (err) | 255 | if (err) |
253 | return err; | 256 | return err; |
254 | 257 | ||
@@ -352,9 +355,9 @@ static void destroy_replay_list(struct ubifs_info *c) | |||
352 | * in case of success and a negative error code in case of failure. | 355 | * in case of success and a negative error code in case of failure. |
353 | */ | 356 | */ |
354 | static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, | 357 | static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, |
355 | union ubifs_key *key, unsigned long long sqnum, | 358 | const u8 *hash, union ubifs_key *key, |
356 | int deletion, int *used, loff_t old_size, | 359 | unsigned long long sqnum, int deletion, int *used, |
357 | loff_t new_size) | 360 | loff_t old_size, loff_t new_size) |
358 | { | 361 | { |
359 | struct replay_entry *r; | 362 | struct replay_entry *r; |
360 | 363 | ||
@@ -372,6 +375,7 @@ static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, | |||
372 | r->lnum = lnum; | 375 | r->lnum = lnum; |
373 | r->offs = offs; | 376 | r->offs = offs; |
374 | r->len = len; | 377 | r->len = len; |
378 | ubifs_copy_hash(c, hash, r->hash); | ||
375 | r->deletion = !!deletion; | 379 | r->deletion = !!deletion; |
376 | r->sqnum = sqnum; | 380 | r->sqnum = sqnum; |
377 | key_copy(c, key, &r->key); | 381 | key_copy(c, key, &r->key); |
@@ -400,8 +404,9 @@ static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, | |||
400 | * negative error code in case of failure. | 404 | * negative error code in case of failure. |
401 | */ | 405 | */ |
402 | static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, | 406 | static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, |
403 | union ubifs_key *key, const char *name, int nlen, | 407 | const u8 *hash, union ubifs_key *key, |
404 | unsigned long long sqnum, int deletion, int *used) | 408 | const char *name, int nlen, unsigned long long sqnum, |
409 | int deletion, int *used) | ||
405 | { | 410 | { |
406 | struct replay_entry *r; | 411 | struct replay_entry *r; |
407 | char *nbuf; | 412 | char *nbuf; |
@@ -425,6 +430,7 @@ static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, | |||
425 | r->lnum = lnum; | 430 | r->lnum = lnum; |
426 | r->offs = offs; | 431 | r->offs = offs; |
427 | r->len = len; | 432 | r->len = len; |
433 | ubifs_copy_hash(c, hash, r->hash); | ||
428 | r->deletion = !!deletion; | 434 | r->deletion = !!deletion; |
429 | r->sqnum = sqnum; | 435 | r->sqnum = sqnum; |
430 | key_copy(c, key, &r->key); | 436 | key_copy(c, key, &r->key); |
@@ -528,6 +534,105 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud) | |||
528 | } | 534 | } |
529 | 535 | ||
530 | /** | 536 | /** |
537 | * authenticate_sleb - authenticate one scan LEB | ||
538 | * @c: UBIFS file-system description object | ||
539 | * @sleb: the scan LEB to authenticate | ||
540 | * @log_hash: | ||
541 | * @is_last: if true, this is is the last LEB | ||
542 | * | ||
543 | * This function iterates over the buds of a single LEB authenticating all buds | ||
544 | * with the authentication nodes on this LEB. Authentication nodes are written | ||
545 | * after some buds and contain a HMAC covering the authentication node itself | ||
546 | * and the buds between the last authentication node and the current | ||
547 | * authentication node. It can happen that the last buds cannot be authenticated | ||
548 | * because a powercut happened when some nodes were written but not the | ||
549 | * corresponding authentication node. This function returns the number of nodes | ||
550 | * that could be authenticated or a negative error code. | ||
551 | */ | ||
552 | static int authenticate_sleb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, | ||
553 | struct shash_desc *log_hash, int is_last) | ||
554 | { | ||
555 | int n_not_auth = 0; | ||
556 | struct ubifs_scan_node *snod; | ||
557 | int n_nodes = 0; | ||
558 | int err; | ||
559 | u8 *hash, *hmac; | ||
560 | |||
561 | if (!ubifs_authenticated(c)) | ||
562 | return sleb->nodes_cnt; | ||
563 | |||
564 | hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS); | ||
565 | hmac = kmalloc(c->hmac_desc_len, GFP_NOFS); | ||
566 | if (!hash || !hmac) { | ||
567 | err = -ENOMEM; | ||
568 | goto out; | ||
569 | } | ||
570 | |||
571 | list_for_each_entry(snod, &sleb->nodes, list) { | ||
572 | |||
573 | n_nodes++; | ||
574 | |||
575 | if (snod->type == UBIFS_AUTH_NODE) { | ||
576 | struct ubifs_auth_node *auth = snod->node; | ||
577 | SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm); | ||
578 | SHASH_DESC_ON_STACK(hmac_desc, c->hmac_tfm); | ||
579 | |||
580 | hash_desc->tfm = c->hash_tfm; | ||
581 | hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
582 | |||
583 | ubifs_shash_copy_state(c, log_hash, hash_desc); | ||
584 | err = crypto_shash_final(hash_desc, hash); | ||
585 | if (err) | ||
586 | goto out; | ||
587 | |||
588 | hmac_desc->tfm = c->hmac_tfm; | ||
589 | hmac_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
590 | err = crypto_shash_digest(hmac_desc, hash, c->hash_len, | ||
591 | hmac); | ||
592 | if (err) | ||
593 | goto out; | ||
594 | |||
595 | err = ubifs_check_hmac(c, auth->hmac, hmac); | ||
596 | if (err) { | ||
597 | err = -EPERM; | ||
598 | goto out; | ||
599 | } | ||
600 | n_not_auth = 0; | ||
601 | } else { | ||
602 | err = crypto_shash_update(log_hash, snod->node, | ||
603 | snod->len); | ||
604 | if (err) | ||
605 | goto out; | ||
606 | n_not_auth++; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | /* | ||
611 | * A powercut can happen when some nodes were written, but not yet | ||
612 | * the corresponding authentication node. This may only happen on | ||
613 | * the last bud though. | ||
614 | */ | ||
615 | if (n_not_auth) { | ||
616 | if (is_last) { | ||
617 | dbg_mnt("%d unauthenticated nodes found on LEB %d, Ignoring them", | ||
618 | n_not_auth, sleb->lnum); | ||
619 | err = 0; | ||
620 | } else { | ||
621 | dbg_mnt("%d unauthenticated nodes found on non-last LEB %d", | ||
622 | n_not_auth, sleb->lnum); | ||
623 | err = -EPERM; | ||
624 | } | ||
625 | } else { | ||
626 | err = 0; | ||
627 | } | ||
628 | out: | ||
629 | kfree(hash); | ||
630 | kfree(hmac); | ||
631 | |||
632 | return err ? err : n_nodes - n_not_auth; | ||
633 | } | ||
634 | |||
635 | /** | ||
531 | * replay_bud - replay a bud logical eraseblock. | 636 | * replay_bud - replay a bud logical eraseblock. |
532 | * @c: UBIFS file-system description object | 637 | * @c: UBIFS file-system description object |
533 | * @b: bud entry which describes the bud | 638 | * @b: bud entry which describes the bud |
@@ -540,6 +645,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
540 | { | 645 | { |
541 | int is_last = is_last_bud(c, b->bud); | 646 | int is_last = is_last_bud(c, b->bud); |
542 | int err = 0, used = 0, lnum = b->bud->lnum, offs = b->bud->start; | 647 | int err = 0, used = 0, lnum = b->bud->lnum, offs = b->bud->start; |
648 | int n_nodes, n = 0; | ||
543 | struct ubifs_scan_leb *sleb; | 649 | struct ubifs_scan_leb *sleb; |
544 | struct ubifs_scan_node *snod; | 650 | struct ubifs_scan_node *snod; |
545 | 651 | ||
@@ -559,6 +665,15 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
559 | if (IS_ERR(sleb)) | 665 | if (IS_ERR(sleb)) |
560 | return PTR_ERR(sleb); | 666 | return PTR_ERR(sleb); |
561 | 667 | ||
668 | n_nodes = authenticate_sleb(c, sleb, b->bud->log_hash, is_last); | ||
669 | if (n_nodes < 0) { | ||
670 | err = n_nodes; | ||
671 | goto out; | ||
672 | } | ||
673 | |||
674 | ubifs_shash_copy_state(c, b->bud->log_hash, | ||
675 | c->jheads[b->bud->jhead].log_hash); | ||
676 | |||
562 | /* | 677 | /* |
563 | * The bud does not have to start from offset zero - the beginning of | 678 | * The bud does not have to start from offset zero - the beginning of |
564 | * the 'lnum' LEB may contain previously committed data. One of the | 679 | * the 'lnum' LEB may contain previously committed data. One of the |
@@ -582,6 +697,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
582 | */ | 697 | */ |
583 | 698 | ||
584 | list_for_each_entry(snod, &sleb->nodes, list) { | 699 | list_for_each_entry(snod, &sleb->nodes, list) { |
700 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
585 | int deletion = 0; | 701 | int deletion = 0; |
586 | 702 | ||
587 | cond_resched(); | 703 | cond_resched(); |
@@ -591,6 +707,8 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
591 | goto out_dump; | 707 | goto out_dump; |
592 | } | 708 | } |
593 | 709 | ||
710 | ubifs_node_calc_hash(c, snod->node, hash); | ||
711 | |||
594 | if (snod->sqnum > c->max_sqnum) | 712 | if (snod->sqnum > c->max_sqnum) |
595 | c->max_sqnum = snod->sqnum; | 713 | c->max_sqnum = snod->sqnum; |
596 | 714 | ||
@@ -602,7 +720,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
602 | 720 | ||
603 | if (le32_to_cpu(ino->nlink) == 0) | 721 | if (le32_to_cpu(ino->nlink) == 0) |
604 | deletion = 1; | 722 | deletion = 1; |
605 | err = insert_node(c, lnum, snod->offs, snod->len, | 723 | err = insert_node(c, lnum, snod->offs, snod->len, hash, |
606 | &snod->key, snod->sqnum, deletion, | 724 | &snod->key, snod->sqnum, deletion, |
607 | &used, 0, new_size); | 725 | &used, 0, new_size); |
608 | break; | 726 | break; |
@@ -614,7 +732,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
614 | key_block(c, &snod->key) * | 732 | key_block(c, &snod->key) * |
615 | UBIFS_BLOCK_SIZE; | 733 | UBIFS_BLOCK_SIZE; |
616 | 734 | ||
617 | err = insert_node(c, lnum, snod->offs, snod->len, | 735 | err = insert_node(c, lnum, snod->offs, snod->len, hash, |
618 | &snod->key, snod->sqnum, deletion, | 736 | &snod->key, snod->sqnum, deletion, |
619 | &used, 0, new_size); | 737 | &used, 0, new_size); |
620 | break; | 738 | break; |
@@ -628,7 +746,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
628 | if (err) | 746 | if (err) |
629 | goto out_dump; | 747 | goto out_dump; |
630 | 748 | ||
631 | err = insert_dent(c, lnum, snod->offs, snod->len, | 749 | err = insert_dent(c, lnum, snod->offs, snod->len, hash, |
632 | &snod->key, dent->name, | 750 | &snod->key, dent->name, |
633 | le16_to_cpu(dent->nlen), snod->sqnum, | 751 | le16_to_cpu(dent->nlen), snod->sqnum, |
634 | !le64_to_cpu(dent->inum), &used); | 752 | !le64_to_cpu(dent->inum), &used); |
@@ -654,11 +772,13 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
654 | * functions which expect nodes to have keys. | 772 | * functions which expect nodes to have keys. |
655 | */ | 773 | */ |
656 | trun_key_init(c, &key, le32_to_cpu(trun->inum)); | 774 | trun_key_init(c, &key, le32_to_cpu(trun->inum)); |
657 | err = insert_node(c, lnum, snod->offs, snod->len, | 775 | err = insert_node(c, lnum, snod->offs, snod->len, hash, |
658 | &key, snod->sqnum, 1, &used, | 776 | &key, snod->sqnum, 1, &used, |
659 | old_size, new_size); | 777 | old_size, new_size); |
660 | break; | 778 | break; |
661 | } | 779 | } |
780 | case UBIFS_AUTH_NODE: | ||
781 | break; | ||
662 | default: | 782 | default: |
663 | ubifs_err(c, "unexpected node type %d in bud LEB %d:%d", | 783 | ubifs_err(c, "unexpected node type %d in bud LEB %d:%d", |
664 | snod->type, lnum, snod->offs); | 784 | snod->type, lnum, snod->offs); |
@@ -667,6 +787,10 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
667 | } | 787 | } |
668 | if (err) | 788 | if (err) |
669 | goto out; | 789 | goto out; |
790 | |||
791 | n++; | ||
792 | if (n == n_nodes) | ||
793 | break; | ||
670 | } | 794 | } |
671 | 795 | ||
672 | ubifs_assert(c, ubifs_search_bud(c, lnum)); | 796 | ubifs_assert(c, ubifs_search_bud(c, lnum)); |
@@ -745,6 +869,7 @@ static int add_replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, | |||
745 | { | 869 | { |
746 | struct ubifs_bud *bud; | 870 | struct ubifs_bud *bud; |
747 | struct bud_entry *b; | 871 | struct bud_entry *b; |
872 | int err; | ||
748 | 873 | ||
749 | dbg_mnt("add replay bud LEB %d:%d, head %d", lnum, offs, jhead); | 874 | dbg_mnt("add replay bud LEB %d:%d, head %d", lnum, offs, jhead); |
750 | 875 | ||
@@ -754,13 +879,21 @@ static int add_replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, | |||
754 | 879 | ||
755 | b = kmalloc(sizeof(struct bud_entry), GFP_KERNEL); | 880 | b = kmalloc(sizeof(struct bud_entry), GFP_KERNEL); |
756 | if (!b) { | 881 | if (!b) { |
757 | kfree(bud); | 882 | err = -ENOMEM; |
758 | return -ENOMEM; | 883 | goto out; |
759 | } | 884 | } |
760 | 885 | ||
761 | bud->lnum = lnum; | 886 | bud->lnum = lnum; |
762 | bud->start = offs; | 887 | bud->start = offs; |
763 | bud->jhead = jhead; | 888 | bud->jhead = jhead; |
889 | bud->log_hash = ubifs_hash_get_desc(c); | ||
890 | if (IS_ERR(bud->log_hash)) { | ||
891 | err = PTR_ERR(bud->log_hash); | ||
892 | goto out; | ||
893 | } | ||
894 | |||
895 | ubifs_shash_copy_state(c, c->log_hash, bud->log_hash); | ||
896 | |||
764 | ubifs_add_bud(c, bud); | 897 | ubifs_add_bud(c, bud); |
765 | 898 | ||
766 | b->bud = bud; | 899 | b->bud = bud; |
@@ -768,6 +901,11 @@ static int add_replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, | |||
768 | list_add_tail(&b->list, &c->replay_buds); | 901 | list_add_tail(&b->list, &c->replay_buds); |
769 | 902 | ||
770 | return 0; | 903 | return 0; |
904 | out: | ||
905 | kfree(bud); | ||
906 | kfree(b); | ||
907 | |||
908 | return err; | ||
771 | } | 909 | } |
772 | 910 | ||
773 | /** | 911 | /** |
@@ -873,6 +1011,14 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
873 | 1011 | ||
874 | c->cs_sqnum = le64_to_cpu(node->ch.sqnum); | 1012 | c->cs_sqnum = le64_to_cpu(node->ch.sqnum); |
875 | dbg_mnt("commit start sqnum %llu", c->cs_sqnum); | 1013 | dbg_mnt("commit start sqnum %llu", c->cs_sqnum); |
1014 | |||
1015 | err = ubifs_shash_init(c, c->log_hash); | ||
1016 | if (err) | ||
1017 | goto out; | ||
1018 | |||
1019 | err = ubifs_shash_update(c, c->log_hash, node, UBIFS_CS_NODE_SZ); | ||
1020 | if (err < 0) | ||
1021 | goto out; | ||
876 | } | 1022 | } |
877 | 1023 | ||
878 | if (snod->sqnum < c->cs_sqnum) { | 1024 | if (snod->sqnum < c->cs_sqnum) { |
@@ -920,6 +1066,11 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
920 | if (err) | 1066 | if (err) |
921 | goto out_dump; | 1067 | goto out_dump; |
922 | 1068 | ||
1069 | err = ubifs_shash_update(c, c->log_hash, ref, | ||
1070 | UBIFS_REF_NODE_SZ); | ||
1071 | if (err) | ||
1072 | goto out; | ||
1073 | |||
923 | err = add_replay_bud(c, le32_to_cpu(ref->lnum), | 1074 | err = add_replay_bud(c, le32_to_cpu(ref->lnum), |
924 | le32_to_cpu(ref->offs), | 1075 | le32_to_cpu(ref->offs), |
925 | le32_to_cpu(ref->jhead), | 1076 | le32_to_cpu(ref->jhead), |
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index bf17f58908ff..75a69dd26d6e 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
@@ -82,10 +82,13 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
82 | int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; | 82 | int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; |
83 | int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; | 83 | int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; |
84 | int min_leb_cnt = UBIFS_MIN_LEB_CNT; | 84 | int min_leb_cnt = UBIFS_MIN_LEB_CNT; |
85 | int idx_node_size; | ||
85 | long long tmp64, main_bytes; | 86 | long long tmp64, main_bytes; |
86 | __le64 tmp_le64; | 87 | __le64 tmp_le64; |
87 | __le32 tmp_le32; | 88 | __le32 tmp_le32; |
88 | struct timespec64 ts; | 89 | struct timespec64 ts; |
90 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
91 | u8 hash_lpt[UBIFS_HASH_ARR_SZ]; | ||
89 | 92 | ||
90 | /* Some functions called from here depend on the @c->key_len filed */ | 93 | /* Some functions called from here depend on the @c->key_len filed */ |
91 | c->key_len = UBIFS_SK_LEN; | 94 | c->key_len = UBIFS_SK_LEN; |
@@ -147,7 +150,7 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
147 | c->lsave_cnt = DEFAULT_LSAVE_CNT; | 150 | c->lsave_cnt = DEFAULT_LSAVE_CNT; |
148 | c->max_leb_cnt = c->leb_cnt; | 151 | c->max_leb_cnt = c->leb_cnt; |
149 | err = ubifs_create_dflt_lpt(c, &main_lebs, lpt_first, &lpt_lebs, | 152 | err = ubifs_create_dflt_lpt(c, &main_lebs, lpt_first, &lpt_lebs, |
150 | &big_lpt); | 153 | &big_lpt, hash_lpt); |
151 | if (err) | 154 | if (err) |
152 | return err; | 155 | return err; |
153 | 156 | ||
@@ -156,17 +159,35 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
156 | 159 | ||
157 | main_first = c->leb_cnt - main_lebs; | 160 | main_first = c->leb_cnt - main_lebs; |
158 | 161 | ||
162 | sup = kzalloc(ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size), GFP_KERNEL); | ||
163 | mst = kzalloc(c->mst_node_alsz, GFP_KERNEL); | ||
164 | idx_node_size = ubifs_idx_node_sz(c, 1); | ||
165 | idx = kzalloc(ALIGN(tmp, c->min_io_size), GFP_KERNEL); | ||
166 | ino = kzalloc(ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size), GFP_KERNEL); | ||
167 | cs = kzalloc(ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size), GFP_KERNEL); | ||
168 | |||
169 | if (!sup || !mst || !idx || !ino || !cs) { | ||
170 | err = -ENOMEM; | ||
171 | goto out; | ||
172 | } | ||
173 | |||
159 | /* Create default superblock */ | 174 | /* Create default superblock */ |
160 | tmp = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); | ||
161 | sup = kzalloc(tmp, GFP_KERNEL); | ||
162 | if (!sup) | ||
163 | return -ENOMEM; | ||
164 | 175 | ||
165 | tmp64 = (long long)max_buds * c->leb_size; | 176 | tmp64 = (long long)max_buds * c->leb_size; |
166 | if (big_lpt) | 177 | if (big_lpt) |
167 | sup_flags |= UBIFS_FLG_BIGLPT; | 178 | sup_flags |= UBIFS_FLG_BIGLPT; |
168 | sup_flags |= UBIFS_FLG_DOUBLE_HASH; | 179 | sup_flags |= UBIFS_FLG_DOUBLE_HASH; |
169 | 180 | ||
181 | if (ubifs_authenticated(c)) { | ||
182 | sup_flags |= UBIFS_FLG_AUTHENTICATION; | ||
183 | sup->hash_algo = cpu_to_le16(c->auth_hash_algo); | ||
184 | err = ubifs_hmac_wkm(c, sup->hmac_wkm); | ||
185 | if (err) | ||
186 | goto out; | ||
187 | } else { | ||
188 | sup->hash_algo = 0xffff; | ||
189 | } | ||
190 | |||
170 | sup->ch.node_type = UBIFS_SB_NODE; | 191 | sup->ch.node_type = UBIFS_SB_NODE; |
171 | sup->key_hash = UBIFS_KEY_HASH_R5; | 192 | sup->key_hash = UBIFS_KEY_HASH_R5; |
172 | sup->flags = cpu_to_le32(sup_flags); | 193 | sup->flags = cpu_to_le32(sup_flags); |
@@ -197,17 +218,9 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
197 | sup->rp_size = cpu_to_le64(tmp64); | 218 | sup->rp_size = cpu_to_le64(tmp64); |
198 | sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION); | 219 | sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION); |
199 | 220 | ||
200 | err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0); | ||
201 | kfree(sup); | ||
202 | if (err) | ||
203 | return err; | ||
204 | |||
205 | dbg_gen("default superblock created at LEB 0:0"); | 221 | dbg_gen("default superblock created at LEB 0:0"); |
206 | 222 | ||
207 | /* Create default master node */ | 223 | /* Create default master node */ |
208 | mst = kzalloc(c->mst_node_alsz, GFP_KERNEL); | ||
209 | if (!mst) | ||
210 | return -ENOMEM; | ||
211 | 224 | ||
212 | mst->ch.node_type = UBIFS_MST_NODE; | 225 | mst->ch.node_type = UBIFS_MST_NODE; |
213 | mst->log_lnum = cpu_to_le32(UBIFS_LOG_LNUM); | 226 | mst->log_lnum = cpu_to_le32(UBIFS_LOG_LNUM); |
@@ -233,6 +246,7 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
233 | mst->empty_lebs = cpu_to_le32(main_lebs - 2); | 246 | mst->empty_lebs = cpu_to_le32(main_lebs - 2); |
234 | mst->idx_lebs = cpu_to_le32(1); | 247 | mst->idx_lebs = cpu_to_le32(1); |
235 | mst->leb_cnt = cpu_to_le32(c->leb_cnt); | 248 | mst->leb_cnt = cpu_to_le32(c->leb_cnt); |
249 | ubifs_copy_hash(c, hash_lpt, mst->hash_lpt); | ||
236 | 250 | ||
237 | /* Calculate lprops statistics */ | 251 | /* Calculate lprops statistics */ |
238 | tmp64 = main_bytes; | 252 | tmp64 = main_bytes; |
@@ -253,24 +267,9 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
253 | 267 | ||
254 | mst->total_used = cpu_to_le64(UBIFS_INO_NODE_SZ); | 268 | mst->total_used = cpu_to_le64(UBIFS_INO_NODE_SZ); |
255 | 269 | ||
256 | err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0); | ||
257 | if (err) { | ||
258 | kfree(mst); | ||
259 | return err; | ||
260 | } | ||
261 | err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1, | ||
262 | 0); | ||
263 | kfree(mst); | ||
264 | if (err) | ||
265 | return err; | ||
266 | |||
267 | dbg_gen("default master node created at LEB %d:0", UBIFS_MST_LNUM); | 270 | dbg_gen("default master node created at LEB %d:0", UBIFS_MST_LNUM); |
268 | 271 | ||
269 | /* Create the root indexing node */ | 272 | /* Create the root indexing node */ |
270 | tmp = ubifs_idx_node_sz(c, 1); | ||
271 | idx = kzalloc(ALIGN(tmp, c->min_io_size), GFP_KERNEL); | ||
272 | if (!idx) | ||
273 | return -ENOMEM; | ||
274 | 273 | ||
275 | c->key_fmt = UBIFS_SIMPLE_KEY_FMT; | 274 | c->key_fmt = UBIFS_SIMPLE_KEY_FMT; |
276 | c->key_hash = key_r5_hash; | 275 | c->key_hash = key_r5_hash; |
@@ -282,19 +281,11 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
282 | key_write_idx(c, &key, &br->key); | 281 | key_write_idx(c, &key, &br->key); |
283 | br->lnum = cpu_to_le32(main_first + DEFAULT_DATA_LEB); | 282 | br->lnum = cpu_to_le32(main_first + DEFAULT_DATA_LEB); |
284 | br->len = cpu_to_le32(UBIFS_INO_NODE_SZ); | 283 | br->len = cpu_to_le32(UBIFS_INO_NODE_SZ); |
285 | err = ubifs_write_node(c, idx, tmp, main_first + DEFAULT_IDX_LEB, 0); | ||
286 | kfree(idx); | ||
287 | if (err) | ||
288 | return err; | ||
289 | 284 | ||
290 | dbg_gen("default root indexing node created LEB %d:0", | 285 | dbg_gen("default root indexing node created LEB %d:0", |
291 | main_first + DEFAULT_IDX_LEB); | 286 | main_first + DEFAULT_IDX_LEB); |
292 | 287 | ||
293 | /* Create default root inode */ | 288 | /* Create default root inode */ |
294 | tmp = ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size); | ||
295 | ino = kzalloc(tmp, GFP_KERNEL); | ||
296 | if (!ino) | ||
297 | return -ENOMEM; | ||
298 | 289 | ||
299 | ino_key_init_flash(c, &ino->key, UBIFS_ROOT_INO); | 290 | ino_key_init_flash(c, &ino->key, UBIFS_ROOT_INO); |
300 | ino->ch.node_type = UBIFS_INO_NODE; | 291 | ino->ch.node_type = UBIFS_INO_NODE; |
@@ -317,12 +308,6 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
317 | /* Set compression enabled by default */ | 308 | /* Set compression enabled by default */ |
318 | ino->flags = cpu_to_le32(UBIFS_COMPR_FL); | 309 | ino->flags = cpu_to_le32(UBIFS_COMPR_FL); |
319 | 310 | ||
320 | err = ubifs_write_node(c, ino, UBIFS_INO_NODE_SZ, | ||
321 | main_first + DEFAULT_DATA_LEB, 0); | ||
322 | kfree(ino); | ||
323 | if (err) | ||
324 | return err; | ||
325 | |||
326 | dbg_gen("root inode created at LEB %d:0", | 311 | dbg_gen("root inode created at LEB %d:0", |
327 | main_first + DEFAULT_DATA_LEB); | 312 | main_first + DEFAULT_DATA_LEB); |
328 | 313 | ||
@@ -331,19 +316,54 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
331 | * always the case during normal file-system operation. Write a fake | 316 | * always the case during normal file-system operation. Write a fake |
332 | * commit start node to the log. | 317 | * commit start node to the log. |
333 | */ | 318 | */ |
334 | tmp = ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size); | ||
335 | cs = kzalloc(tmp, GFP_KERNEL); | ||
336 | if (!cs) | ||
337 | return -ENOMEM; | ||
338 | 319 | ||
339 | cs->ch.node_type = UBIFS_CS_NODE; | 320 | cs->ch.node_type = UBIFS_CS_NODE; |
321 | |||
322 | err = ubifs_write_node_hmac(c, sup, UBIFS_SB_NODE_SZ, 0, 0, | ||
323 | offsetof(struct ubifs_sb_node, hmac)); | ||
324 | if (err) | ||
325 | goto out; | ||
326 | |||
327 | err = ubifs_write_node(c, ino, UBIFS_INO_NODE_SZ, | ||
328 | main_first + DEFAULT_DATA_LEB, 0); | ||
329 | if (err) | ||
330 | goto out; | ||
331 | |||
332 | ubifs_node_calc_hash(c, ino, hash); | ||
333 | ubifs_copy_hash(c, hash, ubifs_branch_hash(c, br)); | ||
334 | |||
335 | err = ubifs_write_node(c, idx, idx_node_size, main_first + DEFAULT_IDX_LEB, 0); | ||
336 | if (err) | ||
337 | goto out; | ||
338 | |||
339 | ubifs_node_calc_hash(c, idx, hash); | ||
340 | ubifs_copy_hash(c, hash, mst->hash_root_idx); | ||
341 | |||
342 | err = ubifs_write_node_hmac(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0, | ||
343 | offsetof(struct ubifs_mst_node, hmac)); | ||
344 | if (err) | ||
345 | goto out; | ||
346 | |||
347 | err = ubifs_write_node_hmac(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1, | ||
348 | 0, offsetof(struct ubifs_mst_node, hmac)); | ||
349 | if (err) | ||
350 | goto out; | ||
351 | |||
340 | err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, 0); | 352 | err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, 0); |
341 | kfree(cs); | ||
342 | if (err) | 353 | if (err) |
343 | return err; | 354 | goto out; |
344 | 355 | ||
345 | ubifs_msg(c, "default file-system created"); | 356 | ubifs_msg(c, "default file-system created"); |
346 | return 0; | 357 | |
358 | err = 0; | ||
359 | out: | ||
360 | kfree(sup); | ||
361 | kfree(mst); | ||
362 | kfree(idx); | ||
363 | kfree(ino); | ||
364 | kfree(cs); | ||
365 | |||
366 | return err; | ||
347 | } | 367 | } |
348 | 368 | ||
349 | /** | 369 | /** |
@@ -498,7 +518,7 @@ failed: | |||
498 | * code. Note, the user of this function is responsible of kfree()'ing the | 518 | * code. Note, the user of this function is responsible of kfree()'ing the |
499 | * returned superblock buffer. | 519 | * returned superblock buffer. |
500 | */ | 520 | */ |
501 | struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) | 521 | static struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) |
502 | { | 522 | { |
503 | struct ubifs_sb_node *sup; | 523 | struct ubifs_sb_node *sup; |
504 | int err; | 524 | int err; |
@@ -517,6 +537,65 @@ struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) | |||
517 | return sup; | 537 | return sup; |
518 | } | 538 | } |
519 | 539 | ||
540 | static int authenticate_sb_node(struct ubifs_info *c, | ||
541 | const struct ubifs_sb_node *sup) | ||
542 | { | ||
543 | unsigned int sup_flags = le32_to_cpu(sup->flags); | ||
544 | u8 hmac_wkm[UBIFS_HMAC_ARR_SZ]; | ||
545 | int authenticated = !!(sup_flags & UBIFS_FLG_AUTHENTICATION); | ||
546 | int hash_algo; | ||
547 | int err; | ||
548 | |||
549 | if (c->authenticated && !authenticated) { | ||
550 | ubifs_err(c, "authenticated FS forced, but found FS without authentication"); | ||
551 | return -EINVAL; | ||
552 | } | ||
553 | |||
554 | if (!c->authenticated && authenticated) { | ||
555 | ubifs_err(c, "authenticated FS found, but no key given"); | ||
556 | return -EINVAL; | ||
557 | } | ||
558 | |||
559 | ubifs_msg(c, "Mounting in %sauthenticated mode", | ||
560 | c->authenticated ? "" : "un"); | ||
561 | |||
562 | if (!c->authenticated) | ||
563 | return 0; | ||
564 | |||
565 | if (!IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) | ||
566 | return -EOPNOTSUPP; | ||
567 | |||
568 | hash_algo = le16_to_cpu(sup->hash_algo); | ||
569 | if (hash_algo >= HASH_ALGO__LAST) { | ||
570 | ubifs_err(c, "superblock uses unknown hash algo %d", | ||
571 | hash_algo); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | |||
575 | if (strcmp(hash_algo_name[hash_algo], c->auth_hash_name)) { | ||
576 | ubifs_err(c, "This filesystem uses %s for hashing," | ||
577 | " but %s is specified", hash_algo_name[hash_algo], | ||
578 | c->auth_hash_name); | ||
579 | return -EINVAL; | ||
580 | } | ||
581 | |||
582 | err = ubifs_hmac_wkm(c, hmac_wkm); | ||
583 | if (err) | ||
584 | return err; | ||
585 | |||
586 | if (ubifs_check_hmac(c, hmac_wkm, sup->hmac_wkm)) { | ||
587 | ubifs_err(c, "provided key does not fit"); | ||
588 | return -ENOKEY; | ||
589 | } | ||
590 | |||
591 | err = ubifs_node_verify_hmac(c, sup, sizeof(*sup), | ||
592 | offsetof(struct ubifs_sb_node, hmac)); | ||
593 | if (err) | ||
594 | ubifs_err(c, "Failed to authenticate superblock: %d", err); | ||
595 | |||
596 | return err; | ||
597 | } | ||
598 | |||
520 | /** | 599 | /** |
521 | * ubifs_write_sb_node - write superblock node. | 600 | * ubifs_write_sb_node - write superblock node. |
522 | * @c: UBIFS file-system description object | 601 | * @c: UBIFS file-system description object |
@@ -527,8 +606,13 @@ struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) | |||
527 | int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) | 606 | int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) |
528 | { | 607 | { |
529 | int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); | 608 | int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); |
609 | int err; | ||
610 | |||
611 | err = ubifs_prepare_node_hmac(c, sup, UBIFS_SB_NODE_SZ, | ||
612 | offsetof(struct ubifs_sb_node, hmac), 1); | ||
613 | if (err) | ||
614 | return err; | ||
530 | 615 | ||
531 | ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 1); | ||
532 | return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len); | 616 | return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len); |
533 | } | 617 | } |
534 | 618 | ||
@@ -555,6 +639,8 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
555 | if (IS_ERR(sup)) | 639 | if (IS_ERR(sup)) |
556 | return PTR_ERR(sup); | 640 | return PTR_ERR(sup); |
557 | 641 | ||
642 | c->sup_node = sup; | ||
643 | |||
558 | c->fmt_version = le32_to_cpu(sup->fmt_version); | 644 | c->fmt_version = le32_to_cpu(sup->fmt_version); |
559 | c->ro_compat_version = le32_to_cpu(sup->ro_compat_version); | 645 | c->ro_compat_version = le32_to_cpu(sup->ro_compat_version); |
560 | 646 | ||
@@ -603,7 +689,7 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
603 | c->key_hash = key_test_hash; | 689 | c->key_hash = key_test_hash; |
604 | c->key_hash_type = UBIFS_KEY_HASH_TEST; | 690 | c->key_hash_type = UBIFS_KEY_HASH_TEST; |
605 | break; | 691 | break; |
606 | }; | 692 | } |
607 | 693 | ||
608 | c->key_fmt = sup->key_fmt; | 694 | c->key_fmt = sup->key_fmt; |
609 | 695 | ||
@@ -640,6 +726,10 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
640 | c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH); | 726 | c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH); |
641 | c->encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION); | 727 | c->encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION); |
642 | 728 | ||
729 | err = authenticate_sb_node(c, sup); | ||
730 | if (err) | ||
731 | goto out; | ||
732 | |||
643 | if ((sup_flags & ~UBIFS_FLG_MASK) != 0) { | 733 | if ((sup_flags & ~UBIFS_FLG_MASK) != 0) { |
644 | ubifs_err(c, "Unknown feature flags found: %#x", | 734 | ubifs_err(c, "Unknown feature flags found: %#x", |
645 | sup_flags & ~UBIFS_FLG_MASK); | 735 | sup_flags & ~UBIFS_FLG_MASK); |
@@ -686,7 +776,6 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
686 | 776 | ||
687 | err = validate_sb(c, sup); | 777 | err = validate_sb(c, sup); |
688 | out: | 778 | out: |
689 | kfree(sup); | ||
690 | return err; | 779 | return err; |
691 | } | 780 | } |
692 | 781 | ||
@@ -815,7 +904,7 @@ out: | |||
815 | int ubifs_fixup_free_space(struct ubifs_info *c) | 904 | int ubifs_fixup_free_space(struct ubifs_info *c) |
816 | { | 905 | { |
817 | int err; | 906 | int err; |
818 | struct ubifs_sb_node *sup; | 907 | struct ubifs_sb_node *sup = c->sup_node; |
819 | 908 | ||
820 | ubifs_assert(c, c->space_fixup); | 909 | ubifs_assert(c, c->space_fixup); |
821 | ubifs_assert(c, !c->ro_mount); | 910 | ubifs_assert(c, !c->ro_mount); |
@@ -826,16 +915,11 @@ int ubifs_fixup_free_space(struct ubifs_info *c) | |||
826 | if (err) | 915 | if (err) |
827 | return err; | 916 | return err; |
828 | 917 | ||
829 | sup = ubifs_read_sb_node(c); | ||
830 | if (IS_ERR(sup)) | ||
831 | return PTR_ERR(sup); | ||
832 | |||
833 | /* Free-space fixup is no longer required */ | 918 | /* Free-space fixup is no longer required */ |
834 | c->space_fixup = 0; | 919 | c->space_fixup = 0; |
835 | sup->flags &= cpu_to_le32(~UBIFS_FLG_SPACE_FIXUP); | 920 | sup->flags &= cpu_to_le32(~UBIFS_FLG_SPACE_FIXUP); |
836 | 921 | ||
837 | err = ubifs_write_sb_node(c, sup); | 922 | err = ubifs_write_sb_node(c, sup); |
838 | kfree(sup); | ||
839 | if (err) | 923 | if (err) |
840 | return err; | 924 | return err; |
841 | 925 | ||
@@ -846,7 +930,7 @@ int ubifs_fixup_free_space(struct ubifs_info *c) | |||
846 | int ubifs_enable_encryption(struct ubifs_info *c) | 930 | int ubifs_enable_encryption(struct ubifs_info *c) |
847 | { | 931 | { |
848 | int err; | 932 | int err; |
849 | struct ubifs_sb_node *sup; | 933 | struct ubifs_sb_node *sup = c->sup_node; |
850 | 934 | ||
851 | if (c->encrypted) | 935 | if (c->encrypted) |
852 | return 0; | 936 | return 0; |
@@ -859,16 +943,11 @@ int ubifs_enable_encryption(struct ubifs_info *c) | |||
859 | return -EINVAL; | 943 | return -EINVAL; |
860 | } | 944 | } |
861 | 945 | ||
862 | sup = ubifs_read_sb_node(c); | ||
863 | if (IS_ERR(sup)) | ||
864 | return PTR_ERR(sup); | ||
865 | |||
866 | sup->flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION); | 946 | sup->flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION); |
867 | 947 | ||
868 | err = ubifs_write_sb_node(c, sup); | 948 | err = ubifs_write_sb_node(c, sup); |
869 | if (!err) | 949 | if (!err) |
870 | c->encrypted = 1; | 950 | c->encrypted = 1; |
871 | kfree(sup); | ||
872 | 951 | ||
873 | return err; | 952 | return err; |
874 | } | 953 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index fec62e9dfbe6..1fac1133dadd 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -579,6 +579,9 @@ static int init_constants_early(struct ubifs_info *c) | |||
579 | c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ; | 579 | c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ; |
580 | c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ; | 580 | c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ; |
581 | c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ; | 581 | c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ; |
582 | c->ranges[UBIFS_AUTH_NODE].min_len = UBIFS_AUTH_NODE_SZ; | ||
583 | c->ranges[UBIFS_AUTH_NODE].max_len = UBIFS_AUTH_NODE_SZ + | ||
584 | UBIFS_MAX_HMAC_LEN; | ||
582 | 585 | ||
583 | c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ; | 586 | c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ; |
584 | c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ; | 587 | c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ; |
@@ -816,6 +819,9 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
816 | c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; | 819 | c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; |
817 | c->jheads[i].wbuf.jhead = i; | 820 | c->jheads[i].wbuf.jhead = i; |
818 | c->jheads[i].grouped = 1; | 821 | c->jheads[i].grouped = 1; |
822 | c->jheads[i].log_hash = ubifs_hash_get_desc(c); | ||
823 | if (IS_ERR(c->jheads[i].log_hash)) | ||
824 | goto out; | ||
819 | } | 825 | } |
820 | 826 | ||
821 | /* | 827 | /* |
@@ -826,6 +832,12 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
826 | c->jheads[GCHD].grouped = 0; | 832 | c->jheads[GCHD].grouped = 0; |
827 | 833 | ||
828 | return 0; | 834 | return 0; |
835 | |||
836 | out: | ||
837 | while (i--) | ||
838 | kfree(c->jheads[i].log_hash); | ||
839 | |||
840 | return err; | ||
829 | } | 841 | } |
830 | 842 | ||
831 | /** | 843 | /** |
@@ -840,6 +852,7 @@ static void free_wbufs(struct ubifs_info *c) | |||
840 | for (i = 0; i < c->jhead_cnt; i++) { | 852 | for (i = 0; i < c->jhead_cnt; i++) { |
841 | kfree(c->jheads[i].wbuf.buf); | 853 | kfree(c->jheads[i].wbuf.buf); |
842 | kfree(c->jheads[i].wbuf.inodes); | 854 | kfree(c->jheads[i].wbuf.inodes); |
855 | kfree(c->jheads[i].log_hash); | ||
843 | } | 856 | } |
844 | kfree(c->jheads); | 857 | kfree(c->jheads); |
845 | c->jheads = NULL; | 858 | c->jheads = NULL; |
@@ -924,6 +937,8 @@ static int check_volume_empty(struct ubifs_info *c) | |||
924 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes | 937 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes |
925 | * Opt_override_compr: override default compressor | 938 | * Opt_override_compr: override default compressor |
926 | * Opt_assert: set ubifs_assert() action | 939 | * Opt_assert: set ubifs_assert() action |
940 | * Opt_auth_key: The key name used for authentication | ||
941 | * Opt_auth_hash_name: The hash type used for authentication | ||
927 | * Opt_err: just end of array marker | 942 | * Opt_err: just end of array marker |
928 | */ | 943 | */ |
929 | enum { | 944 | enum { |
@@ -935,6 +950,8 @@ enum { | |||
935 | Opt_no_chk_data_crc, | 950 | Opt_no_chk_data_crc, |
936 | Opt_override_compr, | 951 | Opt_override_compr, |
937 | Opt_assert, | 952 | Opt_assert, |
953 | Opt_auth_key, | ||
954 | Opt_auth_hash_name, | ||
938 | Opt_ignore, | 955 | Opt_ignore, |
939 | Opt_err, | 956 | Opt_err, |
940 | }; | 957 | }; |
@@ -947,6 +964,8 @@ static const match_table_t tokens = { | |||
947 | {Opt_chk_data_crc, "chk_data_crc"}, | 964 | {Opt_chk_data_crc, "chk_data_crc"}, |
948 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, | 965 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, |
949 | {Opt_override_compr, "compr=%s"}, | 966 | {Opt_override_compr, "compr=%s"}, |
967 | {Opt_auth_key, "auth_key=%s"}, | ||
968 | {Opt_auth_hash_name, "auth_hash_name=%s"}, | ||
950 | {Opt_ignore, "ubi=%s"}, | 969 | {Opt_ignore, "ubi=%s"}, |
951 | {Opt_ignore, "vol=%s"}, | 970 | {Opt_ignore, "vol=%s"}, |
952 | {Opt_assert, "assert=%s"}, | 971 | {Opt_assert, "assert=%s"}, |
@@ -1070,6 +1089,16 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
1070 | kfree(act); | 1089 | kfree(act); |
1071 | break; | 1090 | break; |
1072 | } | 1091 | } |
1092 | case Opt_auth_key: | ||
1093 | c->auth_key_name = kstrdup(args[0].from, GFP_KERNEL); | ||
1094 | if (!c->auth_key_name) | ||
1095 | return -ENOMEM; | ||
1096 | break; | ||
1097 | case Opt_auth_hash_name: | ||
1098 | c->auth_hash_name = kstrdup(args[0].from, GFP_KERNEL); | ||
1099 | if (!c->auth_hash_name) | ||
1100 | return -ENOMEM; | ||
1101 | break; | ||
1073 | case Opt_ignore: | 1102 | case Opt_ignore: |
1074 | break; | 1103 | break; |
1075 | default: | 1104 | default: |
@@ -1249,6 +1278,19 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1249 | 1278 | ||
1250 | c->mounting = 1; | 1279 | c->mounting = 1; |
1251 | 1280 | ||
1281 | if (c->auth_key_name) { | ||
1282 | if (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) { | ||
1283 | err = ubifs_init_authentication(c); | ||
1284 | if (err) | ||
1285 | goto out_free; | ||
1286 | } else { | ||
1287 | ubifs_err(c, "auth_key_name, but UBIFS is built without" | ||
1288 | " authentication support"); | ||
1289 | err = -EINVAL; | ||
1290 | goto out_free; | ||
1291 | } | ||
1292 | } | ||
1293 | |||
1252 | err = ubifs_read_superblock(c); | 1294 | err = ubifs_read_superblock(c); |
1253 | if (err) | 1295 | if (err) |
1254 | goto out_free; | 1296 | goto out_free; |
@@ -1367,12 +1409,21 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1367 | } | 1409 | } |
1368 | 1410 | ||
1369 | if (c->need_recovery) { | 1411 | if (c->need_recovery) { |
1370 | err = ubifs_recover_size(c); | 1412 | if (!ubifs_authenticated(c)) { |
1371 | if (err) | 1413 | err = ubifs_recover_size(c, true); |
1372 | goto out_orphans; | 1414 | if (err) |
1415 | goto out_orphans; | ||
1416 | } | ||
1417 | |||
1373 | err = ubifs_rcvry_gc_commit(c); | 1418 | err = ubifs_rcvry_gc_commit(c); |
1374 | if (err) | 1419 | if (err) |
1375 | goto out_orphans; | 1420 | goto out_orphans; |
1421 | |||
1422 | if (ubifs_authenticated(c)) { | ||
1423 | err = ubifs_recover_size(c, false); | ||
1424 | if (err) | ||
1425 | goto out_orphans; | ||
1426 | } | ||
1376 | } else { | 1427 | } else { |
1377 | err = take_gc_lnum(c); | 1428 | err = take_gc_lnum(c); |
1378 | if (err) | 1429 | if (err) |
@@ -1391,7 +1442,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1391 | if (err) | 1442 | if (err) |
1392 | goto out_orphans; | 1443 | goto out_orphans; |
1393 | } else if (c->need_recovery) { | 1444 | } else if (c->need_recovery) { |
1394 | err = ubifs_recover_size(c); | 1445 | err = ubifs_recover_size(c, false); |
1395 | if (err) | 1446 | if (err) |
1396 | goto out_orphans; | 1447 | goto out_orphans; |
1397 | } else { | 1448 | } else { |
@@ -1557,7 +1608,10 @@ static void ubifs_umount(struct ubifs_info *c) | |||
1557 | free_wbufs(c); | 1608 | free_wbufs(c); |
1558 | free_orphans(c); | 1609 | free_orphans(c); |
1559 | ubifs_lpt_free(c, 0); | 1610 | ubifs_lpt_free(c, 0); |
1611 | ubifs_exit_authentication(c); | ||
1560 | 1612 | ||
1613 | kfree(c->auth_key_name); | ||
1614 | kfree(c->auth_hash_name); | ||
1561 | kfree(c->cbuf); | 1615 | kfree(c->cbuf); |
1562 | kfree(c->rcvrd_mst_node); | 1616 | kfree(c->rcvrd_mst_node); |
1563 | kfree(c->mst_node); | 1617 | kfree(c->mst_node); |
@@ -1605,16 +1659,10 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1605 | goto out; | 1659 | goto out; |
1606 | 1660 | ||
1607 | if (c->old_leb_cnt != c->leb_cnt) { | 1661 | if (c->old_leb_cnt != c->leb_cnt) { |
1608 | struct ubifs_sb_node *sup; | 1662 | struct ubifs_sb_node *sup = c->sup_node; |
1609 | 1663 | ||
1610 | sup = ubifs_read_sb_node(c); | ||
1611 | if (IS_ERR(sup)) { | ||
1612 | err = PTR_ERR(sup); | ||
1613 | goto out; | ||
1614 | } | ||
1615 | sup->leb_cnt = cpu_to_le32(c->leb_cnt); | 1664 | sup->leb_cnt = cpu_to_le32(c->leb_cnt); |
1616 | err = ubifs_write_sb_node(c, sup); | 1665 | err = ubifs_write_sb_node(c, sup); |
1617 | kfree(sup); | ||
1618 | if (err) | 1666 | if (err) |
1619 | goto out; | 1667 | goto out; |
1620 | } | 1668 | } |
@@ -1624,9 +1672,11 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1624 | err = ubifs_write_rcvrd_mst_node(c); | 1672 | err = ubifs_write_rcvrd_mst_node(c); |
1625 | if (err) | 1673 | if (err) |
1626 | goto out; | 1674 | goto out; |
1627 | err = ubifs_recover_size(c); | 1675 | if (!ubifs_authenticated(c)) { |
1628 | if (err) | 1676 | err = ubifs_recover_size(c, true); |
1629 | goto out; | 1677 | if (err) |
1678 | goto out; | ||
1679 | } | ||
1630 | err = ubifs_clean_lebs(c, c->sbuf); | 1680 | err = ubifs_clean_lebs(c, c->sbuf); |
1631 | if (err) | 1681 | if (err) |
1632 | goto out; | 1682 | goto out; |
@@ -1692,10 +1742,19 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1692 | goto out; | 1742 | goto out; |
1693 | } | 1743 | } |
1694 | 1744 | ||
1695 | if (c->need_recovery) | 1745 | if (c->need_recovery) { |
1696 | err = ubifs_rcvry_gc_commit(c); | 1746 | err = ubifs_rcvry_gc_commit(c); |
1697 | else | 1747 | if (err) |
1748 | goto out; | ||
1749 | |||
1750 | if (ubifs_authenticated(c)) { | ||
1751 | err = ubifs_recover_size(c, false); | ||
1752 | if (err) | ||
1753 | goto out; | ||
1754 | } | ||
1755 | } else { | ||
1698 | err = ubifs_leb_unmap(c, c->gc_lnum); | 1756 | err = ubifs_leb_unmap(c, c->gc_lnum); |
1757 | } | ||
1699 | if (err) | 1758 | if (err) |
1700 | goto out; | 1759 | goto out; |
1701 | 1760 | ||
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index bf416e512743..25572ffea163 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "ubifs.h" | 35 | #include "ubifs.h" |
36 | 36 | ||
37 | static int try_read_node(const struct ubifs_info *c, void *buf, int type, | 37 | static int try_read_node(const struct ubifs_info *c, void *buf, int type, |
38 | int len, int lnum, int offs); | 38 | struct ubifs_zbranch *zbr); |
39 | static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, | 39 | static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, |
40 | struct ubifs_zbranch *zbr, void *node); | 40 | struct ubifs_zbranch *zbr, void *node); |
41 | 41 | ||
@@ -433,9 +433,7 @@ static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, | |||
433 | * @c: UBIFS file-system description object | 433 | * @c: UBIFS file-system description object |
434 | * @buf: buffer to read to | 434 | * @buf: buffer to read to |
435 | * @type: node type | 435 | * @type: node type |
436 | * @len: node length (not aligned) | 436 | * @zbr: the zbranch describing the node to read |
437 | * @lnum: LEB number of node to read | ||
438 | * @offs: offset of node to read | ||
439 | * | 437 | * |
440 | * This function tries to read a node of known type and length, checks it and | 438 | * This function tries to read a node of known type and length, checks it and |
441 | * stores it in @buf. This function returns %1 if a node is present and %0 if | 439 | * stores it in @buf. This function returns %1 if a node is present and %0 if |
@@ -453,8 +451,11 @@ static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, | |||
453 | * journal nodes may potentially be corrupted, so checking is required. | 451 | * journal nodes may potentially be corrupted, so checking is required. |
454 | */ | 452 | */ |
455 | static int try_read_node(const struct ubifs_info *c, void *buf, int type, | 453 | static int try_read_node(const struct ubifs_info *c, void *buf, int type, |
456 | int len, int lnum, int offs) | 454 | struct ubifs_zbranch *zbr) |
457 | { | 455 | { |
456 | int len = zbr->len; | ||
457 | int lnum = zbr->lnum; | ||
458 | int offs = zbr->offs; | ||
458 | int err, node_len; | 459 | int err, node_len; |
459 | struct ubifs_ch *ch = buf; | 460 | struct ubifs_ch *ch = buf; |
460 | uint32_t crc, node_crc; | 461 | uint32_t crc, node_crc; |
@@ -487,6 +488,12 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type, | |||
487 | if (crc != node_crc) | 488 | if (crc != node_crc) |
488 | return 0; | 489 | return 0; |
489 | 490 | ||
491 | err = ubifs_node_check_hash(c, buf, zbr->hash); | ||
492 | if (err) { | ||
493 | ubifs_bad_hash(c, buf, zbr->hash, lnum, offs); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
490 | return 1; | 497 | return 1; |
491 | } | 498 | } |
492 | 499 | ||
@@ -507,8 +514,7 @@ static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, | |||
507 | 514 | ||
508 | dbg_tnck(key, "LEB %d:%d, key ", zbr->lnum, zbr->offs); | 515 | dbg_tnck(key, "LEB %d:%d, key ", zbr->lnum, zbr->offs); |
509 | 516 | ||
510 | ret = try_read_node(c, node, key_type(c, key), zbr->len, zbr->lnum, | 517 | ret = try_read_node(c, node, key_type(c, key), zbr); |
511 | zbr->offs); | ||
512 | if (ret == 1) { | 518 | if (ret == 1) { |
513 | union ubifs_key node_key; | 519 | union ubifs_key node_key; |
514 | struct ubifs_dent_node *dent = node; | 520 | struct ubifs_dent_node *dent = node; |
@@ -1713,6 +1719,12 @@ static int validate_data_node(struct ubifs_info *c, void *buf, | |||
1713 | goto out; | 1719 | goto out; |
1714 | } | 1720 | } |
1715 | 1721 | ||
1722 | err = ubifs_node_check_hash(c, buf, zbr->hash); | ||
1723 | if (err) { | ||
1724 | ubifs_bad_hash(c, buf, zbr->hash, zbr->lnum, zbr->offs); | ||
1725 | return err; | ||
1726 | } | ||
1727 | |||
1716 | len = le32_to_cpu(ch->len); | 1728 | len = le32_to_cpu(ch->len); |
1717 | if (len != zbr->len) { | 1729 | if (len != zbr->len) { |
1718 | ubifs_err(c, "bad node length %d, expected %d", len, zbr->len); | 1730 | ubifs_err(c, "bad node length %d, expected %d", len, zbr->len); |
@@ -2260,13 +2272,14 @@ do_split: | |||
2260 | * @lnum: LEB number of node | 2272 | * @lnum: LEB number of node |
2261 | * @offs: node offset | 2273 | * @offs: node offset |
2262 | * @len: node length | 2274 | * @len: node length |
2275 | * @hash: The hash over the node | ||
2263 | * | 2276 | * |
2264 | * This function adds a node with key @key to TNC. The node may be new or it may | 2277 | * This function adds a node with key @key to TNC. The node may be new or it may |
2265 | * obsolete some existing one. Returns %0 on success or negative error code on | 2278 | * obsolete some existing one. Returns %0 on success or negative error code on |
2266 | * failure. | 2279 | * failure. |
2267 | */ | 2280 | */ |
2268 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | 2281 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, |
2269 | int offs, int len) | 2282 | int offs, int len, const u8 *hash) |
2270 | { | 2283 | { |
2271 | int found, n, err = 0; | 2284 | int found, n, err = 0; |
2272 | struct ubifs_znode *znode; | 2285 | struct ubifs_znode *znode; |
@@ -2281,6 +2294,7 @@ int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | |||
2281 | zbr.lnum = lnum; | 2294 | zbr.lnum = lnum; |
2282 | zbr.offs = offs; | 2295 | zbr.offs = offs; |
2283 | zbr.len = len; | 2296 | zbr.len = len; |
2297 | ubifs_copy_hash(c, hash, zbr.hash); | ||
2284 | key_copy(c, key, &zbr.key); | 2298 | key_copy(c, key, &zbr.key); |
2285 | err = tnc_insert(c, znode, &zbr, n + 1); | 2299 | err = tnc_insert(c, znode, &zbr, n + 1); |
2286 | } else if (found == 1) { | 2300 | } else if (found == 1) { |
@@ -2291,6 +2305,7 @@ int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | |||
2291 | zbr->lnum = lnum; | 2305 | zbr->lnum = lnum; |
2292 | zbr->offs = offs; | 2306 | zbr->offs = offs; |
2293 | zbr->len = len; | 2307 | zbr->len = len; |
2308 | ubifs_copy_hash(c, hash, zbr->hash); | ||
2294 | } else | 2309 | } else |
2295 | err = found; | 2310 | err = found; |
2296 | if (!err) | 2311 | if (!err) |
@@ -2392,13 +2407,14 @@ out_unlock: | |||
2392 | * @lnum: LEB number of node | 2407 | * @lnum: LEB number of node |
2393 | * @offs: node offset | 2408 | * @offs: node offset |
2394 | * @len: node length | 2409 | * @len: node length |
2410 | * @hash: The hash over the node | ||
2395 | * @nm: node name | 2411 | * @nm: node name |
2396 | * | 2412 | * |
2397 | * This is the same as 'ubifs_tnc_add()' but it should be used with keys which | 2413 | * This is the same as 'ubifs_tnc_add()' but it should be used with keys which |
2398 | * may have collisions, like directory entry keys. | 2414 | * may have collisions, like directory entry keys. |
2399 | */ | 2415 | */ |
2400 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | 2416 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, |
2401 | int lnum, int offs, int len, | 2417 | int lnum, int offs, int len, const u8 *hash, |
2402 | const struct fscrypt_name *nm) | 2418 | const struct fscrypt_name *nm) |
2403 | { | 2419 | { |
2404 | int found, n, err = 0; | 2420 | int found, n, err = 0; |
@@ -2441,6 +2457,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
2441 | zbr->lnum = lnum; | 2457 | zbr->lnum = lnum; |
2442 | zbr->offs = offs; | 2458 | zbr->offs = offs; |
2443 | zbr->len = len; | 2459 | zbr->len = len; |
2460 | ubifs_copy_hash(c, hash, zbr->hash); | ||
2444 | goto out_unlock; | 2461 | goto out_unlock; |
2445 | } | 2462 | } |
2446 | } | 2463 | } |
@@ -2452,6 +2469,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
2452 | zbr.lnum = lnum; | 2469 | zbr.lnum = lnum; |
2453 | zbr.offs = offs; | 2470 | zbr.offs = offs; |
2454 | zbr.len = len; | 2471 | zbr.len = len; |
2472 | ubifs_copy_hash(c, hash, zbr.hash); | ||
2455 | key_copy(c, key, &zbr.key); | 2473 | key_copy(c, key, &zbr.key); |
2456 | err = tnc_insert(c, znode, &zbr, n + 1); | 2474 | err = tnc_insert(c, znode, &zbr, n + 1); |
2457 | if (err) | 2475 | if (err) |
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index dba87d09b989..dbcd2c350b65 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c | |||
@@ -38,6 +38,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx, | |||
38 | struct ubifs_znode *znode, int lnum, int offs, int len) | 38 | struct ubifs_znode *znode, int lnum, int offs, int len) |
39 | { | 39 | { |
40 | struct ubifs_znode *zp; | 40 | struct ubifs_znode *zp; |
41 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
41 | int i, err; | 42 | int i, err; |
42 | 43 | ||
43 | /* Make index node */ | 44 | /* Make index node */ |
@@ -52,6 +53,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx, | |||
52 | br->lnum = cpu_to_le32(zbr->lnum); | 53 | br->lnum = cpu_to_le32(zbr->lnum); |
53 | br->offs = cpu_to_le32(zbr->offs); | 54 | br->offs = cpu_to_le32(zbr->offs); |
54 | br->len = cpu_to_le32(zbr->len); | 55 | br->len = cpu_to_le32(zbr->len); |
56 | ubifs_copy_hash(c, zbr->hash, ubifs_branch_hash(c, br)); | ||
55 | if (!zbr->lnum || !zbr->len) { | 57 | if (!zbr->lnum || !zbr->len) { |
56 | ubifs_err(c, "bad ref in znode"); | 58 | ubifs_err(c, "bad ref in znode"); |
57 | ubifs_dump_znode(c, znode); | 59 | ubifs_dump_znode(c, znode); |
@@ -62,6 +64,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx, | |||
62 | } | 64 | } |
63 | } | 65 | } |
64 | ubifs_prepare_node(c, idx, len, 0); | 66 | ubifs_prepare_node(c, idx, len, 0); |
67 | ubifs_node_calc_hash(c, idx, hash); | ||
65 | 68 | ||
66 | znode->lnum = lnum; | 69 | znode->lnum = lnum; |
67 | znode->offs = offs; | 70 | znode->offs = offs; |
@@ -78,10 +81,12 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx, | |||
78 | zbr->lnum = lnum; | 81 | zbr->lnum = lnum; |
79 | zbr->offs = offs; | 82 | zbr->offs = offs; |
80 | zbr->len = len; | 83 | zbr->len = len; |
84 | ubifs_copy_hash(c, hash, zbr->hash); | ||
81 | } else { | 85 | } else { |
82 | c->zroot.lnum = lnum; | 86 | c->zroot.lnum = lnum; |
83 | c->zroot.offs = offs; | 87 | c->zroot.offs = offs; |
84 | c->zroot.len = len; | 88 | c->zroot.len = len; |
89 | ubifs_copy_hash(c, hash, c->zroot.hash); | ||
85 | } | 90 | } |
86 | c->calc_idx_sz += ALIGN(len, 8); | 91 | c->calc_idx_sz += ALIGN(len, 8); |
87 | 92 | ||
@@ -647,6 +652,8 @@ static int get_znodes_to_commit(struct ubifs_info *c) | |||
647 | znode->cnext = c->cnext; | 652 | znode->cnext = c->cnext; |
648 | break; | 653 | break; |
649 | } | 654 | } |
655 | znode->cparent = znode->parent; | ||
656 | znode->ciip = znode->iip; | ||
650 | znode->cnext = cnext; | 657 | znode->cnext = cnext; |
651 | znode = cnext; | 658 | znode = cnext; |
652 | cnt += 1; | 659 | cnt += 1; |
@@ -840,6 +847,8 @@ static int write_index(struct ubifs_info *c) | |||
840 | } | 847 | } |
841 | 848 | ||
842 | while (1) { | 849 | while (1) { |
850 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
851 | |||
843 | cond_resched(); | 852 | cond_resched(); |
844 | 853 | ||
845 | znode = cnext; | 854 | znode = cnext; |
@@ -857,6 +866,7 @@ static int write_index(struct ubifs_info *c) | |||
857 | br->lnum = cpu_to_le32(zbr->lnum); | 866 | br->lnum = cpu_to_le32(zbr->lnum); |
858 | br->offs = cpu_to_le32(zbr->offs); | 867 | br->offs = cpu_to_le32(zbr->offs); |
859 | br->len = cpu_to_le32(zbr->len); | 868 | br->len = cpu_to_le32(zbr->len); |
869 | ubifs_copy_hash(c, zbr->hash, ubifs_branch_hash(c, br)); | ||
860 | if (!zbr->lnum || !zbr->len) { | 870 | if (!zbr->lnum || !zbr->len) { |
861 | ubifs_err(c, "bad ref in znode"); | 871 | ubifs_err(c, "bad ref in znode"); |
862 | ubifs_dump_znode(c, znode); | 872 | ubifs_dump_znode(c, znode); |
@@ -868,6 +878,23 @@ static int write_index(struct ubifs_info *c) | |||
868 | } | 878 | } |
869 | len = ubifs_idx_node_sz(c, znode->child_cnt); | 879 | len = ubifs_idx_node_sz(c, znode->child_cnt); |
870 | ubifs_prepare_node(c, idx, len, 0); | 880 | ubifs_prepare_node(c, idx, len, 0); |
881 | ubifs_node_calc_hash(c, idx, hash); | ||
882 | |||
883 | mutex_lock(&c->tnc_mutex); | ||
884 | |||
885 | if (znode->cparent) | ||
886 | ubifs_copy_hash(c, hash, | ||
887 | znode->cparent->zbranch[znode->ciip].hash); | ||
888 | |||
889 | if (znode->parent) { | ||
890 | if (!ubifs_zn_obsolete(znode)) | ||
891 | ubifs_copy_hash(c, hash, | ||
892 | znode->parent->zbranch[znode->iip].hash); | ||
893 | } else { | ||
894 | ubifs_copy_hash(c, hash, c->zroot.hash); | ||
895 | } | ||
896 | |||
897 | mutex_unlock(&c->tnc_mutex); | ||
871 | 898 | ||
872 | /* Determine the index node position */ | 899 | /* Determine the index node position */ |
873 | if (lnum == -1) { | 900 | if (lnum == -1) { |
diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c index d90ee01076a9..d1815e959007 100644 --- a/fs/ubifs/tnc_misc.c +++ b/fs/ubifs/tnc_misc.c | |||
@@ -265,9 +265,7 @@ long ubifs_destroy_tnc_subtree(const struct ubifs_info *c, | |||
265 | /** | 265 | /** |
266 | * read_znode - read an indexing node from flash and fill znode. | 266 | * read_znode - read an indexing node from flash and fill znode. |
267 | * @c: UBIFS file-system description object | 267 | * @c: UBIFS file-system description object |
268 | * @lnum: LEB of the indexing node to read | 268 | * @zzbr: the zbranch describing the node to read |
269 | * @offs: node offset | ||
270 | * @len: node length | ||
271 | * @znode: znode to read to | 269 | * @znode: znode to read to |
272 | * | 270 | * |
273 | * This function reads an indexing node from the flash media and fills znode | 271 | * This function reads an indexing node from the flash media and fills znode |
@@ -276,9 +274,12 @@ long ubifs_destroy_tnc_subtree(const struct ubifs_info *c, | |||
276 | * is wrong with it, this function prints complaint messages and returns | 274 | * is wrong with it, this function prints complaint messages and returns |
277 | * %-EINVAL. | 275 | * %-EINVAL. |
278 | */ | 276 | */ |
279 | static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, | 277 | static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr, |
280 | struct ubifs_znode *znode) | 278 | struct ubifs_znode *znode) |
281 | { | 279 | { |
280 | int lnum = zzbr->lnum; | ||
281 | int offs = zzbr->offs; | ||
282 | int len = zzbr->len; | ||
282 | int i, err, type, cmp; | 283 | int i, err, type, cmp; |
283 | struct ubifs_idx_node *idx; | 284 | struct ubifs_idx_node *idx; |
284 | 285 | ||
@@ -292,6 +293,12 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, | |||
292 | return err; | 293 | return err; |
293 | } | 294 | } |
294 | 295 | ||
296 | err = ubifs_node_check_hash(c, idx, zzbr->hash); | ||
297 | if (err) { | ||
298 | ubifs_bad_hash(c, idx, zzbr->hash, lnum, offs); | ||
299 | return err; | ||
300 | } | ||
301 | |||
295 | znode->child_cnt = le16_to_cpu(idx->child_cnt); | 302 | znode->child_cnt = le16_to_cpu(idx->child_cnt); |
296 | znode->level = le16_to_cpu(idx->level); | 303 | znode->level = le16_to_cpu(idx->level); |
297 | 304 | ||
@@ -308,13 +315,14 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, | |||
308 | } | 315 | } |
309 | 316 | ||
310 | for (i = 0; i < znode->child_cnt; i++) { | 317 | for (i = 0; i < znode->child_cnt; i++) { |
311 | const struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); | 318 | struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); |
312 | struct ubifs_zbranch *zbr = &znode->zbranch[i]; | 319 | struct ubifs_zbranch *zbr = &znode->zbranch[i]; |
313 | 320 | ||
314 | key_read(c, &br->key, &zbr->key); | 321 | key_read(c, &br->key, &zbr->key); |
315 | zbr->lnum = le32_to_cpu(br->lnum); | 322 | zbr->lnum = le32_to_cpu(br->lnum); |
316 | zbr->offs = le32_to_cpu(br->offs); | 323 | zbr->offs = le32_to_cpu(br->offs); |
317 | zbr->len = le32_to_cpu(br->len); | 324 | zbr->len = le32_to_cpu(br->len); |
325 | ubifs_copy_hash(c, ubifs_branch_hash(c, br), zbr->hash); | ||
318 | zbr->znode = NULL; | 326 | zbr->znode = NULL; |
319 | 327 | ||
320 | /* Validate branch */ | 328 | /* Validate branch */ |
@@ -425,7 +433,7 @@ struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c, | |||
425 | if (!znode) | 433 | if (!znode) |
426 | return ERR_PTR(-ENOMEM); | 434 | return ERR_PTR(-ENOMEM); |
427 | 435 | ||
428 | err = read_znode(c, zbr->lnum, zbr->offs, zbr->len, znode); | 436 | err = read_znode(c, zbr, znode); |
429 | if (err) | 437 | if (err) |
430 | goto out; | 438 | goto out; |
431 | 439 | ||
@@ -496,5 +504,11 @@ int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, | |||
496 | return -EINVAL; | 504 | return -EINVAL; |
497 | } | 505 | } |
498 | 506 | ||
507 | err = ubifs_node_check_hash(c, node, zbr->hash); | ||
508 | if (err) { | ||
509 | ubifs_bad_hash(c, node, zbr->hash, zbr->lnum, zbr->offs); | ||
510 | return err; | ||
511 | } | ||
512 | |||
499 | return 0; | 513 | return 0; |
500 | } | 514 | } |
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index e8c23c9d4f4a..8b7c1844014f 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h | |||
@@ -286,6 +286,7 @@ enum { | |||
286 | #define UBIFS_IDX_NODE_SZ sizeof(struct ubifs_idx_node) | 286 | #define UBIFS_IDX_NODE_SZ sizeof(struct ubifs_idx_node) |
287 | #define UBIFS_CS_NODE_SZ sizeof(struct ubifs_cs_node) | 287 | #define UBIFS_CS_NODE_SZ sizeof(struct ubifs_cs_node) |
288 | #define UBIFS_ORPH_NODE_SZ sizeof(struct ubifs_orph_node) | 288 | #define UBIFS_ORPH_NODE_SZ sizeof(struct ubifs_orph_node) |
289 | #define UBIFS_AUTH_NODE_SZ sizeof(struct ubifs_auth_node) | ||
289 | /* Extended attribute entry nodes are identical to directory entry nodes */ | 290 | /* Extended attribute entry nodes are identical to directory entry nodes */ |
290 | #define UBIFS_XENT_NODE_SZ UBIFS_DENT_NODE_SZ | 291 | #define UBIFS_XENT_NODE_SZ UBIFS_DENT_NODE_SZ |
291 | /* Only this does not have to be multiple of 8 bytes */ | 292 | /* Only this does not have to be multiple of 8 bytes */ |
@@ -300,6 +301,12 @@ enum { | |||
300 | /* The largest UBIFS node */ | 301 | /* The largest UBIFS node */ |
301 | #define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ | 302 | #define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ |
302 | 303 | ||
304 | /* The maxmimum size of a hash, enough for sha512 */ | ||
305 | #define UBIFS_MAX_HASH_LEN 64 | ||
306 | |||
307 | /* The maxmimum size of a hmac, enough for hmac(sha512) */ | ||
308 | #define UBIFS_MAX_HMAC_LEN 64 | ||
309 | |||
303 | /* | 310 | /* |
304 | * xattr name of UBIFS encryption context, we don't use a prefix | 311 | * xattr name of UBIFS encryption context, we don't use a prefix |
305 | * nor a long name to not waste space on the flash. | 312 | * nor a long name to not waste space on the flash. |
@@ -365,6 +372,7 @@ enum { | |||
365 | * UBIFS_IDX_NODE: index node | 372 | * UBIFS_IDX_NODE: index node |
366 | * UBIFS_CS_NODE: commit start node | 373 | * UBIFS_CS_NODE: commit start node |
367 | * UBIFS_ORPH_NODE: orphan node | 374 | * UBIFS_ORPH_NODE: orphan node |
375 | * UBIFS_AUTH_NODE: authentication node | ||
368 | * UBIFS_NODE_TYPES_CNT: count of supported node types | 376 | * UBIFS_NODE_TYPES_CNT: count of supported node types |
369 | * | 377 | * |
370 | * Note, we index arrays by these numbers, so keep them low and contiguous. | 378 | * Note, we index arrays by these numbers, so keep them low and contiguous. |
@@ -384,6 +392,7 @@ enum { | |||
384 | UBIFS_IDX_NODE, | 392 | UBIFS_IDX_NODE, |
385 | UBIFS_CS_NODE, | 393 | UBIFS_CS_NODE, |
386 | UBIFS_ORPH_NODE, | 394 | UBIFS_ORPH_NODE, |
395 | UBIFS_AUTH_NODE, | ||
387 | UBIFS_NODE_TYPES_CNT, | 396 | UBIFS_NODE_TYPES_CNT, |
388 | }; | 397 | }; |
389 | 398 | ||
@@ -421,15 +430,19 @@ enum { | |||
421 | * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to | 430 | * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to |
422 | * support 64bit cookies for lookups by hash | 431 | * support 64bit cookies for lookups by hash |
423 | * UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files | 432 | * UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files |
433 | * UBIFS_FLG_AUTHENTICATION: this filesystem contains hashes for authentication | ||
424 | */ | 434 | */ |
425 | enum { | 435 | enum { |
426 | UBIFS_FLG_BIGLPT = 0x02, | 436 | UBIFS_FLG_BIGLPT = 0x02, |
427 | UBIFS_FLG_SPACE_FIXUP = 0x04, | 437 | UBIFS_FLG_SPACE_FIXUP = 0x04, |
428 | UBIFS_FLG_DOUBLE_HASH = 0x08, | 438 | UBIFS_FLG_DOUBLE_HASH = 0x08, |
429 | UBIFS_FLG_ENCRYPTION = 0x10, | 439 | UBIFS_FLG_ENCRYPTION = 0x10, |
440 | UBIFS_FLG_AUTHENTICATION = 0x20, | ||
430 | }; | 441 | }; |
431 | 442 | ||
432 | #define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT|UBIFS_FLG_SPACE_FIXUP|UBIFS_FLG_DOUBLE_HASH|UBIFS_FLG_ENCRYPTION) | 443 | #define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT | UBIFS_FLG_SPACE_FIXUP | \ |
444 | UBIFS_FLG_DOUBLE_HASH | UBIFS_FLG_ENCRYPTION | \ | ||
445 | UBIFS_FLG_AUTHENTICATION) | ||
433 | 446 | ||
434 | /** | 447 | /** |
435 | * struct ubifs_ch - common header node. | 448 | * struct ubifs_ch - common header node. |
@@ -633,6 +646,10 @@ struct ubifs_pad_node { | |||
633 | * @time_gran: time granularity in nanoseconds | 646 | * @time_gran: time granularity in nanoseconds |
634 | * @uuid: UUID generated when the file system image was created | 647 | * @uuid: UUID generated when the file system image was created |
635 | * @ro_compat_version: UBIFS R/O compatibility version | 648 | * @ro_compat_version: UBIFS R/O compatibility version |
649 | * @hmac: HMAC to authenticate the superblock node | ||
650 | * @hmac_wkm: HMAC of a well known message (the string "UBIFS") as a convenience | ||
651 | * to the user to check if the correct key is passed. | ||
652 | * @hash_algo: The hash algo used for this filesystem (one of enum hash_algo) | ||
636 | */ | 653 | */ |
637 | struct ubifs_sb_node { | 654 | struct ubifs_sb_node { |
638 | struct ubifs_ch ch; | 655 | struct ubifs_ch ch; |
@@ -660,7 +677,10 @@ struct ubifs_sb_node { | |||
660 | __le32 time_gran; | 677 | __le32 time_gran; |
661 | __u8 uuid[16]; | 678 | __u8 uuid[16]; |
662 | __le32 ro_compat_version; | 679 | __le32 ro_compat_version; |
663 | __u8 padding2[3968]; | 680 | __u8 hmac[UBIFS_MAX_HMAC_LEN]; |
681 | __u8 hmac_wkm[UBIFS_MAX_HMAC_LEN]; | ||
682 | __le16 hash_algo; | ||
683 | __u8 padding2[3838]; | ||
664 | } __packed; | 684 | } __packed; |
665 | 685 | ||
666 | /** | 686 | /** |
@@ -695,6 +715,9 @@ struct ubifs_sb_node { | |||
695 | * @empty_lebs: number of empty logical eraseblocks | 715 | * @empty_lebs: number of empty logical eraseblocks |
696 | * @idx_lebs: number of indexing logical eraseblocks | 716 | * @idx_lebs: number of indexing logical eraseblocks |
697 | * @leb_cnt: count of LEBs used by file-system | 717 | * @leb_cnt: count of LEBs used by file-system |
718 | * @hash_root_idx: the hash of the root index node | ||
719 | * @hash_lpt: the hash of the LPT | ||
720 | * @hmac: HMAC to authenticate the master node | ||
698 | * @padding: reserved for future, zeroes | 721 | * @padding: reserved for future, zeroes |
699 | */ | 722 | */ |
700 | struct ubifs_mst_node { | 723 | struct ubifs_mst_node { |
@@ -727,7 +750,10 @@ struct ubifs_mst_node { | |||
727 | __le32 empty_lebs; | 750 | __le32 empty_lebs; |
728 | __le32 idx_lebs; | 751 | __le32 idx_lebs; |
729 | __le32 leb_cnt; | 752 | __le32 leb_cnt; |
730 | __u8 padding[344]; | 753 | __u8 hash_root_idx[UBIFS_MAX_HASH_LEN]; |
754 | __u8 hash_lpt[UBIFS_MAX_HASH_LEN]; | ||
755 | __u8 hmac[UBIFS_MAX_HMAC_LEN]; | ||
756 | __u8 padding[152]; | ||
731 | } __packed; | 757 | } __packed; |
732 | 758 | ||
733 | /** | 759 | /** |
@@ -747,11 +773,25 @@ struct ubifs_ref_node { | |||
747 | } __packed; | 773 | } __packed; |
748 | 774 | ||
749 | /** | 775 | /** |
776 | * struct ubifs_auth_node - node for authenticating other nodes | ||
777 | * @ch: common header | ||
778 | * @hmac: The HMAC | ||
779 | */ | ||
780 | struct ubifs_auth_node { | ||
781 | struct ubifs_ch ch; | ||
782 | __u8 hmac[]; | ||
783 | } __packed; | ||
784 | |||
785 | /** | ||
750 | * struct ubifs_branch - key/reference/length branch | 786 | * struct ubifs_branch - key/reference/length branch |
751 | * @lnum: LEB number of the target node | 787 | * @lnum: LEB number of the target node |
752 | * @offs: offset within @lnum | 788 | * @offs: offset within @lnum |
753 | * @len: target node length | 789 | * @len: target node length |
754 | * @key: key | 790 | * @key: key |
791 | * | ||
792 | * In an authenticated UBIFS we have the hash of the referenced node after @key. | ||
793 | * This can't be added to the struct type definition because @key is a | ||
794 | * dynamically sized element already. | ||
755 | */ | 795 | */ |
756 | struct ubifs_branch { | 796 | struct ubifs_branch { |
757 | __le32 lnum; | 797 | __le32 lnum; |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 4368cde476b0..38401adaa00d 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -39,6 +39,9 @@ | |||
39 | #include <linux/security.h> | 39 | #include <linux/security.h> |
40 | #include <linux/xattr.h> | 40 | #include <linux/xattr.h> |
41 | #include <linux/random.h> | 41 | #include <linux/random.h> |
42 | #include <crypto/hash_info.h> | ||
43 | #include <crypto/hash.h> | ||
44 | #include <crypto/algapi.h> | ||
42 | 45 | ||
43 | #define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION) | 46 | #define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION) |
44 | #include <linux/fscrypt.h> | 47 | #include <linux/fscrypt.h> |
@@ -157,6 +160,14 @@ | |||
157 | /* Maximum number of data nodes to bulk-read */ | 160 | /* Maximum number of data nodes to bulk-read */ |
158 | #define UBIFS_MAX_BULK_READ 32 | 161 | #define UBIFS_MAX_BULK_READ 32 |
159 | 162 | ||
163 | #ifdef CONFIG_UBIFS_FS_AUTHENTICATION | ||
164 | #define UBIFS_HASH_ARR_SZ UBIFS_MAX_HASH_LEN | ||
165 | #define UBIFS_HMAC_ARR_SZ UBIFS_MAX_HMAC_LEN | ||
166 | #else | ||
167 | #define UBIFS_HASH_ARR_SZ 0 | ||
168 | #define UBIFS_HMAC_ARR_SZ 0 | ||
169 | #endif | ||
170 | |||
160 | /* | 171 | /* |
161 | * Lockdep classes for UBIFS inode @ui_mutex. | 172 | * Lockdep classes for UBIFS inode @ui_mutex. |
162 | */ | 173 | */ |
@@ -706,6 +717,7 @@ struct ubifs_wbuf { | |||
706 | * @jhead: journal head number this bud belongs to | 717 | * @jhead: journal head number this bud belongs to |
707 | * @list: link in the list buds belonging to the same journal head | 718 | * @list: link in the list buds belonging to the same journal head |
708 | * @rb: link in the tree of all buds | 719 | * @rb: link in the tree of all buds |
720 | * @log_hash: the log hash from the commit start node up to this bud | ||
709 | */ | 721 | */ |
710 | struct ubifs_bud { | 722 | struct ubifs_bud { |
711 | int lnum; | 723 | int lnum; |
@@ -713,6 +725,7 @@ struct ubifs_bud { | |||
713 | int jhead; | 725 | int jhead; |
714 | struct list_head list; | 726 | struct list_head list; |
715 | struct rb_node rb; | 727 | struct rb_node rb; |
728 | struct shash_desc *log_hash; | ||
716 | }; | 729 | }; |
717 | 730 | ||
718 | /** | 731 | /** |
@@ -720,6 +733,7 @@ struct ubifs_bud { | |||
720 | * @wbuf: head's write-buffer | 733 | * @wbuf: head's write-buffer |
721 | * @buds_list: list of bud LEBs belonging to this journal head | 734 | * @buds_list: list of bud LEBs belonging to this journal head |
722 | * @grouped: non-zero if UBIFS groups nodes when writing to this journal head | 735 | * @grouped: non-zero if UBIFS groups nodes when writing to this journal head |
736 | * @log_hash: the log hash from the commit start node up to this journal head | ||
723 | * | 737 | * |
724 | * Note, the @buds list is protected by the @c->buds_lock. | 738 | * Note, the @buds list is protected by the @c->buds_lock. |
725 | */ | 739 | */ |
@@ -727,6 +741,7 @@ struct ubifs_jhead { | |||
727 | struct ubifs_wbuf wbuf; | 741 | struct ubifs_wbuf wbuf; |
728 | struct list_head buds_list; | 742 | struct list_head buds_list; |
729 | unsigned int grouped:1; | 743 | unsigned int grouped:1; |
744 | struct shash_desc *log_hash; | ||
730 | }; | 745 | }; |
731 | 746 | ||
732 | /** | 747 | /** |
@@ -736,6 +751,7 @@ struct ubifs_jhead { | |||
736 | * @lnum: LEB number of the target node (indexing node or data node) | 751 | * @lnum: LEB number of the target node (indexing node or data node) |
737 | * @offs: target node offset within @lnum | 752 | * @offs: target node offset within @lnum |
738 | * @len: target node length | 753 | * @len: target node length |
754 | * @hash: the hash of the target node | ||
739 | */ | 755 | */ |
740 | struct ubifs_zbranch { | 756 | struct ubifs_zbranch { |
741 | union ubifs_key key; | 757 | union ubifs_key key; |
@@ -746,12 +762,15 @@ struct ubifs_zbranch { | |||
746 | int lnum; | 762 | int lnum; |
747 | int offs; | 763 | int offs; |
748 | int len; | 764 | int len; |
765 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
749 | }; | 766 | }; |
750 | 767 | ||
751 | /** | 768 | /** |
752 | * struct ubifs_znode - in-memory representation of an indexing node. | 769 | * struct ubifs_znode - in-memory representation of an indexing node. |
753 | * @parent: parent znode or NULL if it is the root | 770 | * @parent: parent znode or NULL if it is the root |
754 | * @cnext: next znode to commit | 771 | * @cnext: next znode to commit |
772 | * @cparent: parent node for this commit | ||
773 | * @ciip: index in cparent's zbranch array | ||
755 | * @flags: znode flags (%DIRTY_ZNODE, %COW_ZNODE or %OBSOLETE_ZNODE) | 774 | * @flags: znode flags (%DIRTY_ZNODE, %COW_ZNODE or %OBSOLETE_ZNODE) |
756 | * @time: last access time (seconds) | 775 | * @time: last access time (seconds) |
757 | * @level: level of the entry in the TNC tree | 776 | * @level: level of the entry in the TNC tree |
@@ -769,6 +788,8 @@ struct ubifs_zbranch { | |||
769 | struct ubifs_znode { | 788 | struct ubifs_znode { |
770 | struct ubifs_znode *parent; | 789 | struct ubifs_znode *parent; |
771 | struct ubifs_znode *cnext; | 790 | struct ubifs_znode *cnext; |
791 | struct ubifs_znode *cparent; | ||
792 | int ciip; | ||
772 | unsigned long flags; | 793 | unsigned long flags; |
773 | time64_t time; | 794 | time64_t time; |
774 | int level; | 795 | int level; |
@@ -983,6 +1004,7 @@ struct ubifs_debug_info; | |||
983 | * struct ubifs_info - UBIFS file-system description data structure | 1004 | * struct ubifs_info - UBIFS file-system description data structure |
984 | * (per-superblock). | 1005 | * (per-superblock). |
985 | * @vfs_sb: VFS @struct super_block object | 1006 | * @vfs_sb: VFS @struct super_block object |
1007 | * @sup_node: The super block node as read from the device | ||
986 | * | 1008 | * |
987 | * @highest_inum: highest used inode number | 1009 | * @highest_inum: highest used inode number |
988 | * @max_sqnum: current global sequence number | 1010 | * @max_sqnum: current global sequence number |
@@ -1028,6 +1050,7 @@ struct ubifs_debug_info; | |||
1028 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) | 1050 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) |
1029 | * @rw_incompat: the media is not R/W compatible | 1051 | * @rw_incompat: the media is not R/W compatible |
1030 | * @assert_action: action to take when a ubifs_assert() fails | 1052 | * @assert_action: action to take when a ubifs_assert() fails |
1053 | * @authenticated: flag indigating the FS is mounted in authenticated mode | ||
1031 | * | 1054 | * |
1032 | * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and | 1055 | * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and |
1033 | * @calc_idx_sz | 1056 | * @calc_idx_sz |
@@ -1075,6 +1098,7 @@ struct ubifs_debug_info; | |||
1075 | * @key_hash: direntry key hash function | 1098 | * @key_hash: direntry key hash function |
1076 | * @key_fmt: key format | 1099 | * @key_fmt: key format |
1077 | * @key_len: key length | 1100 | * @key_len: key length |
1101 | * @hash_len: The length of the index node hashes | ||
1078 | * @fanout: fanout of the index tree (number of links per indexing node) | 1102 | * @fanout: fanout of the index tree (number of links per indexing node) |
1079 | * | 1103 | * |
1080 | * @min_io_size: minimal input/output unit size | 1104 | * @min_io_size: minimal input/output unit size |
@@ -1210,6 +1234,15 @@ struct ubifs_debug_info; | |||
1210 | * @rp_uid: reserved pool user ID | 1234 | * @rp_uid: reserved pool user ID |
1211 | * @rp_gid: reserved pool group ID | 1235 | * @rp_gid: reserved pool group ID |
1212 | * | 1236 | * |
1237 | * @hash_tfm: the hash transformation used for hashing nodes | ||
1238 | * @hmac_tfm: the HMAC transformation for this filesystem | ||
1239 | * @hmac_desc_len: length of the HMAC used for authentication | ||
1240 | * @auth_key_name: the authentication key name | ||
1241 | * @auth_hash_name: the name of the hash algorithm used for authentication | ||
1242 | * @auth_hash_algo: the authentication hash used for this fs | ||
1243 | * @log_hash: the log hash from the commit start node up to the latest reference | ||
1244 | * node. | ||
1245 | * | ||
1213 | * @empty: %1 if the UBI device is empty | 1246 | * @empty: %1 if the UBI device is empty |
1214 | * @need_recovery: %1 if the file-system needs recovery | 1247 | * @need_recovery: %1 if the file-system needs recovery |
1215 | * @replaying: %1 during journal replay | 1248 | * @replaying: %1 during journal replay |
@@ -1230,6 +1263,7 @@ struct ubifs_debug_info; | |||
1230 | */ | 1263 | */ |
1231 | struct ubifs_info { | 1264 | struct ubifs_info { |
1232 | struct super_block *vfs_sb; | 1265 | struct super_block *vfs_sb; |
1266 | struct ubifs_sb_node *sup_node; | ||
1233 | 1267 | ||
1234 | ino_t highest_inum; | 1268 | ino_t highest_inum; |
1235 | unsigned long long max_sqnum; | 1269 | unsigned long long max_sqnum; |
@@ -1270,6 +1304,7 @@ struct ubifs_info { | |||
1270 | unsigned int default_compr:2; | 1304 | unsigned int default_compr:2; |
1271 | unsigned int rw_incompat:1; | 1305 | unsigned int rw_incompat:1; |
1272 | unsigned int assert_action:2; | 1306 | unsigned int assert_action:2; |
1307 | unsigned int authenticated:1; | ||
1273 | 1308 | ||
1274 | struct mutex tnc_mutex; | 1309 | struct mutex tnc_mutex; |
1275 | struct ubifs_zbranch zroot; | 1310 | struct ubifs_zbranch zroot; |
@@ -1314,6 +1349,7 @@ struct ubifs_info { | |||
1314 | uint32_t (*key_hash)(const char *str, int len); | 1349 | uint32_t (*key_hash)(const char *str, int len); |
1315 | int key_fmt; | 1350 | int key_fmt; |
1316 | int key_len; | 1351 | int key_len; |
1352 | int hash_len; | ||
1317 | int fanout; | 1353 | int fanout; |
1318 | 1354 | ||
1319 | int min_io_size; | 1355 | int min_io_size; |
@@ -1441,6 +1477,15 @@ struct ubifs_info { | |||
1441 | kuid_t rp_uid; | 1477 | kuid_t rp_uid; |
1442 | kgid_t rp_gid; | 1478 | kgid_t rp_gid; |
1443 | 1479 | ||
1480 | struct crypto_shash *hash_tfm; | ||
1481 | struct crypto_shash *hmac_tfm; | ||
1482 | int hmac_desc_len; | ||
1483 | char *auth_key_name; | ||
1484 | char *auth_hash_name; | ||
1485 | enum hash_algo auth_hash_algo; | ||
1486 | |||
1487 | struct shash_desc *log_hash; | ||
1488 | |||
1444 | /* The below fields are used only during mounting and re-mounting */ | 1489 | /* The below fields are used only during mounting and re-mounting */ |
1445 | unsigned int empty:1; | 1490 | unsigned int empty:1; |
1446 | unsigned int need_recovery:1; | 1491 | unsigned int need_recovery:1; |
@@ -1471,6 +1516,195 @@ extern const struct inode_operations ubifs_dir_inode_operations; | |||
1471 | extern const struct inode_operations ubifs_symlink_inode_operations; | 1516 | extern const struct inode_operations ubifs_symlink_inode_operations; |
1472 | extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; | 1517 | extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; |
1473 | 1518 | ||
1519 | /* auth.c */ | ||
1520 | static inline int ubifs_authenticated(const struct ubifs_info *c) | ||
1521 | { | ||
1522 | return (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) && c->authenticated; | ||
1523 | } | ||
1524 | |||
1525 | struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c); | ||
1526 | static inline struct shash_desc *ubifs_hash_get_desc(const struct ubifs_info *c) | ||
1527 | { | ||
1528 | return ubifs_authenticated(c) ? __ubifs_hash_get_desc(c) : NULL; | ||
1529 | } | ||
1530 | |||
1531 | static inline int ubifs_shash_init(const struct ubifs_info *c, | ||
1532 | struct shash_desc *desc) | ||
1533 | { | ||
1534 | if (ubifs_authenticated(c)) | ||
1535 | return crypto_shash_init(desc); | ||
1536 | else | ||
1537 | return 0; | ||
1538 | } | ||
1539 | |||
1540 | static inline int ubifs_shash_update(const struct ubifs_info *c, | ||
1541 | struct shash_desc *desc, const void *buf, | ||
1542 | unsigned int len) | ||
1543 | { | ||
1544 | int err = 0; | ||
1545 | |||
1546 | if (ubifs_authenticated(c)) { | ||
1547 | err = crypto_shash_update(desc, buf, len); | ||
1548 | if (err < 0) | ||
1549 | return err; | ||
1550 | } | ||
1551 | |||
1552 | return 0; | ||
1553 | } | ||
1554 | |||
1555 | static inline int ubifs_shash_final(const struct ubifs_info *c, | ||
1556 | struct shash_desc *desc, u8 *out) | ||
1557 | { | ||
1558 | return ubifs_authenticated(c) ? crypto_shash_final(desc, out) : 0; | ||
1559 | } | ||
1560 | |||
1561 | int __ubifs_node_calc_hash(const struct ubifs_info *c, const void *buf, | ||
1562 | u8 *hash); | ||
1563 | static inline int ubifs_node_calc_hash(const struct ubifs_info *c, | ||
1564 | const void *buf, u8 *hash) | ||
1565 | { | ||
1566 | if (ubifs_authenticated(c)) | ||
1567 | return __ubifs_node_calc_hash(c, buf, hash); | ||
1568 | else | ||
1569 | return 0; | ||
1570 | } | ||
1571 | |||
1572 | int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, | ||
1573 | struct shash_desc *inhash); | ||
1574 | |||
1575 | /** | ||
1576 | * ubifs_check_hash - compare two hashes | ||
1577 | * @c: UBIFS file-system description object | ||
1578 | * @expected: first hash | ||
1579 | * @got: second hash | ||
1580 | * | ||
1581 | * Compare two hashes @expected and @got. Returns 0 when they are equal, a | ||
1582 | * negative error code otherwise. | ||
1583 | */ | ||
1584 | static inline int ubifs_check_hash(const struct ubifs_info *c, | ||
1585 | const u8 *expected, const u8 *got) | ||
1586 | { | ||
1587 | return crypto_memneq(expected, got, c->hash_len); | ||
1588 | } | ||
1589 | |||
1590 | /** | ||
1591 | * ubifs_check_hmac - compare two HMACs | ||
1592 | * @c: UBIFS file-system description object | ||
1593 | * @expected: first HMAC | ||
1594 | * @got: second HMAC | ||
1595 | * | ||
1596 | * Compare two hashes @expected and @got. Returns 0 when they are equal, a | ||
1597 | * negative error code otherwise. | ||
1598 | */ | ||
1599 | static inline int ubifs_check_hmac(const struct ubifs_info *c, | ||
1600 | const u8 *expected, const u8 *got) | ||
1601 | { | ||
1602 | return crypto_memneq(expected, got, c->hmac_desc_len); | ||
1603 | } | ||
1604 | |||
1605 | void ubifs_bad_hash(const struct ubifs_info *c, const void *node, | ||
1606 | const u8 *hash, int lnum, int offs); | ||
1607 | |||
1608 | int __ubifs_node_check_hash(const struct ubifs_info *c, const void *buf, | ||
1609 | const u8 *expected); | ||
1610 | static inline int ubifs_node_check_hash(const struct ubifs_info *c, | ||
1611 | const void *buf, const u8 *expected) | ||
1612 | { | ||
1613 | if (ubifs_authenticated(c)) | ||
1614 | return __ubifs_node_check_hash(c, buf, expected); | ||
1615 | else | ||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | int ubifs_init_authentication(struct ubifs_info *c); | ||
1620 | void __ubifs_exit_authentication(struct ubifs_info *c); | ||
1621 | static inline void ubifs_exit_authentication(struct ubifs_info *c) | ||
1622 | { | ||
1623 | if (ubifs_authenticated(c)) | ||
1624 | __ubifs_exit_authentication(c); | ||
1625 | } | ||
1626 | |||
1627 | /** | ||
1628 | * ubifs_branch_hash - returns a pointer to the hash of a branch | ||
1629 | * @c: UBIFS file-system description object | ||
1630 | * @br: branch to get the hash from | ||
1631 | * | ||
1632 | * This returns a pointer to the hash of a branch. Since the key already is a | ||
1633 | * dynamically sized object we cannot use a struct member here. | ||
1634 | */ | ||
1635 | static inline u8 *ubifs_branch_hash(struct ubifs_info *c, | ||
1636 | struct ubifs_branch *br) | ||
1637 | { | ||
1638 | return (void *)br + sizeof(*br) + c->key_len; | ||
1639 | } | ||
1640 | |||
1641 | /** | ||
1642 | * ubifs_copy_hash - copy a hash | ||
1643 | * @c: UBIFS file-system description object | ||
1644 | * @from: source hash | ||
1645 | * @to: destination hash | ||
1646 | * | ||
1647 | * With authentication this copies a hash, otherwise does nothing. | ||
1648 | */ | ||
1649 | static inline void ubifs_copy_hash(const struct ubifs_info *c, const u8 *from, | ||
1650 | u8 *to) | ||
1651 | { | ||
1652 | if (ubifs_authenticated(c)) | ||
1653 | memcpy(to, from, c->hash_len); | ||
1654 | } | ||
1655 | |||
1656 | int __ubifs_node_insert_hmac(const struct ubifs_info *c, void *buf, | ||
1657 | int len, int ofs_hmac); | ||
1658 | static inline int ubifs_node_insert_hmac(const struct ubifs_info *c, void *buf, | ||
1659 | int len, int ofs_hmac) | ||
1660 | { | ||
1661 | if (ubifs_authenticated(c)) | ||
1662 | return __ubifs_node_insert_hmac(c, buf, len, ofs_hmac); | ||
1663 | else | ||
1664 | return 0; | ||
1665 | } | ||
1666 | |||
1667 | int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *buf, | ||
1668 | int len, int ofs_hmac); | ||
1669 | static inline int ubifs_node_verify_hmac(const struct ubifs_info *c, | ||
1670 | const void *buf, int len, int ofs_hmac) | ||
1671 | { | ||
1672 | if (ubifs_authenticated(c)) | ||
1673 | return __ubifs_node_verify_hmac(c, buf, len, ofs_hmac); | ||
1674 | else | ||
1675 | return 0; | ||
1676 | } | ||
1677 | |||
1678 | /** | ||
1679 | * ubifs_auth_node_sz - returns the size of an authentication node | ||
1680 | * @c: UBIFS file-system description object | ||
1681 | * | ||
1682 | * This function returns the size of an authentication node which can | ||
1683 | * be 0 for unauthenticated filesystems or the real size of an auth node | ||
1684 | * authentication is enabled. | ||
1685 | */ | ||
1686 | static inline int ubifs_auth_node_sz(const struct ubifs_info *c) | ||
1687 | { | ||
1688 | if (ubifs_authenticated(c)) | ||
1689 | return sizeof(struct ubifs_auth_node) + c->hmac_desc_len; | ||
1690 | else | ||
1691 | return 0; | ||
1692 | } | ||
1693 | |||
1694 | int ubifs_hmac_wkm(struct ubifs_info *c, u8 *hmac); | ||
1695 | |||
1696 | int __ubifs_shash_copy_state(const struct ubifs_info *c, struct shash_desc *src, | ||
1697 | struct shash_desc *target); | ||
1698 | static inline int ubifs_shash_copy_state(const struct ubifs_info *c, | ||
1699 | struct shash_desc *src, | ||
1700 | struct shash_desc *target) | ||
1701 | { | ||
1702 | if (ubifs_authenticated(c)) | ||
1703 | return __ubifs_shash_copy_state(c, src, target); | ||
1704 | else | ||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1474 | /* io.c */ | 1708 | /* io.c */ |
1475 | void ubifs_ro_mode(struct ubifs_info *c, int err); | 1709 | void ubifs_ro_mode(struct ubifs_info *c, int err); |
1476 | int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, | 1710 | int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, |
@@ -1490,9 +1724,15 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, | |||
1490 | int lnum, int offs); | 1724 | int lnum, int offs); |
1491 | int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum, | 1725 | int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum, |
1492 | int offs); | 1726 | int offs); |
1727 | int ubifs_write_node_hmac(struct ubifs_info *c, void *buf, int len, int lnum, | ||
1728 | int offs, int hmac_offs); | ||
1493 | int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, | 1729 | int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, |
1494 | int offs, int quiet, int must_chk_crc); | 1730 | int offs, int quiet, int must_chk_crc); |
1731 | void ubifs_init_node(struct ubifs_info *c, void *buf, int len, int pad); | ||
1732 | void ubifs_crc_node(struct ubifs_info *c, void *buf, int len); | ||
1495 | void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad); | 1733 | void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad); |
1734 | int ubifs_prepare_node_hmac(struct ubifs_info *c, void *node, int len, | ||
1735 | int hmac_offs, int pad); | ||
1496 | void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last); | 1736 | void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last); |
1497 | int ubifs_io_init(struct ubifs_info *c); | 1737 | int ubifs_io_init(struct ubifs_info *c); |
1498 | void ubifs_pad(const struct ubifs_info *c, void *buf, int pad); | 1738 | void ubifs_pad(const struct ubifs_info *c, void *buf, int pad); |
@@ -1592,11 +1832,12 @@ int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, | |||
1592 | int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, | 1832 | int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, |
1593 | void *node, int *lnum, int *offs); | 1833 | void *node, int *lnum, int *offs); |
1594 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | 1834 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, |
1595 | int offs, int len); | 1835 | int offs, int len, const u8 *hash); |
1596 | int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, | 1836 | int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, |
1597 | int old_lnum, int old_offs, int lnum, int offs, int len); | 1837 | int old_lnum, int old_offs, int lnum, int offs, int len); |
1598 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | 1838 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, |
1599 | int lnum, int offs, int len, const struct fscrypt_name *nm); | 1839 | int lnum, int offs, int len, const u8 *hash, |
1840 | const struct fscrypt_name *nm); | ||
1600 | int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); | 1841 | int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); |
1601 | int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, | 1842 | int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, |
1602 | const struct fscrypt_name *nm); | 1843 | const struct fscrypt_name *nm); |
@@ -1659,12 +1900,12 @@ int ubifs_gc_should_commit(struct ubifs_info *c); | |||
1659 | void ubifs_wait_for_commit(struct ubifs_info *c); | 1900 | void ubifs_wait_for_commit(struct ubifs_info *c); |
1660 | 1901 | ||
1661 | /* master.c */ | 1902 | /* master.c */ |
1903 | int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2); | ||
1662 | int ubifs_read_master(struct ubifs_info *c); | 1904 | int ubifs_read_master(struct ubifs_info *c); |
1663 | int ubifs_write_master(struct ubifs_info *c); | 1905 | int ubifs_write_master(struct ubifs_info *c); |
1664 | 1906 | ||
1665 | /* sb.c */ | 1907 | /* sb.c */ |
1666 | int ubifs_read_superblock(struct ubifs_info *c); | 1908 | int ubifs_read_superblock(struct ubifs_info *c); |
1667 | struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c); | ||
1668 | int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup); | 1909 | int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup); |
1669 | int ubifs_fixup_free_space(struct ubifs_info *c); | 1910 | int ubifs_fixup_free_space(struct ubifs_info *c); |
1670 | int ubifs_enable_encryption(struct ubifs_info *c); | 1911 | int ubifs_enable_encryption(struct ubifs_info *c); |
@@ -1693,7 +1934,7 @@ int ubifs_clear_orphans(struct ubifs_info *c); | |||
1693 | /* lpt.c */ | 1934 | /* lpt.c */ |
1694 | int ubifs_calc_lpt_geom(struct ubifs_info *c); | 1935 | int ubifs_calc_lpt_geom(struct ubifs_info *c); |
1695 | int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | 1936 | int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, |
1696 | int *lpt_lebs, int *big_lpt); | 1937 | int *lpt_lebs, int *big_lpt, u8 *hash); |
1697 | int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr); | 1938 | int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr); |
1698 | struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum); | 1939 | struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum); |
1699 | struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum); | 1940 | struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum); |
@@ -1712,6 +1953,7 @@ struct ubifs_pnode *ubifs_get_pnode(struct ubifs_info *c, | |||
1712 | struct ubifs_nnode *parent, int iip); | 1953 | struct ubifs_nnode *parent, int iip); |
1713 | struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c, | 1954 | struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c, |
1714 | struct ubifs_nnode *parent, int iip); | 1955 | struct ubifs_nnode *parent, int iip); |
1956 | struct ubifs_pnode *ubifs_pnode_lookup(struct ubifs_info *c, int i); | ||
1715 | int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip); | 1957 | int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip); |
1716 | void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); | 1958 | void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); |
1717 | void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); | 1959 | void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); |
@@ -1720,6 +1962,7 @@ struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght); | |||
1720 | /* Needed only in debugging code in lpt_commit.c */ | 1962 | /* Needed only in debugging code in lpt_commit.c */ |
1721 | int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, | 1963 | int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, |
1722 | struct ubifs_nnode *nnode); | 1964 | struct ubifs_nnode *nnode); |
1965 | int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash); | ||
1723 | 1966 | ||
1724 | /* lpt_commit.c */ | 1967 | /* lpt_commit.c */ |
1725 | int ubifs_lpt_start_commit(struct ubifs_info *c); | 1968 | int ubifs_lpt_start_commit(struct ubifs_info *c); |
@@ -1807,7 +2050,7 @@ int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf); | |||
1807 | int ubifs_rcvry_gc_commit(struct ubifs_info *c); | 2050 | int ubifs_rcvry_gc_commit(struct ubifs_info *c); |
1808 | int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, | 2051 | int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, |
1809 | int deletion, loff_t new_size); | 2052 | int deletion, loff_t new_size); |
1810 | int ubifs_recover_size(struct ubifs_info *c); | 2053 | int ubifs_recover_size(struct ubifs_info *c, bool in_place); |
1811 | void ubifs_destroy_size_tree(struct ubifs_info *c); | 2054 | void ubifs_destroy_size_tree(struct ubifs_info *c); |
1812 | 2055 | ||
1813 | /* ioctl.c */ | 2056 | /* ioctl.c */ |