|
24 | 24 | * /proc/sys/fs/verity/require_signatures |
25 | 25 | * If 1, all verity files must have a valid builtin signature. |
26 | 26 | */ |
27 | | -static int fsverity_require_signatures; |
| 27 | +int fsverity_require_signatures; |
28 | 28 |
|
29 | 29 | /* |
30 | 30 | * Keyring that contains the trusted X.509 certificates. |
@@ -62,6 +62,22 @@ int fsverity_verify_signature(const struct fsverity_info *vi, |
62 | 62 | return 0; |
63 | 63 | } |
64 | 64 |
|
| 65 | + if (fsverity_keyring->keys.nr_leaves_on_tree == 0) { |
| 66 | + /* |
| 67 | + * The ".fs-verity" keyring is empty, due to builtin signatures |
| 68 | + * being supported by the kernel but not actually being used. |
| 69 | + * In this case, verify_pkcs7_signature() would always return an |
| 70 | + * error, usually ENOKEY. It could also be EBADMSG if the |
| 71 | + * PKCS#7 is malformed, but that isn't very important to |
| 72 | + * distinguish. So, just skip to ENOKEY to avoid the attack |
| 73 | + * surface of the PKCS#7 parser, which would otherwise be |
| 74 | + * reachable by any task able to execute FS_IOC_ENABLE_VERITY. |
| 75 | + */ |
| 76 | + fsverity_err(inode, |
| 77 | + "fs-verity keyring is empty, rejecting signed file!"); |
| 78 | + return -ENOKEY; |
| 79 | + } |
| 80 | + |
65 | 81 | d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL); |
66 | 82 | if (!d) |
67 | 83 | return -ENOMEM; |
@@ -93,59 +109,14 @@ int fsverity_verify_signature(const struct fsverity_info *vi, |
93 | 109 | return 0; |
94 | 110 | } |
95 | 111 |
|
96 | | -#ifdef CONFIG_SYSCTL |
97 | | -static struct ctl_table_header *fsverity_sysctl_header; |
98 | | - |
99 | | -static struct ctl_table fsverity_sysctl_table[] = { |
100 | | - { |
101 | | - .procname = "require_signatures", |
102 | | - .data = &fsverity_require_signatures, |
103 | | - .maxlen = sizeof(int), |
104 | | - .mode = 0644, |
105 | | - .proc_handler = proc_dointvec_minmax, |
106 | | - .extra1 = SYSCTL_ZERO, |
107 | | - .extra2 = SYSCTL_ONE, |
108 | | - }, |
109 | | - { } |
110 | | -}; |
111 | | - |
112 | | -static int __init fsverity_sysctl_init(void) |
113 | | -{ |
114 | | - fsverity_sysctl_header = register_sysctl("fs/verity", fsverity_sysctl_table); |
115 | | - if (!fsverity_sysctl_header) { |
116 | | - pr_err("sysctl registration failed!\n"); |
117 | | - return -ENOMEM; |
118 | | - } |
119 | | - return 0; |
120 | | -} |
121 | | -#else /* !CONFIG_SYSCTL */ |
122 | | -static inline int __init fsverity_sysctl_init(void) |
| 112 | +void __init fsverity_init_signature(void) |
123 | 113 | { |
124 | | - return 0; |
125 | | -} |
126 | | -#endif /* !CONFIG_SYSCTL */ |
127 | | - |
128 | | -int __init fsverity_init_signature(void) |
129 | | -{ |
130 | | - struct key *ring; |
131 | | - int err; |
132 | | - |
133 | | - ring = keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0), |
134 | | - current_cred(), KEY_POS_SEARCH | |
| 114 | + fsverity_keyring = |
| 115 | + keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0), |
| 116 | + current_cred(), KEY_POS_SEARCH | |
135 | 117 | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | |
136 | 118 | KEY_USR_SEARCH | KEY_USR_SETATTR, |
137 | | - KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); |
138 | | - if (IS_ERR(ring)) |
139 | | - return PTR_ERR(ring); |
140 | | - |
141 | | - err = fsverity_sysctl_init(); |
142 | | - if (err) |
143 | | - goto err_put_ring; |
144 | | - |
145 | | - fsverity_keyring = ring; |
146 | | - return 0; |
147 | | - |
148 | | -err_put_ring: |
149 | | - key_put(ring); |
150 | | - return err; |
| 119 | + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); |
| 120 | + if (IS_ERR(fsverity_keyring)) |
| 121 | + panic("failed to allocate \".fs-verity\" keyring"); |
151 | 122 | } |
0 commit comments