Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'keys-fixes-20170419' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull keyrings fixes from David Howells:

(1) Disallow keyrings whose name begins with a '.' to be joined
[CVE-2016-9604].

(2) Change the name of the dead type to ".dead" to prevent user access
[CVE-2017-6951].

(3) Fix keyctl_set_reqkey_keyring() to not leak thread keyrings
[CVE-2017-7472]

* tag 'keys-fixes-20170419' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings
KEYS: Change the name of the dead type to ".dead" to prevent user access
KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings

+39 -27
+1 -1
security/keys/gc.c
··· 46 46 * immediately unlinked. 47 47 */ 48 48 struct key_type key_type_dead = { 49 - .name = "dead", 49 + .name = ".dead", 50 50 }; 51 51 52 52 /*
+11 -9
security/keys/keyctl.c
··· 273 273 * Create and join an anonymous session keyring or join a named session 274 274 * keyring, creating it if necessary. A named session keyring must have Search 275 275 * permission for it to be joined. Session keyrings without this permit will 276 - * be skipped over. 276 + * be skipped over. It is not permitted for userspace to create or join 277 + * keyrings whose name begin with a dot. 277 278 * 278 279 * If successful, the ID of the joined session keyring will be returned. 279 280 */ ··· 291 290 ret = PTR_ERR(name); 292 291 goto error; 293 292 } 293 + 294 + ret = -EPERM; 295 + if (name[0] == '.') 296 + goto error_name; 294 297 } 295 298 296 299 /* join the session */ 297 300 ret = join_session_keyring(name); 301 + error_name: 298 302 kfree(name); 299 - 300 303 error: 301 304 return ret; 302 305 } ··· 1258 1253 * Read or set the default keyring in which request_key() will cache keys and 1259 1254 * return the old setting. 1260 1255 * 1261 - * If a process keyring is specified then this will be created if it doesn't 1262 - * yet exist. The old setting will be returned if successful. 1256 + * If a thread or process keyring is specified then it will be created if it 1257 + * doesn't yet exist. The old setting will be returned if successful. 1263 1258 */ 1264 1259 long keyctl_set_reqkey_keyring(int reqkey_defl) 1265 1260 { ··· 1284 1279 1285 1280 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 1286 1281 ret = install_process_keyring_to_cred(new); 1287 - if (ret < 0) { 1288 - if (ret != -EEXIST) 1289 - goto error; 1290 - ret = 0; 1291 - } 1282 + if (ret < 0) 1283 + goto error; 1292 1284 goto set; 1293 1285 1294 1286 case KEY_REQKEY_DEFL_DEFAULT:
+27 -17
security/keys/process_keys.c
··· 128 128 } 129 129 130 130 /* 131 - * Install a fresh thread keyring directly to new credentials. This keyring is 132 - * allowed to overrun the quota. 131 + * Install a thread keyring to the given credentials struct if it didn't have 132 + * one already. This is allowed to overrun the quota. 133 + * 134 + * Return: 0 if a thread keyring is now present; -errno on failure. 133 135 */ 134 136 int install_thread_keyring_to_cred(struct cred *new) 135 137 { 136 138 struct key *keyring; 139 + 140 + if (new->thread_keyring) 141 + return 0; 137 142 138 143 keyring = keyring_alloc("_tid", new->uid, new->gid, new, 139 144 KEY_POS_ALL | KEY_USR_VIEW, ··· 152 147 } 153 148 154 149 /* 155 - * Install a fresh thread keyring, discarding the old one. 150 + * Install a thread keyring to the current task if it didn't have one already. 151 + * 152 + * Return: 0 if a thread keyring is now present; -errno on failure. 156 153 */ 157 154 static int install_thread_keyring(void) 158 155 { ··· 164 157 new = prepare_creds(); 165 158 if (!new) 166 159 return -ENOMEM; 167 - 168 - BUG_ON(new->thread_keyring); 169 160 170 161 ret = install_thread_keyring_to_cred(new); 171 162 if (ret < 0) { ··· 175 170 } 176 171 177 172 /* 178 - * Install a process keyring directly to a credentials struct. 173 + * Install a process keyring to the given credentials struct if it didn't have 174 + * one already. This is allowed to overrun the quota. 179 175 * 180 - * Returns -EEXIST if there was already a process keyring, 0 if one installed, 181 - * and other value on any other error 176 + * Return: 0 if a process keyring is now present; -errno on failure. 182 177 */ 183 178 int install_process_keyring_to_cred(struct cred *new) 184 179 { 185 180 struct key *keyring; 186 181 187 182 if (new->process_keyring) 188 - return -EEXIST; 183 + return 0; 189 184 190 185 keyring = keyring_alloc("_pid", new->uid, new->gid, new, 191 186 KEY_POS_ALL | KEY_USR_VIEW, ··· 199 194 } 200 195 201 196 /* 202 - * Make sure a process keyring is installed for the current process. The 203 - * existing process keyring is not replaced. 197 + * Install a process keyring to the current task if it didn't have one already. 204 198 * 205 - * Returns 0 if there is a process keyring by the end of this function, some 206 - * error otherwise. 199 + * Return: 0 if a process keyring is now present; -errno on failure. 207 200 */ 208 201 static int install_process_keyring(void) 209 202 { ··· 215 212 ret = install_process_keyring_to_cred(new); 216 213 if (ret < 0) { 217 214 abort_creds(new); 218 - return ret != -EEXIST ? ret : 0; 215 + return ret; 219 216 } 220 217 221 218 return commit_creds(new); 222 219 } 223 220 224 221 /* 225 - * Install a session keyring directly to a credentials struct. 222 + * Install the given keyring as the session keyring of the given credentials 223 + * struct, replacing the existing one if any. If the given keyring is NULL, 224 + * then install a new anonymous session keyring. 225 + * 226 + * Return: 0 on success; -errno on failure. 226 227 */ 227 228 int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) 228 229 { ··· 261 254 } 262 255 263 256 /* 264 - * Install a session keyring, discarding the old one. If a keyring is not 265 - * supplied, an empty one is invented. 257 + * Install the given keyring as the session keyring of the current task, 258 + * replacing the existing one if any. If the given keyring is NULL, then 259 + * install a new anonymous session keyring. 260 + * 261 + * Return: 0 on success; -errno on failure. 266 262 */ 267 263 static int install_session_keyring(struct key *keyring) 268 264 {