2 * Copyright (c) 2015 Google, Inc.
5 #define TAG "ext4_utils"
12 #include <sys/xattr.h>
13 #include <sys/syscall.h>
16 #include <cutils/klog.h>
18 #include "ext4_crypt.h"
20 /* keyring keyctl commands */
21 #define KEYCTL_SETPERM 5 /* set permissions for a key in a keyring */
22 #define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
23 #define KEYCTL_SEARCH 10 /* search for a key in a keyring */
25 #define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy"
26 #define EXT4_KEYREF_DELIMITER ((char)'.')
28 /* Validate that all path items are available and accessible. */
29 static int is_path_valid(const char *path
)
31 if (access(path
, W_OK
)) {
32 KLOG_ERROR(TAG
, "Can't access %s: %s\n",strerror(errno
), path
);
39 /* Checks whether the policy provided is valid */
40 static int is_keyref_valid(const char *keyref
)
43 size_t key_location_len
= 0;
45 /* Key ref must have a key and location delimiter character. */
46 period
= strchr(keyref
, EXT4_KEYREF_DELIMITER
);
51 /* period must be >= keyref. */
52 key_location_len
= period
- keyref
;
54 if (strncmp(keyref
, "@t", key_location_len
) == 0 ||
55 strncmp(keyref
, "@p", key_location_len
) == 0 ||
56 strncmp(keyref
, "@s", key_location_len
) == 0 ||
57 strncmp(keyref
, "@u", key_location_len
) == 0 ||
58 strncmp(keyref
, "@g", key_location_len
) == 0 ||
59 strncmp(keyref
, "@us", key_location_len
) == 0)
65 static int is_dir_empty(const char *dirname
)
71 dir
= opendir(dirname
);
72 while ((d
= readdir(dir
)) != NULL
) {
73 if (strcmp(d
->d_name
, "lost+found") == 0) {
74 // Skip lost+found directory
83 int do_policy_set(const char *directory
, const char *policy
)
88 if (!is_keyref_valid(policy
)) {
89 KLOG_ERROR(TAG
, "Policy has invalid format.\n");
93 if (!is_path_valid(directory
)) {
98 if (!S_ISDIR(st
.st_mode
)) {
99 KLOG_ERROR(TAG
, "Can only set policy on a directory (%s)\n", directory
);
103 if (!is_dir_empty(directory
)) {
104 KLOG_ERROR(TAG
, "Can only set policy on an empty directory (%s)\n", directory
);
108 ret
= lsetxattr(directory
, XATTR_NAME_ENCRYPTION_POLICY
, policy
,
112 KLOG_ERROR(TAG
, "Failed to set encryption policy for %s: %s\n",
113 directory
, strerror(errno
));
117 KLOG_INFO(TAG
, "Encryption policy for %s is set to %s\n", directory
, policy
);
121 static long keyctl(int cmd
, ...)
124 unsigned long arg2
, arg3
, arg4
, arg5
;
127 arg2
= va_arg(va
, unsigned long);
128 arg3
= va_arg(va
, unsigned long);
129 arg4
= va_arg(va
, unsigned long);
130 arg5
= va_arg(va
, unsigned long);
132 return syscall(__NR_keyctl
, cmd
, arg2
, arg3
, arg4
, arg5
);
135 key_serial_t
add_key(const char *type
,
136 const char *description
,
141 return syscall(__NR_add_key
, type
, description
, payload
, plen
, ringid
);
144 long keyctl_setperm(key_serial_t id
, int permissions
)
146 return keyctl(KEYCTL_SETPERM
, id
, permissions
);