keyctl.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  1. /* keyctl.c: userspace keyctl operations
  2. *
  3. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/sched.h>
  14. #include <linux/slab.h>
  15. #include <linux/syscalls.h>
  16. #include <linux/keyctl.h>
  17. #include <linux/fs.h>
  18. #include <linux/err.h>
  19. #include <asm/uaccess.h>
  20. #include "internal.h"
  21. /*****************************************************************************/
  22. /*
  23. * extract the description of a new key from userspace and either add it as a
  24. * new key to the specified keyring or update a matching key in that keyring
  25. * - the keyring must be writable
  26. * - returns the new key's serial number
  27. * - implements add_key()
  28. */
  29. asmlinkage long sys_add_key(const char __user *_type,
  30. const char __user *_description,
  31. const void __user *_payload,
  32. size_t plen,
  33. key_serial_t ringid)
  34. {
  35. struct key *keyring, *key;
  36. char type[32], *description;
  37. void *payload;
  38. long dlen, ret;
  39. ret = -EINVAL;
  40. if (plen > 32767)
  41. goto error;
  42. /* draw all the data into kernel space */
  43. ret = strncpy_from_user(type, _type, sizeof(type) - 1);
  44. if (ret < 0)
  45. goto error;
  46. type[31] = '\0';
  47. ret = -EFAULT;
  48. dlen = strnlen_user(_description, PAGE_SIZE - 1);
  49. if (dlen <= 0)
  50. goto error;
  51. ret = -EINVAL;
  52. if (dlen > PAGE_SIZE - 1)
  53. goto error;
  54. ret = -ENOMEM;
  55. description = kmalloc(dlen + 1, GFP_KERNEL);
  56. if (!description)
  57. goto error;
  58. ret = -EFAULT;
  59. if (copy_from_user(description, _description, dlen + 1) != 0)
  60. goto error2;
  61. /* pull the payload in if one was supplied */
  62. payload = NULL;
  63. if (_payload) {
  64. ret = -ENOMEM;
  65. payload = kmalloc(plen, GFP_KERNEL);
  66. if (!payload)
  67. goto error2;
  68. ret = -EFAULT;
  69. if (copy_from_user(payload, _payload, plen) != 0)
  70. goto error3;
  71. }
  72. /* find the target keyring (which must be writable) */
  73. keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
  74. if (IS_ERR(keyring)) {
  75. ret = PTR_ERR(keyring);
  76. goto error3;
  77. }
  78. /* create or update the requested key and add it to the target
  79. * keyring */
  80. key = key_create_or_update(keyring, type, description,
  81. payload, plen, 0);
  82. if (!IS_ERR(key)) {
  83. ret = key->serial;
  84. key_put(key);
  85. }
  86. else {
  87. ret = PTR_ERR(key);
  88. }
  89. key_put(keyring);
  90. error3:
  91. kfree(payload);
  92. error2:
  93. kfree(description);
  94. error:
  95. return ret;
  96. } /* end sys_add_key() */
  97. /*****************************************************************************/
  98. /*
  99. * search the process keyrings for a matching key
  100. * - nested keyrings may also be searched if they have Search permission
  101. * - if a key is found, it will be attached to the destination keyring if
  102. * there's one specified
  103. * - /sbin/request-key will be invoked if _callout_info is non-NULL
  104. * - the _callout_info string will be passed to /sbin/request-key
  105. * - if the _callout_info string is empty, it will be rendered as "-"
  106. * - implements request_key()
  107. */
  108. asmlinkage long sys_request_key(const char __user *_type,
  109. const char __user *_description,
  110. const char __user *_callout_info,
  111. key_serial_t destringid)
  112. {
  113. struct key_type *ktype;
  114. struct key *key, *dest;
  115. char type[32], *description, *callout_info;
  116. long dlen, ret;
  117. /* pull the type into kernel space */
  118. ret = strncpy_from_user(type, _type, sizeof(type) - 1);
  119. if (ret < 0)
  120. goto error;
  121. type[31] = '\0';
  122. /* pull the description into kernel space */
  123. ret = -EFAULT;
  124. dlen = strnlen_user(_description, PAGE_SIZE - 1);
  125. if (dlen <= 0)
  126. goto error;
  127. ret = -EINVAL;
  128. if (dlen > PAGE_SIZE - 1)
  129. goto error;
  130. ret = -ENOMEM;
  131. description = kmalloc(dlen + 1, GFP_KERNEL);
  132. if (!description)
  133. goto error;
  134. ret = -EFAULT;
  135. if (copy_from_user(description, _description, dlen + 1) != 0)
  136. goto error2;
  137. /* pull the callout info into kernel space */
  138. callout_info = NULL;
  139. if (_callout_info) {
  140. ret = -EFAULT;
  141. dlen = strnlen_user(_callout_info, PAGE_SIZE - 1);
  142. if (dlen <= 0)
  143. goto error2;
  144. ret = -EINVAL;
  145. if (dlen > PAGE_SIZE - 1)
  146. goto error2;
  147. ret = -ENOMEM;
  148. callout_info = kmalloc(dlen + 1, GFP_KERNEL);
  149. if (!callout_info)
  150. goto error2;
  151. ret = -EFAULT;
  152. if (copy_from_user(callout_info, _callout_info, dlen + 1) != 0)
  153. goto error3;
  154. }
  155. /* get the destination keyring if specified */
  156. dest = NULL;
  157. if (destringid) {
  158. dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
  159. if (IS_ERR(dest)) {
  160. ret = PTR_ERR(dest);
  161. goto error3;
  162. }
  163. }
  164. /* find the key type */
  165. ktype = key_type_lookup(type);
  166. if (IS_ERR(ktype)) {
  167. ret = PTR_ERR(ktype);
  168. goto error4;
  169. }
  170. /* do the search */
  171. key = request_key(ktype, description, callout_info);
  172. if (IS_ERR(key)) {
  173. ret = PTR_ERR(key);
  174. goto error5;
  175. }
  176. /* link the resulting key to the destination keyring */
  177. if (dest) {
  178. ret = key_link(dest, key);
  179. if (ret < 0)
  180. goto error6;
  181. }
  182. ret = key->serial;
  183. error6:
  184. key_put(key);
  185. error5:
  186. key_type_put(ktype);
  187. error4:
  188. key_put(dest);
  189. error3:
  190. kfree(callout_info);
  191. error2:
  192. kfree(description);
  193. error:
  194. return ret;
  195. } /* end sys_request_key() */
  196. /*****************************************************************************/
  197. /*
  198. * get the ID of the specified process keyring
  199. * - the keyring must have search permission to be found
  200. * - implements keyctl(KEYCTL_GET_KEYRING_ID)
  201. */
  202. long keyctl_get_keyring_ID(key_serial_t id, int create)
  203. {
  204. struct key *key;
  205. long ret;
  206. key = lookup_user_key(id, create, 0, KEY_SEARCH);
  207. if (IS_ERR(key)) {
  208. ret = PTR_ERR(key);
  209. goto error;
  210. }
  211. ret = key->serial;
  212. key_put(key);
  213. error:
  214. return ret;
  215. } /* end keyctl_get_keyring_ID() */
  216. /*****************************************************************************/
  217. /*
  218. * join the session keyring
  219. * - implements keyctl(KEYCTL_JOIN_SESSION_KEYRING)
  220. */
  221. long keyctl_join_session_keyring(const char __user *_name)
  222. {
  223. char *name;
  224. long nlen, ret;
  225. /* fetch the name from userspace */
  226. name = NULL;
  227. if (_name) {
  228. ret = -EFAULT;
  229. nlen = strnlen_user(_name, PAGE_SIZE - 1);
  230. if (nlen <= 0)
  231. goto error;
  232. ret = -EINVAL;
  233. if (nlen > PAGE_SIZE - 1)
  234. goto error;
  235. ret = -ENOMEM;
  236. name = kmalloc(nlen + 1, GFP_KERNEL);
  237. if (!name)
  238. goto error;
  239. ret = -EFAULT;
  240. if (copy_from_user(name, _name, nlen + 1) != 0)
  241. goto error2;
  242. }
  243. /* join the session */
  244. ret = join_session_keyring(name);
  245. error2:
  246. kfree(name);
  247. error:
  248. return ret;
  249. } /* end keyctl_join_session_keyring() */
  250. /*****************************************************************************/
  251. /*
  252. * update a key's data payload
  253. * - the key must be writable
  254. * - implements keyctl(KEYCTL_UPDATE)
  255. */
  256. long keyctl_update_key(key_serial_t id,
  257. const void __user *_payload,
  258. size_t plen)
  259. {
  260. struct key *key;
  261. void *payload;
  262. long ret;
  263. ret = -EINVAL;
  264. if (plen > PAGE_SIZE)
  265. goto error;
  266. /* pull the payload in if one was supplied */
  267. payload = NULL;
  268. if (_payload) {
  269. ret = -ENOMEM;
  270. payload = kmalloc(plen, GFP_KERNEL);
  271. if (!payload)
  272. goto error;
  273. ret = -EFAULT;
  274. if (copy_from_user(payload, _payload, plen) != 0)
  275. goto error2;
  276. }
  277. /* find the target key (which must be writable) */
  278. key = lookup_user_key(id, 0, 0, KEY_WRITE);
  279. if (IS_ERR(key)) {
  280. ret = PTR_ERR(key);
  281. goto error2;
  282. }
  283. /* update the key */
  284. ret = key_update(key, payload, plen);
  285. key_put(key);
  286. error2:
  287. kfree(payload);
  288. error:
  289. return ret;
  290. } /* end keyctl_update_key() */
  291. /*****************************************************************************/
  292. /*
  293. * revoke a key
  294. * - the key must be writable
  295. * - implements keyctl(KEYCTL_REVOKE)
  296. */
  297. long keyctl_revoke_key(key_serial_t id)
  298. {
  299. struct key *key;
  300. long ret;
  301. key = lookup_user_key(id, 0, 0, KEY_WRITE);
  302. if (IS_ERR(key)) {
  303. ret = PTR_ERR(key);
  304. goto error;
  305. }
  306. key_revoke(key);
  307. ret = 0;
  308. key_put(key);
  309. error:
  310. return 0;
  311. } /* end keyctl_revoke_key() */
  312. /*****************************************************************************/
  313. /*
  314. * clear the specified process keyring
  315. * - the keyring must be writable
  316. * - implements keyctl(KEYCTL_CLEAR)
  317. */
  318. long keyctl_keyring_clear(key_serial_t ringid)
  319. {
  320. struct key *keyring;
  321. long ret;
  322. keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
  323. if (IS_ERR(keyring)) {
  324. ret = PTR_ERR(keyring);
  325. goto error;
  326. }
  327. ret = keyring_clear(keyring);
  328. key_put(keyring);
  329. error:
  330. return ret;
  331. } /* end keyctl_keyring_clear() */
  332. /*****************************************************************************/
  333. /*
  334. * link a key into a keyring
  335. * - the keyring must be writable
  336. * - the key must be linkable
  337. * - implements keyctl(KEYCTL_LINK)
  338. */
  339. long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
  340. {
  341. struct key *keyring, *key;
  342. long ret;
  343. keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
  344. if (IS_ERR(keyring)) {
  345. ret = PTR_ERR(keyring);
  346. goto error;
  347. }
  348. key = lookup_user_key(id, 1, 0, KEY_LINK);
  349. if (IS_ERR(key)) {
  350. ret = PTR_ERR(key);
  351. goto error2;
  352. }
  353. ret = key_link(keyring, key);
  354. key_put(key);
  355. error2:
  356. key_put(keyring);
  357. error:
  358. return ret;
  359. } /* end keyctl_keyring_link() */
  360. /*****************************************************************************/
  361. /*
  362. * unlink the first attachment of a key from a keyring
  363. * - the keyring must be writable
  364. * - we don't need any permissions on the key
  365. * - implements keyctl(KEYCTL_UNLINK)
  366. */
  367. long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
  368. {
  369. struct key *keyring, *key;
  370. long ret;
  371. keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE);
  372. if (IS_ERR(keyring)) {
  373. ret = PTR_ERR(keyring);
  374. goto error;
  375. }
  376. key = lookup_user_key(id, 0, 0, 0);
  377. if (IS_ERR(key)) {
  378. ret = PTR_ERR(key);
  379. goto error2;
  380. }
  381. ret = key_unlink(keyring, key);
  382. key_put(key);
  383. error2:
  384. key_put(keyring);
  385. error:
  386. return ret;
  387. } /* end keyctl_keyring_unlink() */
  388. /*****************************************************************************/
  389. /*
  390. * describe a user key
  391. * - the key must have view permission
  392. * - if there's a buffer, we place up to buflen bytes of data into it
  393. * - unless there's an error, we return the amount of description available,
  394. * irrespective of how much we may have copied
  395. * - the description is formatted thus:
  396. * type;uid;gid;perm;description<NUL>
  397. * - implements keyctl(KEYCTL_DESCRIBE)
  398. */
  399. long keyctl_describe_key(key_serial_t keyid,
  400. char __user *buffer,
  401. size_t buflen)
  402. {
  403. struct key *key;
  404. char *tmpbuf;
  405. long ret;
  406. key = lookup_user_key(keyid, 0, 1, KEY_VIEW);
  407. if (IS_ERR(key)) {
  408. ret = PTR_ERR(key);
  409. goto error;
  410. }
  411. /* calculate how much description we're going to return */
  412. ret = -ENOMEM;
  413. tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
  414. if (!tmpbuf)
  415. goto error2;
  416. ret = snprintf(tmpbuf, PAGE_SIZE - 1,
  417. "%s;%d;%d;%06x;%s",
  418. key->type->name,
  419. key->uid,
  420. key->gid,
  421. key->perm,
  422. key->description ? key->description :""
  423. );
  424. /* include a NUL char at the end of the data */
  425. if (ret > PAGE_SIZE - 1)
  426. ret = PAGE_SIZE - 1;
  427. tmpbuf[ret] = 0;
  428. ret++;
  429. /* consider returning the data */
  430. if (buffer && buflen > 0) {
  431. if (buflen > ret)
  432. buflen = ret;
  433. if (copy_to_user(buffer, tmpbuf, buflen) != 0)
  434. ret = -EFAULT;
  435. }
  436. kfree(tmpbuf);
  437. error2:
  438. key_put(key);
  439. error:
  440. return ret;
  441. } /* end keyctl_describe_key() */
  442. /*****************************************************************************/
  443. /*
  444. * search the specified keyring for a matching key
  445. * - the start keyring must be searchable
  446. * - nested keyrings may also be searched if they are searchable
  447. * - only keys with search permission may be found
  448. * - if a key is found, it will be attached to the destination keyring if
  449. * there's one specified
  450. * - implements keyctl(KEYCTL_SEARCH)
  451. */
  452. long keyctl_keyring_search(key_serial_t ringid,
  453. const char __user *_type,
  454. const char __user *_description,
  455. key_serial_t destringid)
  456. {
  457. struct key_type *ktype;
  458. struct key *keyring, *key, *dest;
  459. char type[32], *description;
  460. long dlen, ret;
  461. /* pull the type and description into kernel space */
  462. ret = strncpy_from_user(type, _type, sizeof(type) - 1);
  463. if (ret < 0)
  464. goto error;
  465. type[31] = '\0';
  466. ret = -EFAULT;
  467. dlen = strnlen_user(_description, PAGE_SIZE - 1);
  468. if (dlen <= 0)
  469. goto error;
  470. ret = -EINVAL;
  471. if (dlen > PAGE_SIZE - 1)
  472. goto error;
  473. ret = -ENOMEM;
  474. description = kmalloc(dlen + 1, GFP_KERNEL);
  475. if (!description)
  476. goto error;
  477. ret = -EFAULT;
  478. if (copy_from_user(description, _description, dlen + 1) != 0)
  479. goto error2;
  480. /* get the keyring at which to begin the search */
  481. keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH);
  482. if (IS_ERR(keyring)) {
  483. ret = PTR_ERR(keyring);
  484. goto error2;
  485. }
  486. /* get the destination keyring if specified */
  487. dest = NULL;
  488. if (destringid) {
  489. dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
  490. if (IS_ERR(dest)) {
  491. ret = PTR_ERR(dest);
  492. goto error3;
  493. }
  494. }
  495. /* find the key type */
  496. ktype = key_type_lookup(type);
  497. if (IS_ERR(ktype)) {
  498. ret = PTR_ERR(ktype);
  499. goto error4;
  500. }
  501. /* do the search */
  502. key = keyring_search(keyring, ktype, description);
  503. if (IS_ERR(key)) {
  504. ret = PTR_ERR(key);
  505. /* treat lack or presence of a negative key the same */
  506. if (ret == -EAGAIN)
  507. ret = -ENOKEY;
  508. goto error5;
  509. }
  510. /* link the resulting key to the destination keyring if we can */
  511. if (dest) {
  512. ret = -EACCES;
  513. if (!key_permission(key, KEY_LINK))
  514. goto error6;
  515. ret = key_link(dest, key);
  516. if (ret < 0)
  517. goto error6;
  518. }
  519. ret = key->serial;
  520. error6:
  521. key_put(key);
  522. error5:
  523. key_type_put(ktype);
  524. error4:
  525. key_put(dest);
  526. error3:
  527. key_put(keyring);
  528. error2:
  529. kfree(description);
  530. error:
  531. return ret;
  532. } /* end keyctl_keyring_search() */
  533. /*****************************************************************************/
  534. /*
  535. * see if the key we're looking at is the target key
  536. */
  537. static int keyctl_read_key_same(const struct key *key, const void *target)
  538. {
  539. return key == target;
  540. } /* end keyctl_read_key_same() */
  541. /*****************************************************************************/
  542. /*
  543. * read a user key's payload
  544. * - the keyring must be readable or the key must be searchable from the
  545. * process's keyrings
  546. * - if there's a buffer, we place up to buflen bytes of data into it
  547. * - unless there's an error, we return the amount of data in the key,
  548. * irrespective of how much we may have copied
  549. * - implements keyctl(KEYCTL_READ)
  550. */
  551. long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
  552. {
  553. struct key *key, *skey;
  554. long ret;
  555. /* find the key first */
  556. key = lookup_user_key(keyid, 0, 0, 0);
  557. if (!IS_ERR(key)) {
  558. /* see if we can read it directly */
  559. if (key_permission(key, KEY_READ))
  560. goto can_read_key;
  561. /* can't; see if it's searchable from this process's
  562. * keyrings */
  563. ret = -ENOKEY;
  564. if (key_permission(key, KEY_SEARCH)) {
  565. /* okay - we do have search permission on the key
  566. * itself, but do we have the key? */
  567. skey = search_process_keyrings_aux(key->type, key,
  568. keyctl_read_key_same);
  569. if (!IS_ERR(skey))
  570. goto can_read_key2;
  571. }
  572. goto error2;
  573. }
  574. ret = -ENOKEY;
  575. goto error;
  576. /* the key is probably readable - now try to read it */
  577. can_read_key2:
  578. key_put(skey);
  579. can_read_key:
  580. ret = key_validate(key);
  581. if (ret == 0) {
  582. ret = -EOPNOTSUPP;
  583. if (key->type->read) {
  584. /* read the data with the semaphore held (since we
  585. * might sleep) */
  586. down_read(&key->sem);
  587. ret = key->type->read(key, buffer, buflen);
  588. up_read(&key->sem);
  589. }
  590. }
  591. error2:
  592. key_put(key);
  593. error:
  594. return ret;
  595. } /* end keyctl_read_key() */
  596. /*****************************************************************************/
  597. /*
  598. * change the ownership of a key
  599. * - the keyring owned by the changer
  600. * - if the uid or gid is -1, then that parameter is not changed
  601. * - implements keyctl(KEYCTL_CHOWN)
  602. */
  603. long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
  604. {
  605. struct key *key;
  606. long ret;
  607. ret = 0;
  608. if (uid == (uid_t) -1 && gid == (gid_t) -1)
  609. goto error;
  610. key = lookup_user_key(id, 1, 1, 0);
  611. if (IS_ERR(key)) {
  612. ret = PTR_ERR(key);
  613. goto error;
  614. }
  615. /* make the changes with the locks held to prevent chown/chown races */
  616. ret = -EACCES;
  617. down_write(&key->sem);
  618. write_lock(&key->lock);
  619. if (!capable(CAP_SYS_ADMIN)) {
  620. /* only the sysadmin can chown a key to some other UID */
  621. if (uid != (uid_t) -1 && key->uid != uid)
  622. goto no_access;
  623. /* only the sysadmin can set the key's GID to a group other
  624. * than one of those that the current process subscribes to */
  625. if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid))
  626. goto no_access;
  627. }
  628. /* change the UID (have to update the quotas) */
  629. if (uid != (uid_t) -1 && uid != key->uid) {
  630. /* don't support UID changing yet */
  631. ret = -EOPNOTSUPP;
  632. goto no_access;
  633. }
  634. /* change the GID */
  635. if (gid != (gid_t) -1)
  636. key->gid = gid;
  637. ret = 0;
  638. no_access:
  639. write_unlock(&key->lock);
  640. up_write(&key->sem);
  641. key_put(key);
  642. error:
  643. return ret;
  644. } /* end keyctl_chown_key() */
  645. /*****************************************************************************/
  646. /*
  647. * change the permission mask on a key
  648. * - the keyring owned by the changer
  649. * - implements keyctl(KEYCTL_SETPERM)
  650. */
  651. long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
  652. {
  653. struct key *key;
  654. long ret;
  655. ret = -EINVAL;
  656. if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
  657. goto error;
  658. key = lookup_user_key(id, 1, 1, 0);
  659. if (IS_ERR(key)) {
  660. ret = PTR_ERR(key);
  661. goto error;
  662. }
  663. /* make the changes with the locks held to prevent chown/chmod
  664. * races */
  665. ret = -EACCES;
  666. down_write(&key->sem);
  667. write_lock(&key->lock);
  668. /* if we're not the sysadmin, we can only chmod a key that we
  669. * own */
  670. if (!capable(CAP_SYS_ADMIN) && key->uid != current->fsuid)
  671. goto no_access;
  672. /* changing the permissions mask */
  673. key->perm = perm;
  674. ret = 0;
  675. no_access:
  676. write_unlock(&key->lock);
  677. up_write(&key->sem);
  678. key_put(key);
  679. error:
  680. return ret;
  681. } /* end keyctl_setperm_key() */
  682. /*****************************************************************************/
  683. /*
  684. * instantiate the key with the specified payload, and, if one is given, link
  685. * the key into the keyring
  686. */
  687. long keyctl_instantiate_key(key_serial_t id,
  688. const void __user *_payload,
  689. size_t plen,
  690. key_serial_t ringid)
  691. {
  692. struct key *key, *keyring;
  693. void *payload;
  694. long ret;
  695. ret = -EINVAL;
  696. if (plen > 32767)
  697. goto error;
  698. /* pull the payload in if one was supplied */
  699. payload = NULL;
  700. if (_payload) {
  701. ret = -ENOMEM;
  702. payload = kmalloc(plen, GFP_KERNEL);
  703. if (!payload)
  704. goto error;
  705. ret = -EFAULT;
  706. if (copy_from_user(payload, _payload, plen) != 0)
  707. goto error2;
  708. }
  709. /* find the target key (which must be writable) */
  710. key = lookup_user_key(id, 0, 1, KEY_WRITE);
  711. if (IS_ERR(key)) {
  712. ret = PTR_ERR(key);
  713. goto error2;
  714. }
  715. /* find the destination keyring if present (which must also be
  716. * writable) */
  717. keyring = NULL;
  718. if (ringid) {
  719. keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
  720. if (IS_ERR(keyring)) {
  721. ret = PTR_ERR(keyring);
  722. goto error3;
  723. }
  724. }
  725. /* instantiate the key and link it into a keyring */
  726. ret = key_instantiate_and_link(key, payload, plen, keyring);
  727. key_put(keyring);
  728. error3:
  729. key_put(key);
  730. error2:
  731. kfree(payload);
  732. error:
  733. return ret;
  734. } /* end keyctl_instantiate_key() */
  735. /*****************************************************************************/
  736. /*
  737. * negatively instantiate the key with the given timeout (in seconds), and, if
  738. * one is given, link the key into the keyring
  739. */
  740. long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
  741. {
  742. struct key *key, *keyring;
  743. long ret;
  744. /* find the target key (which must be writable) */
  745. key = lookup_user_key(id, 0, 1, KEY_WRITE);
  746. if (IS_ERR(key)) {
  747. ret = PTR_ERR(key);
  748. goto error;
  749. }
  750. /* find the destination keyring if present (which must also be
  751. * writable) */
  752. keyring = NULL;
  753. if (ringid) {
  754. keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
  755. if (IS_ERR(keyring)) {
  756. ret = PTR_ERR(keyring);
  757. goto error2;
  758. }
  759. }
  760. /* instantiate the key and link it into a keyring */
  761. ret = key_negate_and_link(key, timeout, keyring);
  762. key_put(keyring);
  763. error2:
  764. key_put(key);
  765. error:
  766. return ret;
  767. } /* end keyctl_negate_key() */
  768. /*****************************************************************************/
  769. /*
  770. * the key control system call
  771. */
  772. asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
  773. unsigned long arg4, unsigned long arg5)
  774. {
  775. switch (option) {
  776. case KEYCTL_GET_KEYRING_ID:
  777. return keyctl_get_keyring_ID((key_serial_t) arg2,
  778. (int) arg3);
  779. case KEYCTL_JOIN_SESSION_KEYRING:
  780. return keyctl_join_session_keyring((const char __user *) arg2);
  781. case KEYCTL_UPDATE:
  782. return keyctl_update_key((key_serial_t) arg2,
  783. (const void __user *) arg3,
  784. (size_t) arg4);
  785. case KEYCTL_REVOKE:
  786. return keyctl_revoke_key((key_serial_t) arg2);
  787. case KEYCTL_DESCRIBE:
  788. return keyctl_describe_key((key_serial_t) arg2,
  789. (char __user *) arg3,
  790. (unsigned) arg4);
  791. case KEYCTL_CLEAR:
  792. return keyctl_keyring_clear((key_serial_t) arg2);
  793. case KEYCTL_LINK:
  794. return keyctl_keyring_link((key_serial_t) arg2,
  795. (key_serial_t) arg3);
  796. case KEYCTL_UNLINK:
  797. return keyctl_keyring_unlink((key_serial_t) arg2,
  798. (key_serial_t) arg3);
  799. case KEYCTL_SEARCH:
  800. return keyctl_keyring_search((key_serial_t) arg2,
  801. (const char __user *) arg3,
  802. (const char __user *) arg4,
  803. (key_serial_t) arg5);
  804. case KEYCTL_READ:
  805. return keyctl_read_key((key_serial_t) arg2,
  806. (char __user *) arg3,
  807. (size_t) arg4);
  808. case KEYCTL_CHOWN:
  809. return keyctl_chown_key((key_serial_t) arg2,
  810. (uid_t) arg3,
  811. (gid_t) arg4);
  812. case KEYCTL_SETPERM:
  813. return keyctl_setperm_key((key_serial_t) arg2,
  814. (key_perm_t) arg3);
  815. case KEYCTL_INSTANTIATE:
  816. return keyctl_instantiate_key((key_serial_t) arg2,
  817. (const void __user *) arg3,
  818. (size_t) arg4,
  819. (key_serial_t) arg5);
  820. case KEYCTL_NEGATE:
  821. return keyctl_negate_key((key_serial_t) arg2,
  822. (unsigned) arg3,
  823. (key_serial_t) arg4);
  824. default:
  825. return -EOPNOTSUPP;
  826. }
  827. } /* end sys_keyctl() */