1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include <linux/fs.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 
8 #include "missing_fs.h"
9 
10 /* The chattr() flags to apply when creating a new file *before* writing to it. In particular, flags such as
11  * FS_NOCOW_FL don't work if applied a-posteriori. All other flags are fine (or even necessary, think
12  * FS_IMMUTABLE_FL!) to apply after writing to the files. */
13 #define CHATTR_EARLY_FL                         \
14         (FS_NOATIME_FL |                        \
15          FS_COMPR_FL   |                        \
16          FS_NOCOW_FL   |                        \
17          FS_NOCOMP_FL  |                        \
18          FS_PROJINHERIT_FL)
19 
20 #define CHATTR_ALL_FL                           \
21         (FS_NOATIME_FL      |                   \
22          FS_SYNC_FL         |                   \
23          FS_DIRSYNC_FL      |                   \
24          FS_APPEND_FL       |                   \
25          FS_COMPR_FL        |                   \
26          FS_NODUMP_FL       |                   \
27          FS_EXTENT_FL       |                   \
28          FS_IMMUTABLE_FL    |                   \
29          FS_JOURNAL_DATA_FL |                   \
30          FS_SECRM_FL        |                   \
31          FS_UNRM_FL         |                   \
32          FS_NOTAIL_FL       |                   \
33          FS_TOPDIR_FL       |                   \
34          FS_NOCOW_FL        |                   \
35          FS_PROJINHERIT_FL)
36 
37 typedef enum ChattrApplyFlags {
38         CHATTR_FALLBACK_BITWISE       = 1 << 0,
39         CHATTR_WARN_UNSUPPORTED_FLAGS = 1 << 1,
40 } ChattrApplyFlags;
41 
42 int chattr_full(const char *path, int fd, unsigned value, unsigned mask, unsigned *ret_previous, unsigned *ret_final, ChattrApplyFlags flags);
43 
chattr_fd(int fd,unsigned value,unsigned mask,unsigned * previous)44 static inline int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous) {
45         return chattr_full(NULL, fd, value, mask, previous, NULL, 0);
46 }
chattr_path(const char * path,unsigned value,unsigned mask,unsigned * previous)47 static inline int chattr_path(const char *path, unsigned value, unsigned mask, unsigned *previous) {
48         return chattr_full(path, -1, value, mask, previous, NULL, 0);
49 }
50 
51 int read_attr_fd(int fd, unsigned *ret);
52 int read_attr_path(const char *p, unsigned *ret);
53 
54 /* Combination of chattr flags, that should be appropriate for secrets stored on disk: Secure Remove +
55  * Exclusion from Dumping + Synchronous Writing (i.e. not caching in memory) + In-Place Updating (i.e. not
56  * spurious copies). */
57 #define CHATTR_SECRET_FLAGS (FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL)
58 
chattr_secret(int fd,ChattrApplyFlags flags)59 static inline int chattr_secret(int fd, ChattrApplyFlags flags) {
60         return chattr_full(NULL, fd, CHATTR_SECRET_FLAGS, CHATTR_SECRET_FLAGS, NULL, NULL, flags|CHATTR_FALLBACK_BITWISE);
61 }
62