diff options
-rw-r--r-- | Documentation/keys.txt | 285 | ||||
-rw-r--r-- | include/linux/key-ui.h | 6 | ||||
-rw-r--r-- | include/linux/key.h | 25 | ||||
-rw-r--r-- | security/keys/key.c | 94 | ||||
-rw-r--r-- | security/keys/keyctl.c | 23 | ||||
-rw-r--r-- | security/keys/keyring.c | 245 | ||||
-rw-r--r-- | security/keys/proc.c | 21 | ||||
-rw-r--r-- | security/keys/process_keys.c | 12 | ||||
-rw-r--r-- | security/keys/request_key.c | 32 | ||||
-rw-r--r-- | security/keys/user_defined.c | 85 |
10 files changed, 480 insertions, 348 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index 36d80aeeaf28..3df40c1fe15a 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -22,6 +22,7 @@ This document has the following sections: | |||
22 | - New procfs files | 22 | - New procfs files |
23 | - Userspace system call interface | 23 | - Userspace system call interface |
24 | - Kernel services | 24 | - Kernel services |
25 | - Notes on accessing payload contents | ||
25 | - Defining a key type | 26 | - Defining a key type |
26 | - Request-key callback service | 27 | - Request-key callback service |
27 | - Key access filesystem | 28 | - Key access filesystem |
@@ -45,27 +46,26 @@ Each key has a number of attributes: | |||
45 | - State. | 46 | - State. |
46 | 47 | ||
47 | 48 | ||
48 | (*) Each key is issued a serial number of type key_serial_t that is unique | 49 | (*) Each key is issued a serial number of type key_serial_t that is unique for |
49 | for the lifetime of that key. All serial numbers are positive non-zero | 50 | the lifetime of that key. All serial numbers are positive non-zero 32-bit |
50 | 32-bit integers. | 51 | integers. |
51 | 52 | ||
52 | Userspace programs can use a key's serial numbers as a way to gain access | 53 | Userspace programs can use a key's serial numbers as a way to gain access |
53 | to it, subject to permission checking. | 54 | to it, subject to permission checking. |
54 | 55 | ||
55 | (*) Each key is of a defined "type". Types must be registered inside the | 56 | (*) Each key is of a defined "type". Types must be registered inside the |
56 | kernel by a kernel service (such as a filesystem) before keys of that | 57 | kernel by a kernel service (such as a filesystem) before keys of that type |
57 | type can be added or used. Userspace programs cannot define new types | 58 | can be added or used. Userspace programs cannot define new types directly. |
58 | directly. | ||
59 | 59 | ||
60 | Key types are represented in the kernel by struct key_type. This defines | 60 | Key types are represented in the kernel by struct key_type. This defines a |
61 | a number of operations that can be performed on a key of that type. | 61 | number of operations that can be performed on a key of that type. |
62 | 62 | ||
63 | Should a type be removed from the system, all the keys of that type will | 63 | Should a type be removed from the system, all the keys of that type will |
64 | be invalidated. | 64 | be invalidated. |
65 | 65 | ||
66 | (*) Each key has a description. This should be a printable string. The key | 66 | (*) Each key has a description. This should be a printable string. The key |
67 | type provides an operation to perform a match between the description on | 67 | type provides an operation to perform a match between the description on a |
68 | a key and a criterion string. | 68 | key and a criterion string. |
69 | 69 | ||
70 | (*) Each key has an owner user ID, a group ID and a permissions mask. These | 70 | (*) Each key has an owner user ID, a group ID and a permissions mask. These |
71 | are used to control what a process may do to a key from userspace, and | 71 | are used to control what a process may do to a key from userspace, and |
@@ -74,10 +74,10 @@ Each key has a number of attributes: | |||
74 | (*) Each key can be set to expire at a specific time by the key type's | 74 | (*) Each key can be set to expire at a specific time by the key type's |
75 | instantiation function. Keys can also be immortal. | 75 | instantiation function. Keys can also be immortal. |
76 | 76 | ||
77 | (*) Each key can have a payload. This is a quantity of data that represent | 77 | (*) Each key can have a payload. This is a quantity of data that represent the |
78 | the actual "key". In the case of a keyring, this is a list of keys to | 78 | actual "key". In the case of a keyring, this is a list of keys to which |
79 | which the keyring links; in the case of a user-defined key, it's an | 79 | the keyring links; in the case of a user-defined key, it's an arbitrary |
80 | arbitrary blob of data. | 80 | blob of data. |
81 | 81 | ||
82 | Having a payload is not required; and the payload can, in fact, just be a | 82 | Having a payload is not required; and the payload can, in fact, just be a |
83 | value stored in the struct key itself. | 83 | value stored in the struct key itself. |
@@ -92,8 +92,8 @@ Each key has a number of attributes: | |||
92 | 92 | ||
93 | (*) Each key can be in one of a number of basic states: | 93 | (*) Each key can be in one of a number of basic states: |
94 | 94 | ||
95 | (*) Uninstantiated. The key exists, but does not have any data | 95 | (*) Uninstantiated. The key exists, but does not have any data attached. |
96 | attached. Keys being requested from userspace will be in this state. | 96 | Keys being requested from userspace will be in this state. |
97 | 97 | ||
98 | (*) Instantiated. This is the normal state. The key is fully formed, and | 98 | (*) Instantiated. This is the normal state. The key is fully formed, and |
99 | has data attached. | 99 | has data attached. |
@@ -140,10 +140,10 @@ The key service provides a number of features besides keys: | |||
140 | clone, fork, vfork or execve occurs. A new keyring is created only when | 140 | clone, fork, vfork or execve occurs. A new keyring is created only when |
141 | required. | 141 | required. |
142 | 142 | ||
143 | The process-specific keyring is replaced with an empty one in the child | 143 | The process-specific keyring is replaced with an empty one in the child on |
144 | on clone, fork, vfork unless CLONE_THREAD is supplied, in which case it | 144 | clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is |
145 | is shared. execve also discards the process's process keyring and creates | 145 | shared. execve also discards the process's process keyring and creates a |
146 | a new one. | 146 | new one. |
147 | 147 | ||
148 | The session-specific keyring is persistent across clone, fork, vfork and | 148 | The session-specific keyring is persistent across clone, fork, vfork and |
149 | execve, even when the latter executes a set-UID or set-GID binary. A | 149 | execve, even when the latter executes a set-UID or set-GID binary. A |
@@ -177,11 +177,11 @@ The key service provides a number of features besides keys: | |||
177 | If a system call that modifies a key or keyring in some way would put the | 177 | If a system call that modifies a key or keyring in some way would put the |
178 | user over quota, the operation is refused and error EDQUOT is returned. | 178 | user over quota, the operation is refused and error EDQUOT is returned. |
179 | 179 | ||
180 | (*) There's a system call interface by which userspace programs can create | 180 | (*) There's a system call interface by which userspace programs can create and |
181 | and manipulate keys and keyrings. | 181 | manipulate keys and keyrings. |
182 | 182 | ||
183 | (*) There's a kernel interface by which services can register types and | 183 | (*) There's a kernel interface by which services can register types and search |
184 | search for keys. | 184 | for keys. |
185 | 185 | ||
186 | (*) There's a way for the a search done from the kernel to call back to | 186 | (*) There's a way for the a search done from the kernel to call back to |
187 | userspace to request a key that can't be found in a process's keyrings. | 187 | userspace to request a key that can't be found in a process's keyrings. |
@@ -194,9 +194,9 @@ The key service provides a number of features besides keys: | |||
194 | KEY ACCESS PERMISSIONS | 194 | KEY ACCESS PERMISSIONS |
195 | ====================== | 195 | ====================== |
196 | 196 | ||
197 | Keys have an owner user ID, a group access ID, and a permissions mask. The | 197 | Keys have an owner user ID, a group access ID, and a permissions mask. The mask |
198 | mask has up to eight bits each for user, group and other access. Only five of | 198 | has up to eight bits each for user, group and other access. Only five of each |
199 | each set of eight bits are defined. These permissions granted are: | 199 | set of eight bits are defined. These permissions granted are: |
200 | 200 | ||
201 | (*) View | 201 | (*) View |
202 | 202 | ||
@@ -210,8 +210,8 @@ each set of eight bits are defined. These permissions granted are: | |||
210 | 210 | ||
211 | (*) Write | 211 | (*) Write |
212 | 212 | ||
213 | This permits a key's payload to be instantiated or updated, or it allows | 213 | This permits a key's payload to be instantiated or updated, or it allows a |
214 | a link to be added to or removed from a keyring. | 214 | link to be added to or removed from a keyring. |
215 | 215 | ||
216 | (*) Search | 216 | (*) Search |
217 | 217 | ||
@@ -238,8 +238,8 @@ about the status of the key service: | |||
238 | (*) /proc/keys | 238 | (*) /proc/keys |
239 | 239 | ||
240 | This lists all the keys on the system, giving information about their | 240 | This lists all the keys on the system, giving information about their |
241 | type, description and permissions. The payload of the key is not | 241 | type, description and permissions. The payload of the key is not available |
242 | available this way: | 242 | this way: |
243 | 243 | ||
244 | SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY | 244 | SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY |
245 | 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4 | 245 | 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4 |
@@ -318,21 +318,21 @@ The main syscalls are: | |||
318 | If a key of the same type and description as that proposed already exists | 318 | If a key of the same type and description as that proposed already exists |
319 | in the keyring, this will try to update it with the given payload, or it | 319 | in the keyring, this will try to update it with the given payload, or it |
320 | will return error EEXIST if that function is not supported by the key | 320 | will return error EEXIST if that function is not supported by the key |
321 | type. The process must also have permission to write to the key to be | 321 | type. The process must also have permission to write to the key to be able |
322 | able to update it. The new key will have all user permissions granted and | 322 | to update it. The new key will have all user permissions granted and no |
323 | no group or third party permissions. | 323 | group or third party permissions. |
324 | 324 | ||
325 | Otherwise, this will attempt to create a new key of the specified type | 325 | Otherwise, this will attempt to create a new key of the specified type and |
326 | and description, and to instantiate it with the supplied payload and | 326 | description, and to instantiate it with the supplied payload and attach it |
327 | attach it to the keyring. In this case, an error will be generated if the | 327 | to the keyring. In this case, an error will be generated if the process |
328 | process does not have permission to write to the keyring. | 328 | does not have permission to write to the keyring. |
329 | 329 | ||
330 | The payload is optional, and the pointer can be NULL if not required by | 330 | The payload is optional, and the pointer can be NULL if not required by |
331 | the type. The payload is plen in size, and plen can be zero for an empty | 331 | the type. The payload is plen in size, and plen can be zero for an empty |
332 | payload. | 332 | payload. |
333 | 333 | ||
334 | A new keyring can be generated by setting type "keyring", the keyring | 334 | A new keyring can be generated by setting type "keyring", the keyring name |
335 | name as the description (or NULL) and setting the payload to NULL. | 335 | as the description (or NULL) and setting the payload to NULL. |
336 | 336 | ||
337 | User defined keys can be created by specifying type "user". It is | 337 | User defined keys can be created by specifying type "user". It is |
338 | recommended that a user defined key's description by prefixed with a type | 338 | recommended that a user defined key's description by prefixed with a type |
@@ -369,9 +369,9 @@ The keyctl syscall functions are: | |||
369 | key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id, | 369 | key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id, |
370 | int create); | 370 | int create); |
371 | 371 | ||
372 | The special key specified by "id" is looked up (with the key being | 372 | The special key specified by "id" is looked up (with the key being created |
373 | created if necessary) and the ID of the key or keyring thus found is | 373 | if necessary) and the ID of the key or keyring thus found is returned if |
374 | returned if it exists. | 374 | it exists. |
375 | 375 | ||
376 | If the key does not yet exist, the key will be created if "create" is | 376 | If the key does not yet exist, the key will be created if "create" is |
377 | non-zero; and the error ENOKEY will be returned if "create" is zero. | 377 | non-zero; and the error ENOKEY will be returned if "create" is zero. |
@@ -402,8 +402,8 @@ The keyctl syscall functions are: | |||
402 | 402 | ||
403 | This will try to update the specified key with the given payload, or it | 403 | This will try to update the specified key with the given payload, or it |
404 | will return error EOPNOTSUPP if that function is not supported by the key | 404 | will return error EOPNOTSUPP if that function is not supported by the key |
405 | type. The process must also have permission to write to the key to be | 405 | type. The process must also have permission to write to the key to be able |
406 | able to update it. | 406 | to update it. |
407 | 407 | ||
408 | The payload is of length plen, and may be absent or empty as for | 408 | The payload is of length plen, and may be absent or empty as for |
409 | add_key(). | 409 | add_key(). |
@@ -422,8 +422,8 @@ The keyctl syscall functions are: | |||
422 | 422 | ||
423 | long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid); | 423 | long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid); |
424 | 424 | ||
425 | This function permits a key's owner and group ID to be changed. Either | 425 | This function permits a key's owner and group ID to be changed. Either one |
426 | one of uid or gid can be set to -1 to suppress that change. | 426 | of uid or gid can be set to -1 to suppress that change. |
427 | 427 | ||
428 | Only the superuser can change a key's owner to something other than the | 428 | Only the superuser can change a key's owner to something other than the |
429 | key's current owner. Similarly, only the superuser can change a key's | 429 | key's current owner. Similarly, only the superuser can change a key's |
@@ -484,12 +484,12 @@ The keyctl syscall functions are: | |||
484 | 484 | ||
485 | long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key); | 485 | long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key); |
486 | 486 | ||
487 | This function creates a link from the keyring to the key. The process | 487 | This function creates a link from the keyring to the key. The process must |
488 | must have write permission on the keyring and must have link permission | 488 | have write permission on the keyring and must have link permission on the |
489 | on the key. | 489 | key. |
490 | 490 | ||
491 | Should the keyring not be a keyring, error ENOTDIR will result; and if | 491 | Should the keyring not be a keyring, error ENOTDIR will result; and if the |
492 | the keyring is full, error ENFILE will result. | 492 | keyring is full, error ENFILE will result. |
493 | 493 | ||
494 | The link procedure checks the nesting of the keyrings, returning ELOOP if | 494 | The link procedure checks the nesting of the keyrings, returning ELOOP if |
495 | it appears to deep or EDEADLK if the link would introduce a cycle. | 495 | it appears to deep or EDEADLK if the link would introduce a cycle. |
@@ -503,8 +503,8 @@ The keyctl syscall functions are: | |||
503 | specified key, and removes it if found. Subsequent links to that key are | 503 | specified key, and removes it if found. Subsequent links to that key are |
504 | ignored. The process must have write permission on the keyring. | 504 | ignored. The process must have write permission on the keyring. |
505 | 505 | ||
506 | If the keyring is not a keyring, error ENOTDIR will result; and if the | 506 | If the keyring is not a keyring, error ENOTDIR will result; and if the key |
507 | key is not present, error ENOENT will be the result. | 507 | is not present, error ENOENT will be the result. |
508 | 508 | ||
509 | 509 | ||
510 | (*) Search a keyring tree for a key: | 510 | (*) Search a keyring tree for a key: |
@@ -513,9 +513,9 @@ The keyctl syscall functions are: | |||
513 | const char *type, const char *description, | 513 | const char *type, const char *description, |
514 | key_serial_t dest_keyring); | 514 | key_serial_t dest_keyring); |
515 | 515 | ||
516 | This searches the keyring tree headed by the specified keyring until a | 516 | This searches the keyring tree headed by the specified keyring until a key |
517 | key is found that matches the type and description criteria. Each keyring | 517 | is found that matches the type and description criteria. Each keyring is |
518 | is checked for keys before recursion into its children occurs. | 518 | checked for keys before recursion into its children occurs. |
519 | 519 | ||
520 | The process must have search permission on the top level keyring, or else | 520 | The process must have search permission on the top level keyring, or else |
521 | error EACCES will result. Only keyrings that the process has search | 521 | error EACCES will result. Only keyrings that the process has search |
@@ -549,8 +549,8 @@ The keyctl syscall functions are: | |||
549 | As much of the data as can be fitted into the buffer will be copied to | 549 | As much of the data as can be fitted into the buffer will be copied to |
550 | userspace if the buffer pointer is not NULL. | 550 | userspace if the buffer pointer is not NULL. |
551 | 551 | ||
552 | On a successful return, the function will always return the amount of | 552 | On a successful return, the function will always return the amount of data |
553 | data available rather than the amount copied. | 553 | available rather than the amount copied. |
554 | 554 | ||
555 | 555 | ||
556 | (*) Instantiate a partially constructed key. | 556 | (*) Instantiate a partially constructed key. |
@@ -568,8 +568,8 @@ The keyctl syscall functions are: | |||
568 | it, and the key must be uninstantiated. | 568 | it, and the key must be uninstantiated. |
569 | 569 | ||
570 | If a keyring is specified (non-zero), the key will also be linked into | 570 | If a keyring is specified (non-zero), the key will also be linked into |
571 | that keyring, however all the constraints applying in KEYCTL_LINK apply | 571 | that keyring, however all the constraints applying in KEYCTL_LINK apply in |
572 | in this case too. | 572 | this case too. |
573 | 573 | ||
574 | The payload and plen arguments describe the payload data as for add_key(). | 574 | The payload and plen arguments describe the payload data as for add_key(). |
575 | 575 | ||
@@ -587,8 +587,8 @@ The keyctl syscall functions are: | |||
587 | it, and the key must be uninstantiated. | 587 | it, and the key must be uninstantiated. |
588 | 588 | ||
589 | If a keyring is specified (non-zero), the key will also be linked into | 589 | If a keyring is specified (non-zero), the key will also be linked into |
590 | that keyring, however all the constraints applying in KEYCTL_LINK apply | 590 | that keyring, however all the constraints applying in KEYCTL_LINK apply in |
591 | in this case too. | 591 | this case too. |
592 | 592 | ||
593 | 593 | ||
594 | =============== | 594 | =============== |
@@ -601,17 +601,14 @@ be broken down into two areas: keys and key types. | |||
601 | Dealing with keys is fairly straightforward. Firstly, the kernel service | 601 | Dealing with keys is fairly straightforward. Firstly, the kernel service |
602 | registers its type, then it searches for a key of that type. It should retain | 602 | registers its type, then it searches for a key of that type. It should retain |
603 | the key as long as it has need of it, and then it should release it. For a | 603 | the key as long as it has need of it, and then it should release it. For a |
604 | filesystem or device file, a search would probably be performed during the | 604 | filesystem or device file, a search would probably be performed during the open |
605 | open call, and the key released upon close. How to deal with conflicting keys | 605 | call, and the key released upon close. How to deal with conflicting keys due to |
606 | due to two different users opening the same file is left to the filesystem | 606 | two different users opening the same file is left to the filesystem author to |
607 | author to solve. | 607 | solve. |
608 | 608 | ||
609 | When accessing a key's payload data, key->lock should be at least read locked, | 609 | When accessing a key's payload contents, certain precautions must be taken to |
610 | or else the data may be changed by an update being performed from userspace | 610 | prevent access vs modification races. See the section "Notes on accessing |
611 | whilst the driver or filesystem is trying to access it. If no update method is | 611 | payload contents" for more information. |
612 | supplied, then the key's payload may be accessed without holding a lock as | ||
613 | there is no way to change it, provided it can be guaranteed that the key's | ||
614 | type definition won't go away. | ||
615 | 612 | ||
616 | (*) To search for a key, call: | 613 | (*) To search for a key, call: |
617 | 614 | ||
@@ -690,6 +687,54 @@ type definition won't go away. | |||
690 | void unregister_key_type(struct key_type *type); | 687 | void unregister_key_type(struct key_type *type); |
691 | 688 | ||
692 | 689 | ||
690 | =================================== | ||
691 | NOTES ON ACCESSING PAYLOAD CONTENTS | ||
692 | =================================== | ||
693 | |||
694 | The simplest payload is just a number in key->payload.value. In this case, | ||
695 | there's no need to indulge in RCU or locking when accessing the payload. | ||
696 | |||
697 | More complex payload contents must be allocated and a pointer to them set in | ||
698 | key->payload.data. One of the following ways must be selected to access the | ||
699 | data: | ||
700 | |||
701 | (1) Unmodifyable key type. | ||
702 | |||
703 | If the key type does not have a modify method, then the key's payload can | ||
704 | be accessed without any form of locking, provided that it's known to be | ||
705 | instantiated (uninstantiated keys cannot be "found"). | ||
706 | |||
707 | (2) The key's semaphore. | ||
708 | |||
709 | The semaphore could be used to govern access to the payload and to control | ||
710 | the payload pointer. It must be write-locked for modifications and would | ||
711 | have to be read-locked for general access. The disadvantage of doing this | ||
712 | is that the accessor may be required to sleep. | ||
713 | |||
714 | (3) RCU. | ||
715 | |||
716 | RCU must be used when the semaphore isn't already held; if the semaphore | ||
717 | is held then the contents can't change under you unexpectedly as the | ||
718 | semaphore must still be used to serialise modifications to the key. The | ||
719 | key management code takes care of this for the key type. | ||
720 | |||
721 | However, this means using: | ||
722 | |||
723 | rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock() | ||
724 | |||
725 | to read the pointer, and: | ||
726 | |||
727 | rcu_dereference() ... rcu_assign_pointer() ... call_rcu() | ||
728 | |||
729 | to set the pointer and dispose of the old contents after a grace period. | ||
730 | Note that only the key type should ever modify a key's payload. | ||
731 | |||
732 | Furthermore, an RCU controlled payload must hold a struct rcu_head for the | ||
733 | use of call_rcu() and, if the payload is of variable size, the length of | ||
734 | the payload. key->datalen cannot be relied upon to be consistent with the | ||
735 | payload just dereferenced if the key's semaphore is not held. | ||
736 | |||
737 | |||
693 | =================== | 738 | =================== |
694 | DEFINING A KEY TYPE | 739 | DEFINING A KEY TYPE |
695 | =================== | 740 | =================== |
@@ -717,15 +762,15 @@ The structure has a number of fields, some of which are mandatory: | |||
717 | 762 | ||
718 | int key_payload_reserve(struct key *key, size_t datalen); | 763 | int key_payload_reserve(struct key *key, size_t datalen); |
719 | 764 | ||
720 | With the revised data length. Error EDQUOT will be returned if this is | 765 | With the revised data length. Error EDQUOT will be returned if this is not |
721 | not viable. | 766 | viable. |
722 | 767 | ||
723 | 768 | ||
724 | (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); | 769 | (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); |
725 | 770 | ||
726 | This method is called to attach a payload to a key during construction. | 771 | This method is called to attach a payload to a key during construction. |
727 | The payload attached need not bear any relation to the data passed to | 772 | The payload attached need not bear any relation to the data passed to this |
728 | this function. | 773 | function. |
729 | 774 | ||
730 | If the amount of data attached to the key differs from the size in | 775 | If the amount of data attached to the key differs from the size in |
731 | keytype->def_datalen, then key_payload_reserve() should be called. | 776 | keytype->def_datalen, then key_payload_reserve() should be called. |
@@ -734,38 +779,47 @@ The structure has a number of fields, some of which are mandatory: | |||
734 | The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents | 779 | The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents |
735 | anything else from gaining access to the key. | 780 | anything else from gaining access to the key. |
736 | 781 | ||
737 | This method may sleep if it wishes. | 782 | It is safe to sleep in this method. |
738 | 783 | ||
739 | 784 | ||
740 | (*) int (*duplicate)(struct key *key, const struct key *source); | 785 | (*) int (*duplicate)(struct key *key, const struct key *source); |
741 | 786 | ||
742 | If this type of key can be duplicated, then this method should be | 787 | If this type of key can be duplicated, then this method should be |
743 | provided. It is called to copy the payload attached to the source into | 788 | provided. It is called to copy the payload attached to the source into the |
744 | the new key. The data length on the new key will have been updated and | 789 | new key. The data length on the new key will have been updated and the |
745 | the quota adjusted already. | 790 | quota adjusted already. |
746 | 791 | ||
747 | This method will be called with the source key's semaphore read-locked to | 792 | This method will be called with the source key's semaphore read-locked to |
748 | prevent its payload from being changed. It is safe to sleep here. | 793 | prevent its payload from being changed, thus RCU constraints need not be |
794 | applied to the source key. | ||
795 | |||
796 | This method does not have to lock the destination key in order to attach a | ||
797 | payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags | ||
798 | prevents anything else from gaining access to the key. | ||
799 | |||
800 | It is safe to sleep in this method. | ||
749 | 801 | ||
750 | 802 | ||
751 | (*) int (*update)(struct key *key, const void *data, size_t datalen); | 803 | (*) int (*update)(struct key *key, const void *data, size_t datalen); |
752 | 804 | ||
753 | If this type of key can be updated, then this method should be | 805 | If this type of key can be updated, then this method should be provided. |
754 | provided. It is called to update a key's payload from the blob of data | 806 | It is called to update a key's payload from the blob of data provided. |
755 | provided. | ||
756 | 807 | ||
757 | key_payload_reserve() should be called if the data length might change | 808 | key_payload_reserve() should be called if the data length might change |
758 | before any changes are actually made. Note that if this succeeds, the | 809 | before any changes are actually made. Note that if this succeeds, the type |
759 | type is committed to changing the key because it's already been altered, | 810 | is committed to changing the key because it's already been altered, so all |
760 | so all memory allocation must be done first. | 811 | memory allocation must be done first. |
812 | |||
813 | The key will have its semaphore write-locked before this method is called, | ||
814 | but this only deters other writers; any changes to the key's payload must | ||
815 | be made under RCU conditions, and call_rcu() must be used to dispose of | ||
816 | the old payload. | ||
761 | 817 | ||
762 | key_payload_reserve() should be called with the key->lock write locked, | 818 | key_payload_reserve() should be called before the changes are made, but |
763 | and the changes to the key's attached payload should be made before the | 819 | after all allocations and other potentially failing function calls are |
764 | key is locked. | 820 | made. |
765 | 821 | ||
766 | The key will have its semaphore write-locked before this method is | 822 | It is safe to sleep in this method. |
767 | called. Any changes to the key should be made with the key's rwlock | ||
768 | write-locked also. It is safe to sleep here. | ||
769 | 823 | ||
770 | 824 | ||
771 | (*) int (*match)(const struct key *key, const void *desc); | 825 | (*) int (*match)(const struct key *key, const void *desc); |
@@ -782,12 +836,12 @@ The structure has a number of fields, some of which are mandatory: | |||
782 | 836 | ||
783 | (*) void (*destroy)(struct key *key); | 837 | (*) void (*destroy)(struct key *key); |
784 | 838 | ||
785 | This method is optional. It is called to discard the payload data on a | 839 | This method is optional. It is called to discard the payload data on a key |
786 | key when it is being destroyed. | 840 | when it is being destroyed. |
787 | 841 | ||
788 | This method does not need to lock the key; it can consider the key as | 842 | This method does not need to lock the key to access the payload; it can |
789 | being inaccessible. Note that the key's type may have changed before this | 843 | consider the key as being inaccessible at this time. Note that the key's |
790 | function is called. | 844 | type may have been changed before this function is called. |
791 | 845 | ||
792 | It is not safe to sleep in this method; the caller may hold spinlocks. | 846 | It is not safe to sleep in this method; the caller may hold spinlocks. |
793 | 847 | ||
@@ -797,26 +851,31 @@ The structure has a number of fields, some of which are mandatory: | |||
797 | This method is optional. It is called during /proc/keys reading to | 851 | This method is optional. It is called during /proc/keys reading to |
798 | summarise a key's description and payload in text form. | 852 | summarise a key's description and payload in text form. |
799 | 853 | ||
800 | This method will be called with the key's rwlock read-locked. This will | 854 | This method will be called with the RCU read lock held. rcu_dereference() |
801 | prevent the key's payload and state changing; also the description should | 855 | should be used to read the payload pointer if the payload is to be |
802 | not change. This also means it is not safe to sleep in this method. | 856 | accessed. key->datalen cannot be trusted to stay consistent with the |
857 | contents of the payload. | ||
858 | |||
859 | The description will not change, though the key's state may. | ||
860 | |||
861 | It is not safe to sleep in this method; the RCU read lock is held by the | ||
862 | caller. | ||
803 | 863 | ||
804 | 864 | ||
805 | (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen); | 865 | (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen); |
806 | 866 | ||
807 | This method is optional. It is called by KEYCTL_READ to translate the | 867 | This method is optional. It is called by KEYCTL_READ to translate the |
808 | key's payload into something a blob of data for userspace to deal | 868 | key's payload into something a blob of data for userspace to deal with. |
809 | with. Ideally, the blob should be in the same format as that passed in to | 869 | Ideally, the blob should be in the same format as that passed in to the |
810 | the instantiate and update methods. | 870 | instantiate and update methods. |
811 | 871 | ||
812 | If successful, the blob size that could be produced should be returned | 872 | If successful, the blob size that could be produced should be returned |
813 | rather than the size copied. | 873 | rather than the size copied. |
814 | 874 | ||
815 | This method will be called with the key's semaphore read-locked. This | 875 | This method will be called with the key's semaphore read-locked. This will |
816 | will prevent the key's payload changing. It is not necessary to also | 876 | prevent the key's payload changing. It is not necessary to use RCU locking |
817 | read-lock key->lock when accessing the key's payload. It is safe to sleep | 877 | when accessing the key's payload. It is safe to sleep in this method, such |
818 | in this method, such as might happen when the userspace buffer is | 878 | as might happen when the userspace buffer is accessed. |
819 | accessed. | ||
820 | 879 | ||
821 | 880 | ||
822 | ============================ | 881 | ============================ |
@@ -853,8 +912,8 @@ If it returns with the key remaining in the unconstructed state, the key will | |||
853 | be marked as being negative, it will be added to the session keyring, and an | 912 | be marked as being negative, it will be added to the session keyring, and an |
854 | error will be returned to the key requestor. | 913 | error will be returned to the key requestor. |
855 | 914 | ||
856 | Supplementary information may be provided from whoever or whatever invoked | 915 | Supplementary information may be provided from whoever or whatever invoked this |
857 | this service. This will be passed as the <callout_info> parameter. If no such | 916 | service. This will be passed as the <callout_info> parameter. If no such |
858 | information was made available, then "-" will be passed as this parameter | 917 | information was made available, then "-" will be passed as this parameter |
859 | instead. | 918 | instead. |
860 | 919 | ||
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h index 60cc7b762e78..159ca8d54e9a 100644 --- a/include/linux/key-ui.h +++ b/include/linux/key-ui.h | |||
@@ -31,8 +31,10 @@ extern spinlock_t key_serial_lock; | |||
31 | * subscribed | 31 | * subscribed |
32 | */ | 32 | */ |
33 | struct keyring_list { | 33 | struct keyring_list { |
34 | unsigned maxkeys; /* max keys this list can hold */ | 34 | struct rcu_head rcu; /* RCU deletion hook */ |
35 | unsigned nkeys; /* number of keys currently held */ | 35 | unsigned short maxkeys; /* max keys this list can hold */ |
36 | unsigned short nkeys; /* number of keys currently held */ | ||
37 | unsigned short delkey; /* key to be unlinked by RCU */ | ||
36 | struct key *keys[0]; | 38 | struct key *keys[0]; |
37 | }; | 39 | }; |
38 | 40 | ||
diff --git a/include/linux/key.h b/include/linux/key.h index 6aa46d0e812f..2c24ffaca86f 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/rbtree.h> | 20 | #include <linux/rbtree.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/rcupdate.h> |
22 | #include <asm/atomic.h> | 22 | #include <asm/atomic.h> |
23 | 23 | ||
24 | #ifdef __KERNEL__ | 24 | #ifdef __KERNEL__ |
@@ -78,7 +78,6 @@ struct key { | |||
78 | key_serial_t serial; /* key serial number */ | 78 | key_serial_t serial; /* key serial number */ |
79 | struct rb_node serial_node; | 79 | struct rb_node serial_node; |
80 | struct key_type *type; /* type of key */ | 80 | struct key_type *type; /* type of key */ |
81 | rwlock_t lock; /* examination vs change lock */ | ||
82 | struct rw_semaphore sem; /* change vs change sem */ | 81 | struct rw_semaphore sem; /* change vs change sem */ |
83 | struct key_user *user; /* owner of this key */ | 82 | struct key_user *user; /* owner of this key */ |
84 | time_t expiry; /* time at which key expires (or 0) */ | 83 | time_t expiry; /* time at which key expires (or 0) */ |
@@ -86,14 +85,10 @@ struct key { | |||
86 | gid_t gid; | 85 | gid_t gid; |
87 | key_perm_t perm; /* access permissions */ | 86 | key_perm_t perm; /* access permissions */ |
88 | unsigned short quotalen; /* length added to quota */ | 87 | unsigned short quotalen; /* length added to quota */ |
89 | unsigned short datalen; /* payload data length */ | 88 | unsigned short datalen; /* payload data length |
90 | unsigned short flags; /* status flags (change with lock writelocked) */ | 89 | * - may not match RCU dereferenced payload |
91 | #define KEY_FLAG_INSTANTIATED 0x00000001 /* set if key has been instantiated */ | 90 | * - payload should contain own length |
92 | #define KEY_FLAG_DEAD 0x00000002 /* set if key type has been deleted */ | 91 | */ |
93 | #define KEY_FLAG_REVOKED 0x00000004 /* set if key had been revoked */ | ||
94 | #define KEY_FLAG_IN_QUOTA 0x00000008 /* set if key consumes quota */ | ||
95 | #define KEY_FLAG_USER_CONSTRUCT 0x00000010 /* set if key is being constructed in userspace */ | ||
96 | #define KEY_FLAG_NEGATIVE 0x00000020 /* set if key is negative */ | ||
97 | 92 | ||
98 | #ifdef KEY_DEBUGGING | 93 | #ifdef KEY_DEBUGGING |
99 | unsigned magic; | 94 | unsigned magic; |
@@ -101,6 +96,14 @@ struct key { | |||
101 | #define KEY_DEBUG_MAGIC_X 0xf8e9dacbu | 96 | #define KEY_DEBUG_MAGIC_X 0xf8e9dacbu |
102 | #endif | 97 | #endif |
103 | 98 | ||
99 | unsigned long flags; /* status flags (change with bitops) */ | ||
100 | #define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */ | ||
101 | #define KEY_FLAG_DEAD 1 /* set if key type has been deleted */ | ||
102 | #define KEY_FLAG_REVOKED 2 /* set if key had been revoked */ | ||
103 | #define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ | ||
104 | #define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ | ||
105 | #define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ | ||
106 | |||
104 | /* the description string | 107 | /* the description string |
105 | * - this is used to match a key against search criteria | 108 | * - this is used to match a key against search criteria |
106 | * - this should be a printable string | 109 | * - this should be a printable string |
@@ -250,6 +253,8 @@ extern int keyring_add_key(struct key *keyring, | |||
250 | 253 | ||
251 | extern struct key *key_lookup(key_serial_t id); | 254 | extern struct key *key_lookup(key_serial_t id); |
252 | 255 | ||
256 | extern void keyring_replace_payload(struct key *key, void *replacement); | ||
257 | |||
253 | #define key_serial(key) ((key) ? (key)->serial : 0) | 258 | #define key_serial(key) ((key) ? (key)->serial : 0) |
254 | 259 | ||
255 | /* | 260 | /* |
diff --git a/security/keys/key.c b/security/keys/key.c index 59402c843203..1fdfccb3fe43 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -294,7 +294,6 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
294 | } | 294 | } |
295 | 295 | ||
296 | atomic_set(&key->usage, 1); | 296 | atomic_set(&key->usage, 1); |
297 | rwlock_init(&key->lock); | ||
298 | init_rwsem(&key->sem); | 297 | init_rwsem(&key->sem); |
299 | key->type = type; | 298 | key->type = type; |
300 | key->user = user; | 299 | key->user = user; |
@@ -308,7 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
308 | key->payload.data = NULL; | 307 | key->payload.data = NULL; |
309 | 308 | ||
310 | if (!not_in_quota) | 309 | if (!not_in_quota) |
311 | key->flags |= KEY_FLAG_IN_QUOTA; | 310 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; |
312 | 311 | ||
313 | memset(&key->type_data, 0, sizeof(key->type_data)); | 312 | memset(&key->type_data, 0, sizeof(key->type_data)); |
314 | 313 | ||
@@ -359,7 +358,7 @@ int key_payload_reserve(struct key *key, size_t datalen) | |||
359 | key_check(key); | 358 | key_check(key); |
360 | 359 | ||
361 | /* contemplate the quota adjustment */ | 360 | /* contemplate the quota adjustment */ |
362 | if (delta != 0 && key->flags & KEY_FLAG_IN_QUOTA) { | 361 | if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { |
363 | spin_lock(&key->user->lock); | 362 | spin_lock(&key->user->lock); |
364 | 363 | ||
365 | if (delta > 0 && | 364 | if (delta > 0 && |
@@ -405,23 +404,17 @@ static int __key_instantiate_and_link(struct key *key, | |||
405 | down_write(&key_construction_sem); | 404 | down_write(&key_construction_sem); |
406 | 405 | ||
407 | /* can't instantiate twice */ | 406 | /* can't instantiate twice */ |
408 | if (!(key->flags & KEY_FLAG_INSTANTIATED)) { | 407 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { |
409 | /* instantiate the key */ | 408 | /* instantiate the key */ |
410 | ret = key->type->instantiate(key, data, datalen); | 409 | ret = key->type->instantiate(key, data, datalen); |
411 | 410 | ||
412 | if (ret == 0) { | 411 | if (ret == 0) { |
413 | /* mark the key as being instantiated */ | 412 | /* mark the key as being instantiated */ |
414 | write_lock(&key->lock); | ||
415 | |||
416 | atomic_inc(&key->user->nikeys); | 413 | atomic_inc(&key->user->nikeys); |
417 | key->flags |= KEY_FLAG_INSTANTIATED; | 414 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); |
418 | 415 | ||
419 | if (key->flags & KEY_FLAG_USER_CONSTRUCT) { | 416 | if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) |
420 | key->flags &= ~KEY_FLAG_USER_CONSTRUCT; | ||
421 | awaken = 1; | 417 | awaken = 1; |
422 | } | ||
423 | |||
424 | write_unlock(&key->lock); | ||
425 | 418 | ||
426 | /* and link it into the destination keyring */ | 419 | /* and link it into the destination keyring */ |
427 | if (keyring) | 420 | if (keyring) |
@@ -486,21 +479,17 @@ int key_negate_and_link(struct key *key, | |||
486 | down_write(&key_construction_sem); | 479 | down_write(&key_construction_sem); |
487 | 480 | ||
488 | /* can't instantiate twice */ | 481 | /* can't instantiate twice */ |
489 | if (!(key->flags & KEY_FLAG_INSTANTIATED)) { | 482 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { |
490 | /* mark the key as being negatively instantiated */ | 483 | /* mark the key as being negatively instantiated */ |
491 | write_lock(&key->lock); | ||
492 | |||
493 | atomic_inc(&key->user->nikeys); | 484 | atomic_inc(&key->user->nikeys); |
494 | key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE; | 485 | set_bit(KEY_FLAG_NEGATIVE, &key->flags); |
486 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); | ||
495 | now = current_kernel_time(); | 487 | now = current_kernel_time(); |
496 | key->expiry = now.tv_sec + timeout; | 488 | key->expiry = now.tv_sec + timeout; |
497 | 489 | ||
498 | if (key->flags & KEY_FLAG_USER_CONSTRUCT) { | 490 | if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) |
499 | key->flags &= ~KEY_FLAG_USER_CONSTRUCT; | ||
500 | awaken = 1; | 491 | awaken = 1; |
501 | } | ||
502 | 492 | ||
503 | write_unlock(&key->lock); | ||
504 | ret = 0; | 493 | ret = 0; |
505 | 494 | ||
506 | /* and link it into the destination keyring */ | 495 | /* and link it into the destination keyring */ |
@@ -553,8 +542,10 @@ static void key_cleanup(void *data) | |||
553 | rb_erase(&key->serial_node, &key_serial_tree); | 542 | rb_erase(&key->serial_node, &key_serial_tree); |
554 | spin_unlock(&key_serial_lock); | 543 | spin_unlock(&key_serial_lock); |
555 | 544 | ||
545 | key_check(key); | ||
546 | |||
556 | /* deal with the user's key tracking and quota */ | 547 | /* deal with the user's key tracking and quota */ |
557 | if (key->flags & KEY_FLAG_IN_QUOTA) { | 548 | if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { |
558 | spin_lock(&key->user->lock); | 549 | spin_lock(&key->user->lock); |
559 | key->user->qnkeys--; | 550 | key->user->qnkeys--; |
560 | key->user->qnbytes -= key->quotalen; | 551 | key->user->qnbytes -= key->quotalen; |
@@ -562,7 +553,7 @@ static void key_cleanup(void *data) | |||
562 | } | 553 | } |
563 | 554 | ||
564 | atomic_dec(&key->user->nkeys); | 555 | atomic_dec(&key->user->nkeys); |
565 | if (key->flags & KEY_FLAG_INSTANTIATED) | 556 | if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) |
566 | atomic_dec(&key->user->nikeys); | 557 | atomic_dec(&key->user->nikeys); |
567 | 558 | ||
568 | key_user_put(key->user); | 559 | key_user_put(key->user); |
@@ -631,9 +622,9 @@ struct key *key_lookup(key_serial_t id) | |||
631 | goto error; | 622 | goto error; |
632 | 623 | ||
633 | found: | 624 | found: |
634 | /* pretent doesn't exist if it's dead */ | 625 | /* pretend it doesn't exist if it's dead */ |
635 | if (atomic_read(&key->usage) == 0 || | 626 | if (atomic_read(&key->usage) == 0 || |
636 | (key->flags & KEY_FLAG_DEAD) || | 627 | test_bit(KEY_FLAG_DEAD, &key->flags) || |
637 | key->type == &key_type_dead) | 628 | key->type == &key_type_dead) |
638 | goto not_found; | 629 | goto not_found; |
639 | 630 | ||
@@ -708,12 +699,9 @@ static inline struct key *__key_update(struct key *key, const void *payload, | |||
708 | 699 | ||
709 | ret = key->type->update(key, payload, plen); | 700 | ret = key->type->update(key, payload, plen); |
710 | 701 | ||
711 | if (ret == 0) { | 702 | if (ret == 0) |
712 | /* updating a negative key instantiates it */ | 703 | /* updating a negative key instantiates it */ |
713 | write_lock(&key->lock); | 704 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); |
714 | key->flags &= ~KEY_FLAG_NEGATIVE; | ||
715 | write_unlock(&key->lock); | ||
716 | } | ||
717 | 705 | ||
718 | up_write(&key->sem); | 706 | up_write(&key->sem); |
719 | 707 | ||
@@ -841,12 +829,9 @@ int key_update(struct key *key, const void *payload, size_t plen) | |||
841 | down_write(&key->sem); | 829 | down_write(&key->sem); |
842 | ret = key->type->update(key, payload, plen); | 830 | ret = key->type->update(key, payload, plen); |
843 | 831 | ||
844 | if (ret == 0) { | 832 | if (ret == 0) |
845 | /* updating a negative key instantiates it */ | 833 | /* updating a negative key instantiates it */ |
846 | write_lock(&key->lock); | 834 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); |
847 | key->flags &= ~KEY_FLAG_NEGATIVE; | ||
848 | write_unlock(&key->lock); | ||
849 | } | ||
850 | 835 | ||
851 | up_write(&key->sem); | 836 | up_write(&key->sem); |
852 | } | 837 | } |
@@ -892,10 +877,7 @@ struct key *key_duplicate(struct key *source, const char *desc) | |||
892 | goto error2; | 877 | goto error2; |
893 | 878 | ||
894 | atomic_inc(&key->user->nikeys); | 879 | atomic_inc(&key->user->nikeys); |
895 | 880 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); | |
896 | write_lock(&key->lock); | ||
897 | key->flags |= KEY_FLAG_INSTANTIATED; | ||
898 | write_unlock(&key->lock); | ||
899 | 881 | ||
900 | error_k: | 882 | error_k: |
901 | up_read(&key_types_sem); | 883 | up_read(&key_types_sem); |
@@ -922,9 +904,7 @@ void key_revoke(struct key *key) | |||
922 | /* make sure no one's trying to change or use the key when we mark | 904 | /* make sure no one's trying to change or use the key when we mark |
923 | * it */ | 905 | * it */ |
924 | down_write(&key->sem); | 906 | down_write(&key->sem); |
925 | write_lock(&key->lock); | 907 | set_bit(KEY_FLAG_REVOKED, &key->flags); |
926 | key->flags |= KEY_FLAG_REVOKED; | ||
927 | write_unlock(&key->lock); | ||
928 | up_write(&key->sem); | 908 | up_write(&key->sem); |
929 | 909 | ||
930 | } /* end key_revoke() */ | 910 | } /* end key_revoke() */ |
@@ -975,24 +955,33 @@ void unregister_key_type(struct key_type *ktype) | |||
975 | /* withdraw the key type */ | 955 | /* withdraw the key type */ |
976 | list_del_init(&ktype->link); | 956 | list_del_init(&ktype->link); |
977 | 957 | ||
978 | /* need to withdraw all keys of this type */ | 958 | /* mark all the keys of this type dead */ |
979 | spin_lock(&key_serial_lock); | 959 | spin_lock(&key_serial_lock); |
980 | 960 | ||
981 | for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { | 961 | for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { |
982 | key = rb_entry(_n, struct key, serial_node); | 962 | key = rb_entry(_n, struct key, serial_node); |
983 | 963 | ||
984 | if (key->type != ktype) | 964 | if (key->type == ktype) |
985 | continue; | 965 | key->type = &key_type_dead; |
966 | } | ||
967 | |||
968 | spin_unlock(&key_serial_lock); | ||
969 | |||
970 | /* make sure everyone revalidates their keys */ | ||
971 | synchronize_kernel(); | ||
972 | |||
973 | /* we should now be able to destroy the payloads of all the keys of | ||
974 | * this type with impunity */ | ||
975 | spin_lock(&key_serial_lock); | ||
986 | 976 | ||
987 | write_lock(&key->lock); | 977 | for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { |
988 | key->type = &key_type_dead; | 978 | key = rb_entry(_n, struct key, serial_node); |
989 | write_unlock(&key->lock); | ||
990 | 979 | ||
991 | /* there shouldn't be anyone looking at the description or | 980 | if (key->type == ktype) { |
992 | * payload now */ | 981 | if (ktype->destroy) |
993 | if (ktype->destroy) | 982 | ktype->destroy(key); |
994 | ktype->destroy(key); | 983 | memset(&key->payload, 0xbd, sizeof(key->payload)); |
995 | memset(&key->payload, 0xbd, sizeof(key->payload)); | 984 | } |
996 | } | 985 | } |
997 | 986 | ||
998 | spin_unlock(&key_serial_lock); | 987 | spin_unlock(&key_serial_lock); |
@@ -1037,4 +1026,5 @@ void __init key_init(void) | |||
1037 | 1026 | ||
1038 | /* link the two root keyrings together */ | 1027 | /* link the two root keyrings together */ |
1039 | key_link(&root_session_keyring, &root_user_keyring); | 1028 | key_link(&root_session_keyring, &root_user_keyring); |
1029 | |||
1040 | } /* end key_init() */ | 1030 | } /* end key_init() */ |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index dc0011b3fac9..cedb7326de29 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -728,7 +728,6 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
728 | /* make the changes with the locks held to prevent chown/chown races */ | 728 | /* make the changes with the locks held to prevent chown/chown races */ |
729 | ret = -EACCES; | 729 | ret = -EACCES; |
730 | down_write(&key->sem); | 730 | down_write(&key->sem); |
731 | write_lock(&key->lock); | ||
732 | 731 | ||
733 | if (!capable(CAP_SYS_ADMIN)) { | 732 | if (!capable(CAP_SYS_ADMIN)) { |
734 | /* only the sysadmin can chown a key to some other UID */ | 733 | /* only the sysadmin can chown a key to some other UID */ |
@@ -755,7 +754,6 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
755 | ret = 0; | 754 | ret = 0; |
756 | 755 | ||
757 | no_access: | 756 | no_access: |
758 | write_unlock(&key->lock); | ||
759 | up_write(&key->sem); | 757 | up_write(&key->sem); |
760 | key_put(key); | 758 | key_put(key); |
761 | error: | 759 | error: |
@@ -784,26 +782,19 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) | |||
784 | goto error; | 782 | goto error; |
785 | } | 783 | } |
786 | 784 | ||
787 | /* make the changes with the locks held to prevent chown/chmod | 785 | /* make the changes with the locks held to prevent chown/chmod races */ |
788 | * races */ | ||
789 | ret = -EACCES; | 786 | ret = -EACCES; |
790 | down_write(&key->sem); | 787 | down_write(&key->sem); |
791 | write_lock(&key->lock); | ||
792 | 788 | ||
793 | /* if we're not the sysadmin, we can only chmod a key that we | 789 | /* if we're not the sysadmin, we can only change a key that we own */ |
794 | * own */ | 790 | if (capable(CAP_SYS_ADMIN) || key->uid == current->fsuid) { |
795 | if (!capable(CAP_SYS_ADMIN) && key->uid != current->fsuid) | 791 | key->perm = perm; |
796 | goto no_access; | 792 | ret = 0; |
797 | 793 | } | |
798 | /* changing the permissions mask */ | ||
799 | key->perm = perm; | ||
800 | ret = 0; | ||
801 | 794 | ||
802 | no_access: | ||
803 | write_unlock(&key->lock); | ||
804 | up_write(&key->sem); | 795 | up_write(&key->sem); |
805 | key_put(key); | 796 | key_put(key); |
806 | error: | 797 | error: |
807 | return ret; | 798 | return ret; |
808 | 799 | ||
809 | } /* end keyctl_setperm_key() */ | 800 | } /* end keyctl_setperm_key() */ |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index e2ab4f8e7481..c9a5de197487 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -132,10 +132,17 @@ static int keyring_duplicate(struct key *keyring, const struct key *source) | |||
132 | (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key); | 132 | (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key); |
133 | 133 | ||
134 | ret = 0; | 134 | ret = 0; |
135 | sklist = source->payload.subscriptions; | ||
136 | 135 | ||
137 | if (sklist && sklist->nkeys > 0) { | 136 | /* find out how many keys are currently linked */ |
137 | rcu_read_lock(); | ||
138 | sklist = rcu_dereference(source->payload.subscriptions); | ||
139 | max = 0; | ||
140 | if (sklist) | ||
138 | max = sklist->nkeys; | 141 | max = sklist->nkeys; |
142 | rcu_read_unlock(); | ||
143 | |||
144 | /* allocate a new payload and stuff load with key links */ | ||
145 | if (max > 0) { | ||
139 | BUG_ON(max > limit); | 146 | BUG_ON(max > limit); |
140 | 147 | ||
141 | max = (max + 3) & ~3; | 148 | max = (max + 3) & ~3; |
@@ -148,6 +155,10 @@ static int keyring_duplicate(struct key *keyring, const struct key *source) | |||
148 | if (!klist) | 155 | if (!klist) |
149 | goto error; | 156 | goto error; |
150 | 157 | ||
158 | /* set links */ | ||
159 | rcu_read_lock(); | ||
160 | sklist = rcu_dereference(source->payload.subscriptions); | ||
161 | |||
151 | klist->maxkeys = max; | 162 | klist->maxkeys = max; |
152 | klist->nkeys = sklist->nkeys; | 163 | klist->nkeys = sklist->nkeys; |
153 | memcpy(klist->keys, | 164 | memcpy(klist->keys, |
@@ -157,7 +168,9 @@ static int keyring_duplicate(struct key *keyring, const struct key *source) | |||
157 | for (loop = klist->nkeys - 1; loop >= 0; loop--) | 168 | for (loop = klist->nkeys - 1; loop >= 0; loop--) |
158 | atomic_inc(&klist->keys[loop]->usage); | 169 | atomic_inc(&klist->keys[loop]->usage); |
159 | 170 | ||
160 | keyring->payload.subscriptions = klist; | 171 | rcu_read_unlock(); |
172 | |||
173 | rcu_assign_pointer(keyring->payload.subscriptions, klist); | ||
161 | ret = 0; | 174 | ret = 0; |
162 | } | 175 | } |
163 | 176 | ||
@@ -192,7 +205,7 @@ static void keyring_destroy(struct key *keyring) | |||
192 | write_unlock(&keyring_name_lock); | 205 | write_unlock(&keyring_name_lock); |
193 | } | 206 | } |
194 | 207 | ||
195 | klist = keyring->payload.subscriptions; | 208 | klist = rcu_dereference(keyring->payload.subscriptions); |
196 | if (klist) { | 209 | if (klist) { |
197 | for (loop = klist->nkeys - 1; loop >= 0; loop--) | 210 | for (loop = klist->nkeys - 1; loop >= 0; loop--) |
198 | key_put(klist->keys[loop]); | 211 | key_put(klist->keys[loop]); |
@@ -216,17 +229,20 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) | |||
216 | seq_puts(m, "[anon]"); | 229 | seq_puts(m, "[anon]"); |
217 | } | 230 | } |
218 | 231 | ||
219 | klist = keyring->payload.subscriptions; | 232 | rcu_read_lock(); |
233 | klist = rcu_dereference(keyring->payload.subscriptions); | ||
220 | if (klist) | 234 | if (klist) |
221 | seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); | 235 | seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); |
222 | else | 236 | else |
223 | seq_puts(m, ": empty"); | 237 | seq_puts(m, ": empty"); |
238 | rcu_read_unlock(); | ||
224 | 239 | ||
225 | } /* end keyring_describe() */ | 240 | } /* end keyring_describe() */ |
226 | 241 | ||
227 | /*****************************************************************************/ | 242 | /*****************************************************************************/ |
228 | /* | 243 | /* |
229 | * read a list of key IDs from the keyring's contents | 244 | * read a list of key IDs from the keyring's contents |
245 | * - the keyring's semaphore is read-locked | ||
230 | */ | 246 | */ |
231 | static long keyring_read(const struct key *keyring, | 247 | static long keyring_read(const struct key *keyring, |
232 | char __user *buffer, size_t buflen) | 248 | char __user *buffer, size_t buflen) |
@@ -237,7 +253,7 @@ static long keyring_read(const struct key *keyring, | |||
237 | int loop, ret; | 253 | int loop, ret; |
238 | 254 | ||
239 | ret = 0; | 255 | ret = 0; |
240 | klist = keyring->payload.subscriptions; | 256 | klist = rcu_dereference(keyring->payload.subscriptions); |
241 | 257 | ||
242 | if (klist) { | 258 | if (klist) { |
243 | /* calculate how much data we could return */ | 259 | /* calculate how much data we could return */ |
@@ -320,7 +336,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
320 | key_match_func_t match) | 336 | key_match_func_t match) |
321 | { | 337 | { |
322 | struct { | 338 | struct { |
323 | struct key *keyring; | 339 | struct keyring_list *keylist; |
324 | int kix; | 340 | int kix; |
325 | } stack[KEYRING_SEARCH_MAX_DEPTH]; | 341 | } stack[KEYRING_SEARCH_MAX_DEPTH]; |
326 | 342 | ||
@@ -328,10 +344,12 @@ struct key *keyring_search_aux(struct key *keyring, | |||
328 | struct timespec now; | 344 | struct timespec now; |
329 | struct key *key; | 345 | struct key *key; |
330 | long err; | 346 | long err; |
331 | int sp, psp, kix; | 347 | int sp, kix; |
332 | 348 | ||
333 | key_check(keyring); | 349 | key_check(keyring); |
334 | 350 | ||
351 | rcu_read_lock(); | ||
352 | |||
335 | /* top keyring must have search permission to begin the search */ | 353 | /* top keyring must have search permission to begin the search */ |
336 | key = ERR_PTR(-EACCES); | 354 | key = ERR_PTR(-EACCES); |
337 | if (!key_permission(keyring, KEY_SEARCH)) | 355 | if (!key_permission(keyring, KEY_SEARCH)) |
@@ -347,11 +365,10 @@ struct key *keyring_search_aux(struct key *keyring, | |||
347 | 365 | ||
348 | /* start processing a new keyring */ | 366 | /* start processing a new keyring */ |
349 | descend: | 367 | descend: |
350 | read_lock(&keyring->lock); | 368 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) |
351 | if (keyring->flags & KEY_FLAG_REVOKED) | ||
352 | goto not_this_keyring; | 369 | goto not_this_keyring; |
353 | 370 | ||
354 | keylist = keyring->payload.subscriptions; | 371 | keylist = rcu_dereference(keyring->payload.subscriptions); |
355 | if (!keylist) | 372 | if (!keylist) |
356 | goto not_this_keyring; | 373 | goto not_this_keyring; |
357 | 374 | ||
@@ -364,7 +381,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
364 | continue; | 381 | continue; |
365 | 382 | ||
366 | /* skip revoked keys and expired keys */ | 383 | /* skip revoked keys and expired keys */ |
367 | if (key->flags & KEY_FLAG_REVOKED) | 384 | if (test_bit(KEY_FLAG_REVOKED, &key->flags)) |
368 | continue; | 385 | continue; |
369 | 386 | ||
370 | if (key->expiry && now.tv_sec >= key->expiry) | 387 | if (key->expiry && now.tv_sec >= key->expiry) |
@@ -379,7 +396,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
379 | continue; | 396 | continue; |
380 | 397 | ||
381 | /* we set a different error code if we find a negative key */ | 398 | /* we set a different error code if we find a negative key */ |
382 | if (key->flags & KEY_FLAG_NEGATIVE) { | 399 | if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { |
383 | err = -ENOKEY; | 400 | err = -ENOKEY; |
384 | continue; | 401 | continue; |
385 | } | 402 | } |
@@ -390,48 +407,37 @@ struct key *keyring_search_aux(struct key *keyring, | |||
390 | /* search through the keyrings nested in this one */ | 407 | /* search through the keyrings nested in this one */ |
391 | kix = 0; | 408 | kix = 0; |
392 | ascend: | 409 | ascend: |
393 | while (kix < keylist->nkeys) { | 410 | for (; kix < keylist->nkeys; kix++) { |
394 | key = keylist->keys[kix]; | 411 | key = keylist->keys[kix]; |
395 | if (key->type != &key_type_keyring) | 412 | if (key->type != &key_type_keyring) |
396 | goto next; | 413 | continue; |
397 | 414 | ||
398 | /* recursively search nested keyrings | 415 | /* recursively search nested keyrings |
399 | * - only search keyrings for which we have search permission | 416 | * - only search keyrings for which we have search permission |
400 | */ | 417 | */ |
401 | if (sp >= KEYRING_SEARCH_MAX_DEPTH) | 418 | if (sp >= KEYRING_SEARCH_MAX_DEPTH) |
402 | goto next; | 419 | continue; |
403 | 420 | ||
404 | if (!key_permission(key, KEY_SEARCH)) | 421 | if (!key_permission(key, KEY_SEARCH)) |
405 | goto next; | 422 | continue; |
406 | |||
407 | /* evade loops in the keyring tree */ | ||
408 | for (psp = 0; psp < sp; psp++) | ||
409 | if (stack[psp].keyring == keyring) | ||
410 | goto next; | ||
411 | 423 | ||
412 | /* stack the current position */ | 424 | /* stack the current position */ |
413 | stack[sp].keyring = keyring; | 425 | stack[sp].keylist = keylist; |
414 | stack[sp].kix = kix; | 426 | stack[sp].kix = kix; |
415 | sp++; | 427 | sp++; |
416 | 428 | ||
417 | /* begin again with the new keyring */ | 429 | /* begin again with the new keyring */ |
418 | keyring = key; | 430 | keyring = key; |
419 | goto descend; | 431 | goto descend; |
420 | |||
421 | next: | ||
422 | kix++; | ||
423 | } | 432 | } |
424 | 433 | ||
425 | /* the keyring we're looking at was disqualified or didn't contain a | 434 | /* the keyring we're looking at was disqualified or didn't contain a |
426 | * matching key */ | 435 | * matching key */ |
427 | not_this_keyring: | 436 | not_this_keyring: |
428 | read_unlock(&keyring->lock); | ||
429 | |||
430 | if (sp > 0) { | 437 | if (sp > 0) { |
431 | /* resume the processing of a keyring higher up in the tree */ | 438 | /* resume the processing of a keyring higher up in the tree */ |
432 | sp--; | 439 | sp--; |
433 | keyring = stack[sp].keyring; | 440 | keylist = stack[sp].keylist; |
434 | keylist = keyring->payload.subscriptions; | ||
435 | kix = stack[sp].kix + 1; | 441 | kix = stack[sp].kix + 1; |
436 | goto ascend; | 442 | goto ascend; |
437 | } | 443 | } |
@@ -442,16 +448,9 @@ struct key *keyring_search_aux(struct key *keyring, | |||
442 | /* we found a viable match */ | 448 | /* we found a viable match */ |
443 | found: | 449 | found: |
444 | atomic_inc(&key->usage); | 450 | atomic_inc(&key->usage); |
445 | read_unlock(&keyring->lock); | ||
446 | |||
447 | /* unwind the keyring stack */ | ||
448 | while (sp > 0) { | ||
449 | sp--; | ||
450 | read_unlock(&stack[sp].keyring->lock); | ||
451 | } | ||
452 | |||
453 | key_check(key); | 451 | key_check(key); |
454 | error: | 452 | error: |
453 | rcu_read_unlock(); | ||
455 | return key; | 454 | return key; |
456 | 455 | ||
457 | } /* end keyring_search_aux() */ | 456 | } /* end keyring_search_aux() */ |
@@ -489,7 +488,9 @@ struct key *__keyring_search_one(struct key *keyring, | |||
489 | struct key *key; | 488 | struct key *key; |
490 | int loop; | 489 | int loop; |
491 | 490 | ||
492 | klist = keyring->payload.subscriptions; | 491 | rcu_read_lock(); |
492 | |||
493 | klist = rcu_dereference(keyring->payload.subscriptions); | ||
493 | if (klist) { | 494 | if (klist) { |
494 | for (loop = 0; loop < klist->nkeys; loop++) { | 495 | for (loop = 0; loop < klist->nkeys; loop++) { |
495 | key = klist->keys[loop]; | 496 | key = klist->keys[loop]; |
@@ -497,7 +498,7 @@ struct key *__keyring_search_one(struct key *keyring, | |||
497 | if (key->type == ktype && | 498 | if (key->type == ktype && |
498 | key->type->match(key, description) && | 499 | key->type->match(key, description) && |
499 | key_permission(key, perm) && | 500 | key_permission(key, perm) && |
500 | !(key->flags & KEY_FLAG_REVOKED) | 501 | !test_bit(KEY_FLAG_REVOKED, &key->flags) |
501 | ) | 502 | ) |
502 | goto found; | 503 | goto found; |
503 | } | 504 | } |
@@ -509,6 +510,7 @@ struct key *__keyring_search_one(struct key *keyring, | |||
509 | found: | 510 | found: |
510 | atomic_inc(&key->usage); | 511 | atomic_inc(&key->usage); |
511 | error: | 512 | error: |
513 | rcu_read_unlock(); | ||
512 | return key; | 514 | return key; |
513 | 515 | ||
514 | } /* end __keyring_search_one() */ | 516 | } /* end __keyring_search_one() */ |
@@ -540,7 +542,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound) | |||
540 | &keyring_name_hash[bucket], | 542 | &keyring_name_hash[bucket], |
541 | type_data.link | 543 | type_data.link |
542 | ) { | 544 | ) { |
543 | if (keyring->flags & KEY_FLAG_REVOKED) | 545 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) |
544 | continue; | 546 | continue; |
545 | 547 | ||
546 | if (strcmp(keyring->description, name) != 0) | 548 | if (strcmp(keyring->description, name) != 0) |
@@ -579,7 +581,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound) | |||
579 | static int keyring_detect_cycle(struct key *A, struct key *B) | 581 | static int keyring_detect_cycle(struct key *A, struct key *B) |
580 | { | 582 | { |
581 | struct { | 583 | struct { |
582 | struct key *subtree; | 584 | struct keyring_list *keylist; |
583 | int kix; | 585 | int kix; |
584 | } stack[KEYRING_SEARCH_MAX_DEPTH]; | 586 | } stack[KEYRING_SEARCH_MAX_DEPTH]; |
585 | 587 | ||
@@ -587,20 +589,21 @@ static int keyring_detect_cycle(struct key *A, struct key *B) | |||
587 | struct key *subtree, *key; | 589 | struct key *subtree, *key; |
588 | int sp, kix, ret; | 590 | int sp, kix, ret; |
589 | 591 | ||
592 | rcu_read_lock(); | ||
593 | |||
590 | ret = -EDEADLK; | 594 | ret = -EDEADLK; |
591 | if (A == B) | 595 | if (A == B) |
592 | goto error; | 596 | goto cycle_detected; |
593 | 597 | ||
594 | subtree = B; | 598 | subtree = B; |
595 | sp = 0; | 599 | sp = 0; |
596 | 600 | ||
597 | /* start processing a new keyring */ | 601 | /* start processing a new keyring */ |
598 | descend: | 602 | descend: |
599 | read_lock(&subtree->lock); | 603 | if (test_bit(KEY_FLAG_REVOKED, &subtree->flags)) |
600 | if (subtree->flags & KEY_FLAG_REVOKED) | ||
601 | goto not_this_keyring; | 604 | goto not_this_keyring; |
602 | 605 | ||
603 | keylist = subtree->payload.subscriptions; | 606 | keylist = rcu_dereference(subtree->payload.subscriptions); |
604 | if (!keylist) | 607 | if (!keylist) |
605 | goto not_this_keyring; | 608 | goto not_this_keyring; |
606 | kix = 0; | 609 | kix = 0; |
@@ -619,7 +622,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B) | |||
619 | goto too_deep; | 622 | goto too_deep; |
620 | 623 | ||
621 | /* stack the current position */ | 624 | /* stack the current position */ |
622 | stack[sp].subtree = subtree; | 625 | stack[sp].keylist = keylist; |
623 | stack[sp].kix = kix; | 626 | stack[sp].kix = kix; |
624 | sp++; | 627 | sp++; |
625 | 628 | ||
@@ -632,13 +635,10 @@ static int keyring_detect_cycle(struct key *A, struct key *B) | |||
632 | /* the keyring we're looking at was disqualified or didn't contain a | 635 | /* the keyring we're looking at was disqualified or didn't contain a |
633 | * matching key */ | 636 | * matching key */ |
634 | not_this_keyring: | 637 | not_this_keyring: |
635 | read_unlock(&subtree->lock); | ||
636 | |||
637 | if (sp > 0) { | 638 | if (sp > 0) { |
638 | /* resume the checking of a keyring higher up in the tree */ | 639 | /* resume the checking of a keyring higher up in the tree */ |
639 | sp--; | 640 | sp--; |
640 | subtree = stack[sp].subtree; | 641 | keylist = stack[sp].keylist; |
641 | keylist = subtree->payload.subscriptions; | ||
642 | kix = stack[sp].kix + 1; | 642 | kix = stack[sp].kix + 1; |
643 | goto ascend; | 643 | goto ascend; |
644 | } | 644 | } |
@@ -646,30 +646,36 @@ static int keyring_detect_cycle(struct key *A, struct key *B) | |||
646 | ret = 0; /* no cycles detected */ | 646 | ret = 0; /* no cycles detected */ |
647 | 647 | ||
648 | error: | 648 | error: |
649 | rcu_read_unlock(); | ||
649 | return ret; | 650 | return ret; |
650 | 651 | ||
651 | too_deep: | 652 | too_deep: |
652 | ret = -ELOOP; | 653 | ret = -ELOOP; |
653 | goto error_unwind; | 654 | goto error; |
655 | |||
654 | cycle_detected: | 656 | cycle_detected: |
655 | ret = -EDEADLK; | 657 | ret = -EDEADLK; |
656 | error_unwind: | ||
657 | read_unlock(&subtree->lock); | ||
658 | |||
659 | /* unwind the keyring stack */ | ||
660 | while (sp > 0) { | ||
661 | sp--; | ||
662 | read_unlock(&stack[sp].subtree->lock); | ||
663 | } | ||
664 | |||
665 | goto error; | 658 | goto error; |
666 | 659 | ||
667 | } /* end keyring_detect_cycle() */ | 660 | } /* end keyring_detect_cycle() */ |
668 | 661 | ||
669 | /*****************************************************************************/ | 662 | /*****************************************************************************/ |
670 | /* | 663 | /* |
664 | * dispose of a keyring list after the RCU grace period | ||
665 | */ | ||
666 | static void keyring_link_rcu_disposal(struct rcu_head *rcu) | ||
667 | { | ||
668 | struct keyring_list *klist = | ||
669 | container_of(rcu, struct keyring_list, rcu); | ||
670 | |||
671 | kfree(klist); | ||
672 | |||
673 | } /* end keyring_link_rcu_disposal() */ | ||
674 | |||
675 | /*****************************************************************************/ | ||
676 | /* | ||
671 | * link a key into to a keyring | 677 | * link a key into to a keyring |
672 | * - must be called with the keyring's semaphore held | 678 | * - must be called with the keyring's semaphore write-locked |
673 | */ | 679 | */ |
674 | int __key_link(struct key *keyring, struct key *key) | 680 | int __key_link(struct key *keyring, struct key *key) |
675 | { | 681 | { |
@@ -679,7 +685,7 @@ int __key_link(struct key *keyring, struct key *key) | |||
679 | int ret; | 685 | int ret; |
680 | 686 | ||
681 | ret = -EKEYREVOKED; | 687 | ret = -EKEYREVOKED; |
682 | if (keyring->flags & KEY_FLAG_REVOKED) | 688 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) |
683 | goto error; | 689 | goto error; |
684 | 690 | ||
685 | ret = -ENOTDIR; | 691 | ret = -ENOTDIR; |
@@ -710,9 +716,10 @@ int __key_link(struct key *keyring, struct key *key) | |||
710 | /* there's sufficient slack space to add directly */ | 716 | /* there's sufficient slack space to add directly */ |
711 | atomic_inc(&key->usage); | 717 | atomic_inc(&key->usage); |
712 | 718 | ||
713 | write_lock(&keyring->lock); | 719 | klist->keys[klist->nkeys] = key; |
714 | klist->keys[klist->nkeys++] = key; | 720 | smp_wmb(); |
715 | write_unlock(&keyring->lock); | 721 | klist->nkeys++; |
722 | smp_wmb(); | ||
716 | 723 | ||
717 | ret = 0; | 724 | ret = 0; |
718 | } | 725 | } |
@@ -723,6 +730,8 @@ int __key_link(struct key *keyring, struct key *key) | |||
723 | max += klist->maxkeys; | 730 | max += klist->maxkeys; |
724 | 731 | ||
725 | ret = -ENFILE; | 732 | ret = -ENFILE; |
733 | if (max > 65535) | ||
734 | goto error3; | ||
726 | size = sizeof(*klist) + sizeof(*key) * max; | 735 | size = sizeof(*klist) + sizeof(*key) * max; |
727 | if (size > PAGE_SIZE) | 736 | if (size > PAGE_SIZE) |
728 | goto error3; | 737 | goto error3; |
@@ -743,14 +752,13 @@ int __key_link(struct key *keyring, struct key *key) | |||
743 | 752 | ||
744 | /* add the key into the new space */ | 753 | /* add the key into the new space */ |
745 | atomic_inc(&key->usage); | 754 | atomic_inc(&key->usage); |
746 | |||
747 | write_lock(&keyring->lock); | ||
748 | keyring->payload.subscriptions = nklist; | ||
749 | nklist->keys[nklist->nkeys++] = key; | 755 | nklist->keys[nklist->nkeys++] = key; |
750 | write_unlock(&keyring->lock); | 756 | |
757 | rcu_assign_pointer(keyring->payload.subscriptions, nklist); | ||
751 | 758 | ||
752 | /* dispose of the old keyring list */ | 759 | /* dispose of the old keyring list */ |
753 | kfree(klist); | 760 | if (klist) |
761 | call_rcu(&klist->rcu, keyring_link_rcu_disposal); | ||
754 | 762 | ||
755 | ret = 0; | 763 | ret = 0; |
756 | } | 764 | } |
@@ -791,11 +799,26 @@ EXPORT_SYMBOL(key_link); | |||
791 | 799 | ||
792 | /*****************************************************************************/ | 800 | /*****************************************************************************/ |
793 | /* | 801 | /* |
802 | * dispose of a keyring list after the RCU grace period, freeing the unlinked | ||
803 | * key | ||
804 | */ | ||
805 | static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) | ||
806 | { | ||
807 | struct keyring_list *klist = | ||
808 | container_of(rcu, struct keyring_list, rcu); | ||
809 | |||
810 | key_put(klist->keys[klist->delkey]); | ||
811 | kfree(klist); | ||
812 | |||
813 | } /* end keyring_unlink_rcu_disposal() */ | ||
814 | |||
815 | /*****************************************************************************/ | ||
816 | /* | ||
794 | * unlink the first link to a key from a keyring | 817 | * unlink the first link to a key from a keyring |
795 | */ | 818 | */ |
796 | int key_unlink(struct key *keyring, struct key *key) | 819 | int key_unlink(struct key *keyring, struct key *key) |
797 | { | 820 | { |
798 | struct keyring_list *klist; | 821 | struct keyring_list *klist, *nklist; |
799 | int loop, ret; | 822 | int loop, ret; |
800 | 823 | ||
801 | key_check(keyring); | 824 | key_check(keyring); |
@@ -819,31 +842,45 @@ int key_unlink(struct key *keyring, struct key *key) | |||
819 | ret = -ENOENT; | 842 | ret = -ENOENT; |
820 | goto error; | 843 | goto error; |
821 | 844 | ||
822 | key_is_present: | 845 | key_is_present: |
846 | /* we need to copy the key list for RCU purposes */ | ||
847 | nklist = kmalloc(sizeof(*klist) + sizeof(*key) * klist->maxkeys, | ||
848 | GFP_KERNEL); | ||
849 | if (!nklist) | ||
850 | goto nomem; | ||
851 | nklist->maxkeys = klist->maxkeys; | ||
852 | nklist->nkeys = klist->nkeys - 1; | ||
853 | |||
854 | if (loop > 0) | ||
855 | memcpy(&nklist->keys[0], | ||
856 | &klist->keys[0], | ||
857 | loop * sizeof(klist->keys[0])); | ||
858 | |||
859 | if (loop < nklist->nkeys) | ||
860 | memcpy(&nklist->keys[loop], | ||
861 | &klist->keys[loop + 1], | ||
862 | (nklist->nkeys - loop) * sizeof(klist->keys[0])); | ||
863 | |||
823 | /* adjust the user's quota */ | 864 | /* adjust the user's quota */ |
824 | key_payload_reserve(keyring, | 865 | key_payload_reserve(keyring, |
825 | keyring->datalen - KEYQUOTA_LINK_BYTES); | 866 | keyring->datalen - KEYQUOTA_LINK_BYTES); |
826 | 867 | ||
827 | /* shuffle down the key pointers | 868 | rcu_assign_pointer(keyring->payload.subscriptions, nklist); |
828 | * - it might be worth shrinking the allocated memory, but that runs | ||
829 | * the risk of ENOMEM as we would have to copy | ||
830 | */ | ||
831 | write_lock(&keyring->lock); | ||
832 | 869 | ||
833 | klist->nkeys--; | 870 | up_write(&keyring->sem); |
834 | if (loop < klist->nkeys) | ||
835 | memcpy(&klist->keys[loop], | ||
836 | &klist->keys[loop + 1], | ||
837 | (klist->nkeys - loop) * sizeof(struct key *)); | ||
838 | 871 | ||
839 | write_unlock(&keyring->lock); | 872 | /* schedule for later cleanup */ |
873 | klist->delkey = loop; | ||
874 | call_rcu(&klist->rcu, keyring_unlink_rcu_disposal); | ||
840 | 875 | ||
841 | up_write(&keyring->sem); | ||
842 | key_put(key); | ||
843 | ret = 0; | 876 | ret = 0; |
844 | 877 | ||
845 | error: | 878 | error: |
846 | return ret; | 879 | return ret; |
880 | nomem: | ||
881 | ret = -ENOMEM; | ||
882 | up_write(&keyring->sem); | ||
883 | goto error; | ||
847 | 884 | ||
848 | } /* end key_unlink() */ | 885 | } /* end key_unlink() */ |
849 | 886 | ||
@@ -851,13 +888,32 @@ EXPORT_SYMBOL(key_unlink); | |||
851 | 888 | ||
852 | /*****************************************************************************/ | 889 | /*****************************************************************************/ |
853 | /* | 890 | /* |
891 | * dispose of a keyring list after the RCU grace period, releasing the keys it | ||
892 | * links to | ||
893 | */ | ||
894 | static void keyring_clear_rcu_disposal(struct rcu_head *rcu) | ||
895 | { | ||
896 | struct keyring_list *klist; | ||
897 | int loop; | ||
898 | |||
899 | klist = container_of(rcu, struct keyring_list, rcu); | ||
900 | |||
901 | for (loop = klist->nkeys - 1; loop >= 0; loop--) | ||
902 | key_put(klist->keys[loop]); | ||
903 | |||
904 | kfree(klist); | ||
905 | |||
906 | } /* end keyring_clear_rcu_disposal() */ | ||
907 | |||
908 | /*****************************************************************************/ | ||
909 | /* | ||
854 | * clear the specified process keyring | 910 | * clear the specified process keyring |
855 | * - implements keyctl(KEYCTL_CLEAR) | 911 | * - implements keyctl(KEYCTL_CLEAR) |
856 | */ | 912 | */ |
857 | int keyring_clear(struct key *keyring) | 913 | int keyring_clear(struct key *keyring) |
858 | { | 914 | { |
859 | struct keyring_list *klist; | 915 | struct keyring_list *klist; |
860 | int loop, ret; | 916 | int ret; |
861 | 917 | ||
862 | ret = -ENOTDIR; | 918 | ret = -ENOTDIR; |
863 | if (keyring->type == &key_type_keyring) { | 919 | if (keyring->type == &key_type_keyring) { |
@@ -870,20 +926,15 @@ int keyring_clear(struct key *keyring) | |||
870 | key_payload_reserve(keyring, | 926 | key_payload_reserve(keyring, |
871 | sizeof(struct keyring_list)); | 927 | sizeof(struct keyring_list)); |
872 | 928 | ||
873 | write_lock(&keyring->lock); | 929 | rcu_assign_pointer(keyring->payload.subscriptions, |
874 | keyring->payload.subscriptions = NULL; | 930 | NULL); |
875 | write_unlock(&keyring->lock); | ||
876 | } | 931 | } |
877 | 932 | ||
878 | up_write(&keyring->sem); | 933 | up_write(&keyring->sem); |
879 | 934 | ||
880 | /* free the keys after the locks have been dropped */ | 935 | /* free the keys after the locks have been dropped */ |
881 | if (klist) { | 936 | if (klist) |
882 | for (loop = klist->nkeys - 1; loop >= 0; loop--) | 937 | call_rcu(&klist->rcu, keyring_clear_rcu_disposal); |
883 | key_put(klist->keys[loop]); | ||
884 | |||
885 | kfree(klist); | ||
886 | } | ||
887 | 938 | ||
888 | ret = 0; | 939 | ret = 0; |
889 | } | 940 | } |
diff --git a/security/keys/proc.c b/security/keys/proc.c index 91343b85c39c..c55cf1fd0826 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
@@ -140,7 +140,7 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
140 | 140 | ||
141 | now = current_kernel_time(); | 141 | now = current_kernel_time(); |
142 | 142 | ||
143 | read_lock(&key->lock); | 143 | rcu_read_lock(); |
144 | 144 | ||
145 | /* come up with a suitable timeout value */ | 145 | /* come up with a suitable timeout value */ |
146 | if (key->expiry == 0) { | 146 | if (key->expiry == 0) { |
@@ -164,14 +164,17 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
164 | sprintf(xbuf, "%luw", timo / (60*60*24*7)); | 164 | sprintf(xbuf, "%luw", timo / (60*60*24*7)); |
165 | } | 165 | } |
166 | 166 | ||
167 | #define showflag(KEY, LETTER, FLAG) \ | ||
168 | (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') | ||
169 | |||
167 | seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ", | 170 | seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ", |
168 | key->serial, | 171 | key->serial, |
169 | key->flags & KEY_FLAG_INSTANTIATED ? 'I' : '-', | 172 | showflag(key, 'I', KEY_FLAG_INSTANTIATED), |
170 | key->flags & KEY_FLAG_REVOKED ? 'R' : '-', | 173 | showflag(key, 'R', KEY_FLAG_REVOKED), |
171 | key->flags & KEY_FLAG_DEAD ? 'D' : '-', | 174 | showflag(key, 'D', KEY_FLAG_DEAD), |
172 | key->flags & KEY_FLAG_IN_QUOTA ? 'Q' : '-', | 175 | showflag(key, 'Q', KEY_FLAG_IN_QUOTA), |
173 | key->flags & KEY_FLAG_USER_CONSTRUCT ? 'U' : '-', | 176 | showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), |
174 | key->flags & KEY_FLAG_NEGATIVE ? 'N' : '-', | 177 | showflag(key, 'N', KEY_FLAG_NEGATIVE), |
175 | atomic_read(&key->usage), | 178 | atomic_read(&key->usage), |
176 | xbuf, | 179 | xbuf, |
177 | key->perm, | 180 | key->perm, |
@@ -179,11 +182,13 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
179 | key->gid, | 182 | key->gid, |
180 | key->type->name); | 183 | key->type->name); |
181 | 184 | ||
185 | #undef showflag | ||
186 | |||
182 | if (key->type->describe) | 187 | if (key->type->describe) |
183 | key->type->describe(key, m); | 188 | key->type->describe(key, m); |
184 | seq_putc(m, '\n'); | 189 | seq_putc(m, '\n'); |
185 | 190 | ||
186 | read_unlock(&key->lock); | 191 | rcu_read_unlock(); |
187 | 192 | ||
188 | return 0; | 193 | return 0; |
189 | 194 | ||
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 2eb0e471cd40..059c350cac46 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -38,10 +38,9 @@ struct key root_user_keyring = { | |||
38 | .serial = 2, | 38 | .serial = 2, |
39 | .type = &key_type_keyring, | 39 | .type = &key_type_keyring, |
40 | .user = &root_key_user, | 40 | .user = &root_key_user, |
41 | .lock = RW_LOCK_UNLOCKED, | ||
42 | .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), | 41 | .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), |
43 | .perm = KEY_USR_ALL, | 42 | .perm = KEY_USR_ALL, |
44 | .flags = KEY_FLAG_INSTANTIATED, | 43 | .flags = 1 << KEY_FLAG_INSTANTIATED, |
45 | .description = "_uid.0", | 44 | .description = "_uid.0", |
46 | #ifdef KEY_DEBUGGING | 45 | #ifdef KEY_DEBUGGING |
47 | .magic = KEY_DEBUG_MAGIC, | 46 | .magic = KEY_DEBUG_MAGIC, |
@@ -54,10 +53,9 @@ struct key root_session_keyring = { | |||
54 | .serial = 1, | 53 | .serial = 1, |
55 | .type = &key_type_keyring, | 54 | .type = &key_type_keyring, |
56 | .user = &root_key_user, | 55 | .user = &root_key_user, |
57 | .lock = RW_LOCK_UNLOCKED, | ||
58 | .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), | 56 | .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), |
59 | .perm = KEY_USR_ALL, | 57 | .perm = KEY_USR_ALL, |
60 | .flags = KEY_FLAG_INSTANTIATED, | 58 | .flags = 1 << KEY_FLAG_INSTANTIATED, |
61 | .description = "_uid_ses.0", | 59 | .description = "_uid_ses.0", |
62 | #ifdef KEY_DEBUGGING | 60 | #ifdef KEY_DEBUGGING |
63 | .magic = KEY_DEBUG_MAGIC, | 61 | .magic = KEY_DEBUG_MAGIC, |
@@ -349,9 +347,7 @@ void key_fsuid_changed(struct task_struct *tsk) | |||
349 | /* update the ownership of the thread keyring */ | 347 | /* update the ownership of the thread keyring */ |
350 | if (tsk->thread_keyring) { | 348 | if (tsk->thread_keyring) { |
351 | down_write(&tsk->thread_keyring->sem); | 349 | down_write(&tsk->thread_keyring->sem); |
352 | write_lock(&tsk->thread_keyring->lock); | ||
353 | tsk->thread_keyring->uid = tsk->fsuid; | 350 | tsk->thread_keyring->uid = tsk->fsuid; |
354 | write_unlock(&tsk->thread_keyring->lock); | ||
355 | up_write(&tsk->thread_keyring->sem); | 351 | up_write(&tsk->thread_keyring->sem); |
356 | } | 352 | } |
357 | 353 | ||
@@ -366,9 +362,7 @@ void key_fsgid_changed(struct task_struct *tsk) | |||
366 | /* update the ownership of the thread keyring */ | 362 | /* update the ownership of the thread keyring */ |
367 | if (tsk->thread_keyring) { | 363 | if (tsk->thread_keyring) { |
368 | down_write(&tsk->thread_keyring->sem); | 364 | down_write(&tsk->thread_keyring->sem); |
369 | write_lock(&tsk->thread_keyring->lock); | ||
370 | tsk->thread_keyring->gid = tsk->fsgid; | 365 | tsk->thread_keyring->gid = tsk->fsgid; |
371 | write_unlock(&tsk->thread_keyring->lock); | ||
372 | up_write(&tsk->thread_keyring->sem); | 366 | up_write(&tsk->thread_keyring->sem); |
373 | } | 367 | } |
374 | 368 | ||
@@ -588,7 +582,7 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial, | |||
588 | } | 582 | } |
589 | 583 | ||
590 | ret = -EIO; | 584 | ret = -EIO; |
591 | if (!partial && !(key->flags & KEY_FLAG_INSTANTIATED)) | 585 | if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) |
592 | goto invalid_key; | 586 | goto invalid_key; |
593 | 587 | ||
594 | ret = -EACCES; | 588 | ret = -EACCES; |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 9705b1aeba5d..1f6c0940297f 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -105,7 +105,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
105 | struct key_construction cons; | 105 | struct key_construction cons; |
106 | struct timespec now; | 106 | struct timespec now; |
107 | struct key *key; | 107 | struct key *key; |
108 | int ret, negative; | 108 | int ret, negated; |
109 | 109 | ||
110 | /* create a key and add it to the queue */ | 110 | /* create a key and add it to the queue */ |
111 | key = key_alloc(type, description, | 111 | key = key_alloc(type, description, |
@@ -113,9 +113,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
113 | if (IS_ERR(key)) | 113 | if (IS_ERR(key)) |
114 | goto alloc_failed; | 114 | goto alloc_failed; |
115 | 115 | ||
116 | write_lock(&key->lock); | 116 | set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); |
117 | key->flags |= KEY_FLAG_USER_CONSTRUCT; | ||
118 | write_unlock(&key->lock); | ||
119 | 117 | ||
120 | cons.key = key; | 118 | cons.key = key; |
121 | list_add_tail(&cons.link, &key->user->consq); | 119 | list_add_tail(&cons.link, &key->user->consq); |
@@ -130,7 +128,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
130 | 128 | ||
131 | /* if the key wasn't instantiated, then we want to give an error */ | 129 | /* if the key wasn't instantiated, then we want to give an error */ |
132 | ret = -ENOKEY; | 130 | ret = -ENOKEY; |
133 | if (!(key->flags & KEY_FLAG_INSTANTIATED)) | 131 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) |
134 | goto request_failed; | 132 | goto request_failed; |
135 | 133 | ||
136 | down_write(&key_construction_sem); | 134 | down_write(&key_construction_sem); |
@@ -139,7 +137,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
139 | 137 | ||
140 | /* also give an error if the key was negatively instantiated */ | 138 | /* also give an error if the key was negatively instantiated */ |
141 | check_not_negative: | 139 | check_not_negative: |
142 | if (key->flags & KEY_FLAG_NEGATIVE) { | 140 | if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { |
143 | key_put(key); | 141 | key_put(key); |
144 | key = ERR_PTR(-ENOKEY); | 142 | key = ERR_PTR(-ENOKEY); |
145 | } | 143 | } |
@@ -152,24 +150,23 @@ static struct key *__request_key_construction(struct key_type *type, | |||
152 | * - remove from construction queue | 150 | * - remove from construction queue |
153 | * - mark the key as dead | 151 | * - mark the key as dead |
154 | */ | 152 | */ |
155 | negative = 0; | 153 | negated = 0; |
156 | down_write(&key_construction_sem); | 154 | down_write(&key_construction_sem); |
157 | 155 | ||
158 | list_del(&cons.link); | 156 | list_del(&cons.link); |
159 | 157 | ||
160 | write_lock(&key->lock); | ||
161 | key->flags &= ~KEY_FLAG_USER_CONSTRUCT; | ||
162 | |||
163 | /* check it didn't get instantiated between the check and the down */ | 158 | /* check it didn't get instantiated between the check and the down */ |
164 | if (!(key->flags & KEY_FLAG_INSTANTIATED)) { | 159 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { |
165 | key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE; | 160 | set_bit(KEY_FLAG_NEGATIVE, &key->flags); |
166 | negative = 1; | 161 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); |
162 | negated = 1; | ||
167 | } | 163 | } |
168 | 164 | ||
169 | write_unlock(&key->lock); | 165 | clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); |
166 | |||
170 | up_write(&key_construction_sem); | 167 | up_write(&key_construction_sem); |
171 | 168 | ||
172 | if (!negative) | 169 | if (!negated) |
173 | goto check_not_negative; /* surprisingly, the key got | 170 | goto check_not_negative; /* surprisingly, the key got |
174 | * instantiated */ | 171 | * instantiated */ |
175 | 172 | ||
@@ -250,7 +247,7 @@ static struct key *request_key_construction(struct key_type *type, | |||
250 | 247 | ||
251 | for (;;) { | 248 | for (;;) { |
252 | set_current_state(TASK_UNINTERRUPTIBLE); | 249 | set_current_state(TASK_UNINTERRUPTIBLE); |
253 | if (!(ckey->flags & KEY_FLAG_USER_CONSTRUCT)) | 250 | if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags)) |
254 | break; | 251 | break; |
255 | schedule(); | 252 | schedule(); |
256 | } | 253 | } |
@@ -339,7 +336,8 @@ int key_validate(struct key *key) | |||
339 | if (key) { | 336 | if (key) { |
340 | /* check it's still accessible */ | 337 | /* check it's still accessible */ |
341 | ret = -EKEYREVOKED; | 338 | ret = -EKEYREVOKED; |
342 | if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD)) | 339 | if (test_bit(KEY_FLAG_REVOKED, &key->flags) || |
340 | test_bit(KEY_FLAG_DEAD, &key->flags)) | ||
343 | goto error; | 341 | goto error; |
344 | 342 | ||
345 | /* check it hasn't expired */ | 343 | /* check it hasn't expired */ |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index 8d65b3a28129..c33d3614a0db 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c | |||
@@ -42,12 +42,19 @@ struct key_type key_type_user = { | |||
42 | .read = user_read, | 42 | .read = user_read, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct user_key_payload { | ||
46 | struct rcu_head rcu; /* RCU destructor */ | ||
47 | unsigned short datalen; /* length of this data */ | ||
48 | char data[0]; /* actual data */ | ||
49 | }; | ||
50 | |||
45 | /*****************************************************************************/ | 51 | /*****************************************************************************/ |
46 | /* | 52 | /* |
47 | * instantiate a user defined key | 53 | * instantiate a user defined key |
48 | */ | 54 | */ |
49 | static int user_instantiate(struct key *key, const void *data, size_t datalen) | 55 | static int user_instantiate(struct key *key, const void *data, size_t datalen) |
50 | { | 56 | { |
57 | struct user_key_payload *upayload; | ||
51 | int ret; | 58 | int ret; |
52 | 59 | ||
53 | ret = -EINVAL; | 60 | ret = -EINVAL; |
@@ -58,13 +65,15 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen) | |||
58 | if (ret < 0) | 65 | if (ret < 0) |
59 | goto error; | 66 | goto error; |
60 | 67 | ||
61 | /* attach the data */ | ||
62 | ret = -ENOMEM; | 68 | ret = -ENOMEM; |
63 | key->payload.data = kmalloc(datalen, GFP_KERNEL); | 69 | upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); |
64 | if (!key->payload.data) | 70 | if (!upayload) |
65 | goto error; | 71 | goto error; |
66 | 72 | ||
67 | memcpy(key->payload.data, data, datalen); | 73 | /* attach the data */ |
74 | upayload->datalen = datalen; | ||
75 | memcpy(upayload->data, data, datalen); | ||
76 | rcu_assign_pointer(key->payload.data, upayload); | ||
68 | ret = 0; | 77 | ret = 0; |
69 | 78 | ||
70 | error: | 79 | error: |
@@ -75,18 +84,25 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen) | |||
75 | /*****************************************************************************/ | 84 | /*****************************************************************************/ |
76 | /* | 85 | /* |
77 | * duplicate a user defined key | 86 | * duplicate a user defined key |
87 | * - both keys' semaphores are locked against further modification | ||
88 | * - the new key cannot yet be accessed | ||
78 | */ | 89 | */ |
79 | static int user_duplicate(struct key *key, const struct key *source) | 90 | static int user_duplicate(struct key *key, const struct key *source) |
80 | { | 91 | { |
92 | struct user_key_payload *upayload, *spayload; | ||
81 | int ret; | 93 | int ret; |
82 | 94 | ||
83 | /* just copy the payload */ | 95 | /* just copy the payload */ |
84 | ret = -ENOMEM; | 96 | ret = -ENOMEM; |
85 | key->payload.data = kmalloc(source->datalen, GFP_KERNEL); | 97 | upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL); |
98 | if (upayload) { | ||
99 | spayload = rcu_dereference(source->payload.data); | ||
100 | BUG_ON(source->datalen != spayload->datalen); | ||
86 | 101 | ||
87 | if (key->payload.data) { | 102 | upayload->datalen = key->datalen = spayload->datalen; |
88 | key->datalen = source->datalen; | 103 | memcpy(upayload->data, spayload->data, key->datalen); |
89 | memcpy(key->payload.data, source->payload.data, source->datalen); | 104 | |
105 | key->payload.data = upayload; | ||
90 | ret = 0; | 106 | ret = 0; |
91 | } | 107 | } |
92 | 108 | ||
@@ -96,40 +112,54 @@ static int user_duplicate(struct key *key, const struct key *source) | |||
96 | 112 | ||
97 | /*****************************************************************************/ | 113 | /*****************************************************************************/ |
98 | /* | 114 | /* |
115 | * dispose of the old data from an updated user defined key | ||
116 | */ | ||
117 | static void user_update_rcu_disposal(struct rcu_head *rcu) | ||
118 | { | ||
119 | struct user_key_payload *upayload; | ||
120 | |||
121 | upayload = container_of(rcu, struct user_key_payload, rcu); | ||
122 | |||
123 | kfree(upayload); | ||
124 | |||
125 | } /* end user_update_rcu_disposal() */ | ||
126 | |||
127 | /*****************************************************************************/ | ||
128 | /* | ||
99 | * update a user defined key | 129 | * update a user defined key |
130 | * - the key's semaphore is write-locked | ||
100 | */ | 131 | */ |
101 | static int user_update(struct key *key, const void *data, size_t datalen) | 132 | static int user_update(struct key *key, const void *data, size_t datalen) |
102 | { | 133 | { |
103 | void *new, *zap; | 134 | struct user_key_payload *upayload, *zap; |
104 | int ret; | 135 | int ret; |
105 | 136 | ||
106 | ret = -EINVAL; | 137 | ret = -EINVAL; |
107 | if (datalen <= 0 || datalen > 32767 || !data) | 138 | if (datalen <= 0 || datalen > 32767 || !data) |
108 | goto error; | 139 | goto error; |
109 | 140 | ||
110 | /* copy the data */ | 141 | /* construct a replacement payload */ |
111 | ret = -ENOMEM; | 142 | ret = -ENOMEM; |
112 | new = kmalloc(datalen, GFP_KERNEL); | 143 | upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); |
113 | if (!new) | 144 | if (!upayload) |
114 | goto error; | 145 | goto error; |
115 | 146 | ||
116 | memcpy(new, data, datalen); | 147 | upayload->datalen = datalen; |
148 | memcpy(upayload->data, data, datalen); | ||
117 | 149 | ||
118 | /* check the quota and attach the new data */ | 150 | /* check the quota and attach the new data */ |
119 | zap = new; | 151 | zap = upayload; |
120 | write_lock(&key->lock); | ||
121 | 152 | ||
122 | ret = key_payload_reserve(key, datalen); | 153 | ret = key_payload_reserve(key, datalen); |
123 | 154 | ||
124 | if (ret == 0) { | 155 | if (ret == 0) { |
125 | /* attach the new data, displacing the old */ | 156 | /* attach the new data, displacing the old */ |
126 | zap = key->payload.data; | 157 | zap = key->payload.data; |
127 | key->payload.data = new; | 158 | rcu_assign_pointer(key->payload.data, upayload); |
128 | key->expiry = 0; | 159 | key->expiry = 0; |
129 | } | 160 | } |
130 | 161 | ||
131 | write_unlock(&key->lock); | 162 | call_rcu(&zap->rcu, user_update_rcu_disposal); |
132 | kfree(zap); | ||
133 | 163 | ||
134 | error: | 164 | error: |
135 | return ret; | 165 | return ret; |
@@ -152,13 +182,15 @@ static int user_match(const struct key *key, const void *description) | |||
152 | */ | 182 | */ |
153 | static void user_destroy(struct key *key) | 183 | static void user_destroy(struct key *key) |
154 | { | 184 | { |
155 | kfree(key->payload.data); | 185 | struct user_key_payload *upayload = key->payload.data; |
186 | |||
187 | kfree(upayload); | ||
156 | 188 | ||
157 | } /* end user_destroy() */ | 189 | } /* end user_destroy() */ |
158 | 190 | ||
159 | /*****************************************************************************/ | 191 | /*****************************************************************************/ |
160 | /* | 192 | /* |
161 | * describe the user | 193 | * describe the user key |
162 | */ | 194 | */ |
163 | static void user_describe(const struct key *key, struct seq_file *m) | 195 | static void user_describe(const struct key *key, struct seq_file *m) |
164 | { | 196 | { |
@@ -171,18 +203,23 @@ static void user_describe(const struct key *key, struct seq_file *m) | |||
171 | /*****************************************************************************/ | 203 | /*****************************************************************************/ |
172 | /* | 204 | /* |
173 | * read the key data | 205 | * read the key data |
206 | * - the key's semaphore is read-locked | ||
174 | */ | 207 | */ |
175 | static long user_read(const struct key *key, | 208 | static long user_read(const struct key *key, |
176 | char __user *buffer, size_t buflen) | 209 | char __user *buffer, size_t buflen) |
177 | { | 210 | { |
178 | long ret = key->datalen; | 211 | struct user_key_payload *upayload; |
212 | long ret; | ||
213 | |||
214 | upayload = rcu_dereference(key->payload.data); | ||
215 | ret = upayload->datalen; | ||
179 | 216 | ||
180 | /* we can return the data as is */ | 217 | /* we can return the data as is */ |
181 | if (buffer && buflen > 0) { | 218 | if (buffer && buflen > 0) { |
182 | if (buflen > key->datalen) | 219 | if (buflen > upayload->datalen) |
183 | buflen = key->datalen; | 220 | buflen = upayload->datalen; |
184 | 221 | ||
185 | if (copy_to_user(buffer, key->payload.data, buflen) != 0) | 222 | if (copy_to_user(buffer, upayload->data, buflen) != 0) |
186 | ret = -EFAULT; | 223 | ret = -EFAULT; |
187 | } | 224 | } |
188 | 225 | ||