diff options
-rw-r--r-- | Documentation/keys-request-key.txt | 161 | ||||
-rw-r--r-- | Documentation/keys.txt | 18 | ||||
-rw-r--r-- | arch/sparc/Kconfig | 4 | ||||
-rw-r--r-- | arch/sparc/defconfig | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 39 | ||||
-rw-r--r-- | arch/sparc64/kernel/power.c | 64 | ||||
-rw-r--r-- | arch/sparc64/kernel/rtrap.S | 7 | ||||
-rw-r--r-- | arch/sparc64/lib/VISsave.S | 8 | ||||
-rw-r--r-- | drivers/pcmcia/ti113x.h | 5 | ||||
-rw-r--r-- | drivers/video/p9100.c | 4 | ||||
-rw-r--r-- | fs/namei.c | 6 | ||||
-rw-r--r-- | include/linux/key-ui.h | 91 | ||||
-rw-r--r-- | kernel/signal.c | 3 | ||||
-rw-r--r-- | security/keys/Makefile | 1 | ||||
-rw-r--r-- | security/keys/permission.c | 70 | ||||
-rw-r--r-- | security/keys/request_key.c | 2 | ||||
-rw-r--r-- | security/keys/request_key_auth.c | 3 |
17 files changed, 352 insertions, 135 deletions
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt new file mode 100644 index 000000000000..5f2b9c5edbb5 --- /dev/null +++ b/Documentation/keys-request-key.txt | |||
@@ -0,0 +1,161 @@ | |||
1 | =================== | ||
2 | KEY REQUEST SERVICE | ||
3 | =================== | ||
4 | |||
5 | The key request service is part of the key retention service (refer to | ||
6 | Documentation/keys.txt). This document explains more fully how that the | ||
7 | requesting algorithm works. | ||
8 | |||
9 | The process starts by either the kernel requesting a service by calling | ||
10 | request_key(): | ||
11 | |||
12 | struct key *request_key(const struct key_type *type, | ||
13 | const char *description, | ||
14 | const char *callout_string); | ||
15 | |||
16 | Or by userspace invoking the request_key system call: | ||
17 | |||
18 | key_serial_t request_key(const char *type, | ||
19 | const char *description, | ||
20 | const char *callout_info, | ||
21 | key_serial_t dest_keyring); | ||
22 | |||
23 | The main difference between the two access points is that the in-kernel | ||
24 | interface does not need to link the key to a keyring to prevent it from being | ||
25 | immediately destroyed. The kernel interface returns a pointer directly to the | ||
26 | key, and it's up to the caller to destroy the key. | ||
27 | |||
28 | The userspace interface links the key to a keyring associated with the process | ||
29 | to prevent the key from going away, and returns the serial number of the key to | ||
30 | the caller. | ||
31 | |||
32 | |||
33 | =========== | ||
34 | THE PROCESS | ||
35 | =========== | ||
36 | |||
37 | A request proceeds in the following manner: | ||
38 | |||
39 | (1) Process A calls request_key() [the userspace syscall calls the kernel | ||
40 | interface]. | ||
41 | |||
42 | (2) request_key() searches the process's subscribed keyrings to see if there's | ||
43 | a suitable key there. If there is, it returns the key. If there isn't, and | ||
44 | callout_info is not set, an error is returned. Otherwise the process | ||
45 | proceeds to the next step. | ||
46 | |||
47 | (3) request_key() sees that A doesn't have the desired key yet, so it creates | ||
48 | two things: | ||
49 | |||
50 | (a) An uninstantiated key U of requested type and description. | ||
51 | |||
52 | (b) An authorisation key V that refers to key U and notes that process A | ||
53 | is the context in which key U should be instantiated and secured, and | ||
54 | from which associated key requests may be satisfied. | ||
55 | |||
56 | (4) request_key() then forks and executes /sbin/request-key with a new session | ||
57 | keyring that contains a link to auth key V. | ||
58 | |||
59 | (5) /sbin/request-key execs an appropriate program to perform the actual | ||
60 | instantiation. | ||
61 | |||
62 | (6) The program may want to access another key from A's context (say a | ||
63 | Kerberos TGT key). It just requests the appropriate key, and the keyring | ||
64 | search notes that the session keyring has auth key V in its bottom level. | ||
65 | |||
66 | This will permit it to then search the keyrings of process A with the | ||
67 | UID, GID, groups and security info of process A as if it was process A, | ||
68 | and come up with key W. | ||
69 | |||
70 | (7) The program then does what it must to get the data with which to | ||
71 | instantiate key U, using key W as a reference (perhaps it contacts a | ||
72 | Kerberos server using the TGT) and then instantiates key U. | ||
73 | |||
74 | (8) Upon instantiating key U, auth key V is automatically revoked so that it | ||
75 | may not be used again. | ||
76 | |||
77 | (9) The program then exits 0 and request_key() deletes key V and returns key | ||
78 | U to the caller. | ||
79 | |||
80 | This also extends further. If key W (step 5 above) didn't exist, key W would be | ||
81 | created uninstantiated, another auth key (X) would be created [as per step 3] | ||
82 | and another copy of /sbin/request-key spawned [as per step 4]; but the context | ||
83 | specified by auth key X will still be process A, as it was in auth key V. | ||
84 | |||
85 | This is because process A's keyrings can't simply be attached to | ||
86 | /sbin/request-key at the appropriate places because (a) execve will discard two | ||
87 | of them, and (b) it requires the same UID/GID/Groups all the way through. | ||
88 | |||
89 | |||
90 | ====================== | ||
91 | NEGATIVE INSTANTIATION | ||
92 | ====================== | ||
93 | |||
94 | Rather than instantiating a key, it is possible for the possessor of an | ||
95 | authorisation key to negatively instantiate a key that's under construction. | ||
96 | This is a short duration placeholder that causes any attempt at re-requesting | ||
97 | the key whilst it exists to fail with error ENOKEY. | ||
98 | |||
99 | This is provided to prevent excessive repeated spawning of /sbin/request-key | ||
100 | processes for a key that will never be obtainable. | ||
101 | |||
102 | Should the /sbin/request-key process exit anything other than 0 or die on a | ||
103 | signal, the key under construction will be automatically negatively | ||
104 | instantiated for a short amount of time. | ||
105 | |||
106 | |||
107 | ==================== | ||
108 | THE SEARCH ALGORITHM | ||
109 | ==================== | ||
110 | |||
111 | A search of any particular keyring proceeds in the following fashion: | ||
112 | |||
113 | (1) When the key management code searches for a key (keyring_search_aux) it | ||
114 | firstly calls key_permission(SEARCH) on the keyring it's starting with, | ||
115 | if this denies permission, it doesn't search further. | ||
116 | |||
117 | (2) It considers all the non-keyring keys within that keyring and, if any key | ||
118 | matches the criteria specified, calls key_permission(SEARCH) on it to see | ||
119 | if the key is allowed to be found. If it is, that key is returned; if | ||
120 | not, the search continues, and the error code is retained if of higher | ||
121 | priority than the one currently set. | ||
122 | |||
123 | (3) It then considers all the keyring-type keys in the keyring it's currently | ||
124 | searching. It calls key_permission(SEARCH) on each keyring, and if this | ||
125 | grants permission, it recurses, executing steps (2) and (3) on that | ||
126 | keyring. | ||
127 | |||
128 | The process stops immediately a valid key is found with permission granted to | ||
129 | use it. Any error from a previous match attempt is discarded and the key is | ||
130 | returned. | ||
131 | |||
132 | When search_process_keyrings() is invoked, it performs the following searches | ||
133 | until one succeeds: | ||
134 | |||
135 | (1) If extant, the process's thread keyring is searched. | ||
136 | |||
137 | (2) If extant, the process's process keyring is searched. | ||
138 | |||
139 | (3) The process's session keyring is searched. | ||
140 | |||
141 | (4) If the process has a request_key() authorisation key in its session | ||
142 | keyring then: | ||
143 | |||
144 | (a) If extant, the calling process's thread keyring is searched. | ||
145 | |||
146 | (b) If extant, the calling process's process keyring is searched. | ||
147 | |||
148 | (c) The calling process's session keyring is searched. | ||
149 | |||
150 | The moment one succeeds, all pending errors are discarded and the found key is | ||
151 | returned. | ||
152 | |||
153 | Only if all these fail does the whole thing fail with the highest priority | ||
154 | error. Note that several errors may have come from LSM. | ||
155 | |||
156 | The error priority is: | ||
157 | |||
158 | EKEYREVOKED > EKEYEXPIRED > ENOKEY | ||
159 | |||
160 | EACCES/EPERM are only returned on a direct search of a specific keyring where | ||
161 | the basal keyring does not grant Search permission. | ||
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index b22e7c8d059a..4afe03a58c5b 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -361,6 +361,8 @@ The main syscalls are: | |||
361 | /sbin/request-key will be invoked in an attempt to obtain a key. The | 361 | /sbin/request-key will be invoked in an attempt to obtain a key. The |
362 | callout_info string will be passed as an argument to the program. | 362 | callout_info string will be passed as an argument to the program. |
363 | 363 | ||
364 | See also Documentation/keys-request-key.txt. | ||
365 | |||
364 | 366 | ||
365 | The keyctl syscall functions are: | 367 | The keyctl syscall functions are: |
366 | 368 | ||
@@ -533,8 +535,8 @@ The keyctl syscall functions are: | |||
533 | 535 | ||
534 | (*) Read the payload data from a key: | 536 | (*) Read the payload data from a key: |
535 | 537 | ||
536 | key_serial_t keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer, | 538 | long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer, |
537 | size_t buflen); | 539 | size_t buflen); |
538 | 540 | ||
539 | This function attempts to read the payload data from the specified key | 541 | This function attempts to read the payload data from the specified key |
540 | into the buffer. The process must have read permission on the key to | 542 | into the buffer. The process must have read permission on the key to |
@@ -555,9 +557,9 @@ The keyctl syscall functions are: | |||
555 | 557 | ||
556 | (*) Instantiate a partially constructed key. | 558 | (*) Instantiate a partially constructed key. |
557 | 559 | ||
558 | key_serial_t keyctl(KEYCTL_INSTANTIATE, key_serial_t key, | 560 | long keyctl(KEYCTL_INSTANTIATE, key_serial_t key, |
559 | const void *payload, size_t plen, | 561 | const void *payload, size_t plen, |
560 | key_serial_t keyring); | 562 | key_serial_t keyring); |
561 | 563 | ||
562 | If the kernel calls back to userspace to complete the instantiation of a | 564 | If the kernel calls back to userspace to complete the instantiation of a |
563 | key, userspace should use this call to supply data for the key before the | 565 | key, userspace should use this call to supply data for the key before the |
@@ -576,8 +578,8 @@ The keyctl syscall functions are: | |||
576 | 578 | ||
577 | (*) Negatively instantiate a partially constructed key. | 579 | (*) Negatively instantiate a partially constructed key. |
578 | 580 | ||
579 | key_serial_t keyctl(KEYCTL_NEGATE, key_serial_t key, | 581 | long keyctl(KEYCTL_NEGATE, key_serial_t key, |
580 | unsigned timeout, key_serial_t keyring); | 582 | unsigned timeout, key_serial_t keyring); |
581 | 583 | ||
582 | If the kernel calls back to userspace to complete the instantiation of a | 584 | If the kernel calls back to userspace to complete the instantiation of a |
583 | key, userspace should use this call mark the key as negative before the | 585 | key, userspace should use this call mark the key as negative before the |
@@ -688,6 +690,8 @@ payload contents" for more information. | |||
688 | If successful, the key will have been attached to the default keyring for | 690 | If successful, the key will have been attached to the default keyring for |
689 | implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. | 691 | implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. |
690 | 692 | ||
693 | See also Documentation/keys-request-key.txt. | ||
694 | |||
691 | 695 | ||
692 | (*) When it is no longer required, the key should be released using: | 696 | (*) When it is no longer required, the key should be released using: |
693 | 697 | ||
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 6537445dac0e..f7c51b869049 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -21,6 +21,10 @@ config GENERIC_ISA_DMA | |||
21 | bool | 21 | bool |
22 | default y | 22 | default y |
23 | 23 | ||
24 | config GENERIC_IOMAP | ||
25 | bool | ||
26 | default y | ||
27 | |||
24 | source "init/Kconfig" | 28 | source "init/Kconfig" |
25 | 29 | ||
26 | menu "General machine setup" | 30 | menu "General machine setup" |
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index a69856263009..8a3aef1e22f5 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig | |||
@@ -5,6 +5,7 @@ CONFIG_MMU=y | |||
5 | CONFIG_UID16=y | 5 | CONFIG_UID16=y |
6 | CONFIG_HIGHMEM=y | 6 | CONFIG_HIGHMEM=y |
7 | CONFIG_GENERIC_ISA_DMA=y | 7 | CONFIG_GENERIC_ISA_DMA=y |
8 | CONFIG_GENERIC_IOMAP=y | ||
8 | 9 | ||
9 | # | 10 | # |
10 | # Code maturity level options | 11 | # Code maturity level options |
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index f685035dbdb8..11a848402fb1 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -33,7 +33,7 @@ | |||
33 | /* This is trivial with the new code... */ | 33 | /* This is trivial with the new code... */ |
34 | .globl do_fpdis | 34 | .globl do_fpdis |
35 | do_fpdis: | 35 | do_fpdis: |
36 | sethi %hi(TSTATE_PEF), %g4 ! IEU0 | 36 | sethi %hi(TSTATE_PEF), %g4 |
37 | rdpr %tstate, %g5 | 37 | rdpr %tstate, %g5 |
38 | andcc %g5, %g4, %g0 | 38 | andcc %g5, %g4, %g0 |
39 | be,pt %xcc, 1f | 39 | be,pt %xcc, 1f |
@@ -50,18 +50,18 @@ do_fpdis: | |||
50 | add %g0, %g0, %g0 | 50 | add %g0, %g0, %g0 |
51 | ba,a,pt %xcc, rtrap_clr_l6 | 51 | ba,a,pt %xcc, rtrap_clr_l6 |
52 | 52 | ||
53 | 1: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group | 53 | 1: ldub [%g6 + TI_FPSAVED], %g5 |
54 | wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles | 54 | wr %g0, FPRS_FEF, %fprs |
55 | andcc %g5, FPRS_FEF, %g0 ! IEU1 Group | 55 | andcc %g5, FPRS_FEF, %g0 |
56 | be,a,pt %icc, 1f ! CTI | 56 | be,a,pt %icc, 1f |
57 | clr %g7 ! IEU0 | 57 | clr %g7 |
58 | ldx [%g6 + TI_GSR], %g7 ! Load Group | 58 | ldx [%g6 + TI_GSR], %g7 |
59 | 1: andcc %g5, FPRS_DL, %g0 ! IEU1 | 59 | 1: andcc %g5, FPRS_DL, %g0 |
60 | bne,pn %icc, 2f ! CTI | 60 | bne,pn %icc, 2f |
61 | fzero %f0 ! FPA | 61 | fzero %f0 |
62 | andcc %g5, FPRS_DU, %g0 ! IEU1 Group | 62 | andcc %g5, FPRS_DU, %g0 |
63 | bne,pn %icc, 1f ! CTI | 63 | bne,pn %icc, 1f |
64 | fzero %f2 ! FPA | 64 | fzero %f2 |
65 | faddd %f0, %f2, %f4 | 65 | faddd %f0, %f2, %f4 |
66 | fmuld %f0, %f2, %f6 | 66 | fmuld %f0, %f2, %f6 |
67 | faddd %f0, %f2, %f8 | 67 | faddd %f0, %f2, %f8 |
@@ -104,8 +104,10 @@ do_fpdis: | |||
104 | add %g6, TI_FPREGS + 0xc0, %g2 | 104 | add %g6, TI_FPREGS + 0xc0, %g2 |
105 | faddd %f0, %f2, %f8 | 105 | faddd %f0, %f2, %f8 |
106 | fmuld %f0, %f2, %f10 | 106 | fmuld %f0, %f2, %f10 |
107 | ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-( | 107 | membar #Sync |
108 | ldda [%g1] ASI_BLK_S, %f32 | ||
108 | ldda [%g2] ASI_BLK_S, %f48 | 109 | ldda [%g2] ASI_BLK_S, %f48 |
110 | membar #Sync | ||
109 | faddd %f0, %f2, %f12 | 111 | faddd %f0, %f2, %f12 |
110 | fmuld %f0, %f2, %f14 | 112 | fmuld %f0, %f2, %f14 |
111 | faddd %f0, %f2, %f16 | 113 | faddd %f0, %f2, %f16 |
@@ -116,7 +118,6 @@ do_fpdis: | |||
116 | fmuld %f0, %f2, %f26 | 118 | fmuld %f0, %f2, %f26 |
117 | faddd %f0, %f2, %f28 | 119 | faddd %f0, %f2, %f28 |
118 | fmuld %f0, %f2, %f30 | 120 | fmuld %f0, %f2, %f30 |
119 | membar #Sync | ||
120 | b,pt %xcc, fpdis_exit | 121 | b,pt %xcc, fpdis_exit |
121 | nop | 122 | nop |
122 | 2: andcc %g5, FPRS_DU, %g0 | 123 | 2: andcc %g5, FPRS_DU, %g0 |
@@ -133,8 +134,10 @@ do_fpdis: | |||
133 | add %g6, TI_FPREGS + 0x40, %g2 | 134 | add %g6, TI_FPREGS + 0x40, %g2 |
134 | faddd %f32, %f34, %f36 | 135 | faddd %f32, %f34, %f36 |
135 | fmuld %f32, %f34, %f38 | 136 | fmuld %f32, %f34, %f38 |
136 | ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( | 137 | membar #Sync |
138 | ldda [%g1] ASI_BLK_S, %f0 | ||
137 | ldda [%g2] ASI_BLK_S, %f16 | 139 | ldda [%g2] ASI_BLK_S, %f16 |
140 | membar #Sync | ||
138 | faddd %f32, %f34, %f40 | 141 | faddd %f32, %f34, %f40 |
139 | fmuld %f32, %f34, %f42 | 142 | fmuld %f32, %f34, %f42 |
140 | faddd %f32, %f34, %f44 | 143 | faddd %f32, %f34, %f44 |
@@ -147,7 +150,6 @@ do_fpdis: | |||
147 | fmuld %f32, %f34, %f58 | 150 | fmuld %f32, %f34, %f58 |
148 | faddd %f32, %f34, %f60 | 151 | faddd %f32, %f34, %f60 |
149 | fmuld %f32, %f34, %f62 | 152 | fmuld %f32, %f34, %f62 |
150 | membar #Sync | ||
151 | ba,pt %xcc, fpdis_exit | 153 | ba,pt %xcc, fpdis_exit |
152 | nop | 154 | nop |
153 | 3: mov SECONDARY_CONTEXT, %g3 | 155 | 3: mov SECONDARY_CONTEXT, %g3 |
@@ -158,7 +160,8 @@ do_fpdis: | |||
158 | stxa %g2, [%g3] ASI_DMMU | 160 | stxa %g2, [%g3] ASI_DMMU |
159 | membar #Sync | 161 | membar #Sync |
160 | mov 0x40, %g2 | 162 | mov 0x40, %g2 |
161 | ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( | 163 | membar #Sync |
164 | ldda [%g1] ASI_BLK_S, %f0 | ||
162 | ldda [%g1 + %g2] ASI_BLK_S, %f16 | 165 | ldda [%g1 + %g2] ASI_BLK_S, %f16 |
163 | add %g1, 0x80, %g1 | 166 | add %g1, 0x80, %g1 |
164 | ldda [%g1] ASI_BLK_S, %f32 | 167 | ldda [%g1] ASI_BLK_S, %f32 |
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 946cee0257ea..9e8362ea3104 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
19 | #include <asm/ebus.h> | 19 | #include <asm/ebus.h> |
20 | #include <asm/isa.h> | ||
20 | #include <asm/auxio.h> | 21 | #include <asm/auxio.h> |
21 | 22 | ||
22 | #include <linux/unistd.h> | 23 | #include <linux/unistd.h> |
@@ -100,46 +101,83 @@ again: | |||
100 | return 0; | 101 | return 0; |
101 | } | 102 | } |
102 | 103 | ||
103 | static int __init has_button_interrupt(struct linux_ebus_device *edev) | 104 | static int __init has_button_interrupt(unsigned int irq, int prom_node) |
104 | { | 105 | { |
105 | if (edev->irqs[0] == PCI_IRQ_NONE) | 106 | if (irq == PCI_IRQ_NONE) |
106 | return 0; | 107 | return 0; |
107 | if (!prom_node_has_property(edev->prom_node, "button")) | 108 | if (!prom_node_has_property(prom_node, "button")) |
108 | return 0; | 109 | return 0; |
109 | 110 | ||
110 | return 1; | 111 | return 1; |
111 | } | 112 | } |
112 | 113 | ||
113 | void __init power_init(void) | 114 | static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p) |
114 | { | 115 | { |
115 | struct linux_ebus *ebus; | 116 | struct linux_ebus *ebus; |
116 | struct linux_ebus_device *edev; | 117 | struct linux_ebus_device *edev; |
118 | |||
119 | for_each_ebus(ebus) { | ||
120 | for_each_ebusdev(edev, ebus) { | ||
121 | if (!strcmp(edev->prom_name, "power")) { | ||
122 | *resp = &edev->resource[0]; | ||
123 | *irq_p = edev->irqs[0]; | ||
124 | *prom_node_p = edev->prom_node; | ||
125 | return 0; | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | return -ENODEV; | ||
130 | } | ||
131 | |||
132 | static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p) | ||
133 | { | ||
134 | struct sparc_isa_bridge *isa_bus; | ||
135 | struct sparc_isa_device *isa_dev; | ||
136 | |||
137 | for_each_isa(isa_bus) { | ||
138 | for_each_isadev(isa_dev, isa_bus) { | ||
139 | if (!strcmp(isa_dev->prom_name, "power")) { | ||
140 | *resp = &isa_dev->resource; | ||
141 | *irq_p = isa_dev->irq; | ||
142 | *prom_node_p = isa_dev->prom_node; | ||
143 | return 0; | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | return -ENODEV; | ||
148 | } | ||
149 | |||
150 | void __init power_init(void) | ||
151 | { | ||
152 | struct resource *res = NULL; | ||
153 | unsigned int irq; | ||
154 | int prom_node; | ||
117 | static int invoked; | 155 | static int invoked; |
118 | 156 | ||
119 | if (invoked) | 157 | if (invoked) |
120 | return; | 158 | return; |
121 | invoked = 1; | 159 | invoked = 1; |
122 | 160 | ||
123 | for_each_ebus(ebus) { | 161 | if (!power_probe_ebus(&res, &irq, &prom_node)) |
124 | for_each_ebusdev(edev, ebus) { | 162 | goto found; |
125 | if (!strcmp(edev->prom_name, "power")) | 163 | |
126 | goto found; | 164 | if (!power_probe_isa(&res, &irq, &prom_node)) |
127 | } | 165 | goto found; |
128 | } | 166 | |
129 | return; | 167 | return; |
130 | 168 | ||
131 | found: | 169 | found: |
132 | power_reg = ioremap(edev->resource[0].start, 0x4); | 170 | power_reg = ioremap(res->start, 0x4); |
133 | printk("power: Control reg at %p ... ", power_reg); | 171 | printk("power: Control reg at %p ... ", power_reg); |
134 | poweroff_method = machine_halt; /* able to use the standard halt */ | 172 | poweroff_method = machine_halt; /* able to use the standard halt */ |
135 | if (has_button_interrupt(edev)) { | 173 | if (has_button_interrupt(irq, prom_node)) { |
136 | if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { | 174 | if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { |
137 | printk("Failed to start power daemon.\n"); | 175 | printk("Failed to start power daemon.\n"); |
138 | return; | 176 | return; |
139 | } | 177 | } |
140 | printk("powerd running.\n"); | 178 | printk("powerd running.\n"); |
141 | 179 | ||
142 | if (request_irq(edev->irqs[0], | 180 | if (request_irq(irq, |
143 | power_handler, SA_SHIRQ, "power", NULL) < 0) | 181 | power_handler, SA_SHIRQ, "power", NULL) < 0) |
144 | printk("power: Error, cannot register IRQ handler.\n"); | 182 | printk("power: Error, cannot register IRQ handler.\n"); |
145 | } else { | 183 | } else { |
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index ecfb42a69a44..090dcca00d2a 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
@@ -312,32 +312,33 @@ kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5 | |||
312 | wr %g1, FPRS_FEF, %fprs | 312 | wr %g1, FPRS_FEF, %fprs |
313 | ldx [%o1 + %o5], %g1 | 313 | ldx [%o1 + %o5], %g1 |
314 | add %g6, TI_XFSR, %o1 | 314 | add %g6, TI_XFSR, %o1 |
315 | membar #StoreLoad | #LoadLoad | ||
316 | sll %o0, 8, %o2 | 315 | sll %o0, 8, %o2 |
317 | add %g6, TI_FPREGS, %o3 | 316 | add %g6, TI_FPREGS, %o3 |
318 | brz,pn %l6, 1f | 317 | brz,pn %l6, 1f |
319 | add %g6, TI_FPREGS+0x40, %o4 | 318 | add %g6, TI_FPREGS+0x40, %o4 |
320 | 319 | ||
320 | membar #Sync | ||
321 | ldda [%o3 + %o2] ASI_BLK_P, %f0 | 321 | ldda [%o3 + %o2] ASI_BLK_P, %f0 |
322 | ldda [%o4 + %o2] ASI_BLK_P, %f16 | 322 | ldda [%o4 + %o2] ASI_BLK_P, %f16 |
323 | membar #Sync | ||
323 | 1: andcc %l2, FPRS_DU, %g0 | 324 | 1: andcc %l2, FPRS_DU, %g0 |
324 | be,pn %icc, 1f | 325 | be,pn %icc, 1f |
325 | wr %g1, 0, %gsr | 326 | wr %g1, 0, %gsr |
326 | add %o2, 0x80, %o2 | 327 | add %o2, 0x80, %o2 |
328 | membar #Sync | ||
327 | ldda [%o3 + %o2] ASI_BLK_P, %f32 | 329 | ldda [%o3 + %o2] ASI_BLK_P, %f32 |
328 | ldda [%o4 + %o2] ASI_BLK_P, %f48 | 330 | ldda [%o4 + %o2] ASI_BLK_P, %f48 |
329 | |||
330 | 1: membar #Sync | 331 | 1: membar #Sync |
331 | ldx [%o1 + %o5], %fsr | 332 | ldx [%o1 + %o5], %fsr |
332 | 2: stb %l5, [%g6 + TI_FPDEPTH] | 333 | 2: stb %l5, [%g6 + TI_FPDEPTH] |
333 | ba,pt %xcc, rt_continue | 334 | ba,pt %xcc, rt_continue |
334 | nop | 335 | nop |
335 | 5: wr %g0, FPRS_FEF, %fprs | 336 | 5: wr %g0, FPRS_FEF, %fprs |
336 | membar #StoreLoad | #LoadLoad | ||
337 | sll %o0, 8, %o2 | 337 | sll %o0, 8, %o2 |
338 | 338 | ||
339 | add %g6, TI_FPREGS+0x80, %o3 | 339 | add %g6, TI_FPREGS+0x80, %o3 |
340 | add %g6, TI_FPREGS+0xc0, %o4 | 340 | add %g6, TI_FPREGS+0xc0, %o4 |
341 | membar #Sync | ||
341 | ldda [%o3 + %o2] ASI_BLK_P, %f32 | 342 | ldda [%o3 + %o2] ASI_BLK_P, %f32 |
342 | ldda [%o4 + %o2] ASI_BLK_P, %f48 | 343 | ldda [%o4 + %o2] ASI_BLK_P, %f48 |
343 | membar #Sync | 344 | membar #Sync |
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index 4e18989bd602..a0ded5c5aa5c 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S | |||
@@ -59,15 +59,17 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 | |||
59 | be,pn %icc, 9b | 59 | be,pn %icc, 9b |
60 | add %g6, TI_FPREGS, %g2 | 60 | add %g6, TI_FPREGS, %g2 |
61 | andcc %o5, FPRS_DL, %g0 | 61 | andcc %o5, FPRS_DL, %g0 |
62 | membar #StoreStore | #LoadStore | ||
63 | 62 | ||
64 | be,pn %icc, 4f | 63 | be,pn %icc, 4f |
65 | add %g6, TI_FPREGS+0x40, %g3 | 64 | add %g6, TI_FPREGS+0x40, %g3 |
65 | membar #Sync | ||
66 | stda %f0, [%g2 + %g1] ASI_BLK_P | 66 | stda %f0, [%g2 + %g1] ASI_BLK_P |
67 | stda %f16, [%g3 + %g1] ASI_BLK_P | 67 | stda %f16, [%g3 + %g1] ASI_BLK_P |
68 | membar #Sync | ||
68 | andcc %o5, FPRS_DU, %g0 | 69 | andcc %o5, FPRS_DU, %g0 |
69 | be,pn %icc, 5f | 70 | be,pn %icc, 5f |
70 | 4: add %g1, 128, %g1 | 71 | 4: add %g1, 128, %g1 |
72 | membar #Sync | ||
71 | stda %f32, [%g2 + %g1] ASI_BLK_P | 73 | stda %f32, [%g2 + %g1] ASI_BLK_P |
72 | 74 | ||
73 | stda %f48, [%g3 + %g1] ASI_BLK_P | 75 | stda %f48, [%g3 + %g1] ASI_BLK_P |
@@ -87,7 +89,7 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 | |||
87 | sll %g1, 5, %g1 | 89 | sll %g1, 5, %g1 |
88 | add %g6, TI_FPREGS+0xc0, %g3 | 90 | add %g6, TI_FPREGS+0xc0, %g3 |
89 | wr %g0, FPRS_FEF, %fprs | 91 | wr %g0, FPRS_FEF, %fprs |
90 | membar #StoreStore | #LoadStore | 92 | membar #Sync |
91 | stda %f32, [%g2 + %g1] ASI_BLK_P | 93 | stda %f32, [%g2 + %g1] ASI_BLK_P |
92 | stda %f48, [%g3 + %g1] ASI_BLK_P | 94 | stda %f48, [%g3 + %g1] ASI_BLK_P |
93 | membar #Sync | 95 | membar #Sync |
@@ -128,8 +130,8 @@ VISenterhalf: | |||
128 | be,pn %icc, 4f | 130 | be,pn %icc, 4f |
129 | add %g6, TI_FPREGS, %g2 | 131 | add %g6, TI_FPREGS, %g2 |
130 | 132 | ||
131 | membar #StoreStore | #LoadStore | ||
132 | add %g6, TI_FPREGS+0x40, %g3 | 133 | add %g6, TI_FPREGS+0x40, %g3 |
134 | membar #Sync | ||
133 | stda %f0, [%g2 + %g1] ASI_BLK_P | 135 | stda %f0, [%g2 + %g1] ASI_BLK_P |
134 | stda %f16, [%g3 + %g1] ASI_BLK_P | 136 | stda %f16, [%g3 + %g1] ASI_BLK_P |
135 | membar #Sync | 137 | membar #Sync |
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index da0b404561c9..539b5cd1a598 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -873,6 +873,7 @@ static int ti1250_override(struct yenta_socket *socket) | |||
873 | * Some fixup code to make everybody happy (TM). | 873 | * Some fixup code to make everybody happy (TM). |
874 | */ | 874 | */ |
875 | 875 | ||
876 | #ifdef CONFIG_CARDBUS | ||
876 | /** | 877 | /** |
877 | * set/clear various test bits: | 878 | * set/clear various test bits: |
878 | * Defaults to clear the bit. | 879 | * Defaults to clear the bit. |
@@ -927,7 +928,6 @@ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) | |||
927 | config_writeb(socket, ENE_TEST_C9, test_c9); | 928 | config_writeb(socket, ENE_TEST_C9, test_c9); |
928 | } | 929 | } |
929 | 930 | ||
930 | |||
931 | static int ene_override(struct yenta_socket *socket) | 931 | static int ene_override(struct yenta_socket *socket) |
932 | { | 932 | { |
933 | /* install tune_bridge() function */ | 933 | /* install tune_bridge() function */ |
@@ -935,6 +935,9 @@ static int ene_override(struct yenta_socket *socket) | |||
935 | 935 | ||
936 | return ti1250_override(socket); | 936 | return ti1250_override(socket); |
937 | } | 937 | } |
938 | #else | ||
939 | # define ene_override ti1250_override | ||
940 | #endif | ||
938 | 941 | ||
939 | #endif /* _LINUX_TI113X_H */ | 942 | #endif /* _LINUX_TI113X_H */ |
940 | 943 | ||
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 7808a01493ad..b76a5a9a125b 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c | |||
@@ -288,6 +288,9 @@ static void p9100_init_one(struct sbus_dev *sdev) | |||
288 | all->par.physbase = sdev->reg_addrs[2].phys_addr; | 288 | all->par.physbase = sdev->reg_addrs[2].phys_addr; |
289 | 289 | ||
290 | sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); | 290 | sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); |
291 | all->info.var.red.length = 8; | ||
292 | all->info.var.green.length = 8; | ||
293 | all->info.var.blue.length = 8; | ||
291 | 294 | ||
292 | linebytes = prom_getintdefault(sdev->prom_node, "linebytes", | 295 | linebytes = prom_getintdefault(sdev->prom_node, "linebytes", |
293 | all->info.var.xres); | 296 | all->info.var.xres); |
@@ -323,6 +326,7 @@ static void p9100_init_one(struct sbus_dev *sdev) | |||
323 | kfree(all); | 326 | kfree(all); |
324 | return; | 327 | return; |
325 | } | 328 | } |
329 | fb_set_cmap(&all->info.cmap, &all->info); | ||
326 | 330 | ||
327 | list_add(&all->list, &p9100_list); | 331 | list_add(&all->list, &p9100_list); |
328 | 332 | ||
diff --git a/fs/namei.c b/fs/namei.c index 043d587216b5..aa62dbda93ac 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1551,19 +1551,19 @@ do_link: | |||
1551 | if (nd->last_type != LAST_NORM) | 1551 | if (nd->last_type != LAST_NORM) |
1552 | goto exit; | 1552 | goto exit; |
1553 | if (nd->last.name[nd->last.len]) { | 1553 | if (nd->last.name[nd->last.len]) { |
1554 | putname(nd->last.name); | 1554 | __putname(nd->last.name); |
1555 | goto exit; | 1555 | goto exit; |
1556 | } | 1556 | } |
1557 | error = -ELOOP; | 1557 | error = -ELOOP; |
1558 | if (count++==32) { | 1558 | if (count++==32) { |
1559 | putname(nd->last.name); | 1559 | __putname(nd->last.name); |
1560 | goto exit; | 1560 | goto exit; |
1561 | } | 1561 | } |
1562 | dir = nd->dentry; | 1562 | dir = nd->dentry; |
1563 | down(&dir->d_inode->i_sem); | 1563 | down(&dir->d_inode->i_sem); |
1564 | path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); | 1564 | path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); |
1565 | path.mnt = nd->mnt; | 1565 | path.mnt = nd->mnt; |
1566 | putname(nd->last.name); | 1566 | __putname(nd->last.name); |
1567 | goto do_last; | 1567 | goto do_last; |
1568 | } | 1568 | } |
1569 | 1569 | ||
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h index 918c34a8347e..7a2e332067c3 100644 --- a/include/linux/key-ui.h +++ b/include/linux/key-ui.h | |||
@@ -38,97 +38,16 @@ struct keyring_list { | |||
38 | struct key *keys[0]; | 38 | struct key *keys[0]; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | |||
42 | /* | 41 | /* |
43 | * check to see whether permission is granted to use a key in the desired way | 42 | * check to see whether permission is granted to use a key in the desired way |
44 | */ | 43 | */ |
45 | static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) | 44 | extern int key_task_permission(const key_ref_t key_ref, |
46 | { | 45 | struct task_struct *context, |
47 | struct key *key = key_ref_to_ptr(key_ref); | 46 | key_perm_t perm); |
48 | key_perm_t kperm; | ||
49 | |||
50 | if (is_key_possessed(key_ref)) | ||
51 | kperm = key->perm >> 24; | ||
52 | else if (key->uid == current->fsuid) | ||
53 | kperm = key->perm >> 16; | ||
54 | else if (key->gid != -1 && | ||
55 | key->perm & KEY_GRP_ALL && | ||
56 | in_group_p(key->gid) | ||
57 | ) | ||
58 | kperm = key->perm >> 8; | ||
59 | else | ||
60 | kperm = key->perm; | ||
61 | |||
62 | kperm = kperm & perm & KEY_ALL; | ||
63 | |||
64 | return kperm == perm; | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * check to see whether permission is granted to use a key in at least one of | ||
69 | * the desired ways | ||
70 | */ | ||
71 | static inline int key_any_permission(const key_ref_t key_ref, key_perm_t perm) | ||
72 | { | ||
73 | struct key *key = key_ref_to_ptr(key_ref); | ||
74 | key_perm_t kperm; | ||
75 | |||
76 | if (is_key_possessed(key_ref)) | ||
77 | kperm = key->perm >> 24; | ||
78 | else if (key->uid == current->fsuid) | ||
79 | kperm = key->perm >> 16; | ||
80 | else if (key->gid != -1 && | ||
81 | key->perm & KEY_GRP_ALL && | ||
82 | in_group_p(key->gid) | ||
83 | ) | ||
84 | kperm = key->perm >> 8; | ||
85 | else | ||
86 | kperm = key->perm; | ||
87 | 47 | ||
88 | kperm = kperm & perm & KEY_ALL; | 48 | static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) |
89 | |||
90 | return kperm != 0; | ||
91 | } | ||
92 | |||
93 | static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid) | ||
94 | { | ||
95 | int ret; | ||
96 | |||
97 | task_lock(tsk); | ||
98 | ret = groups_search(tsk->group_info, gid); | ||
99 | task_unlock(tsk); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | static inline int key_task_permission(const key_ref_t key_ref, | ||
104 | struct task_struct *context, | ||
105 | key_perm_t perm) | ||
106 | { | 49 | { |
107 | struct key *key = key_ref_to_ptr(key_ref); | 50 | return key_task_permission(key_ref, current, perm); |
108 | key_perm_t kperm; | ||
109 | |||
110 | if (is_key_possessed(key_ref)) { | ||
111 | kperm = key->perm >> 24; | ||
112 | } | ||
113 | else if (key->uid == context->fsuid) { | ||
114 | kperm = key->perm >> 16; | ||
115 | } | ||
116 | else if (key->gid != -1 && | ||
117 | key->perm & KEY_GRP_ALL && ( | ||
118 | key->gid == context->fsgid || | ||
119 | key_task_groups_search(context, key->gid) | ||
120 | ) | ||
121 | ) { | ||
122 | kperm = key->perm >> 8; | ||
123 | } | ||
124 | else { | ||
125 | kperm = key->perm; | ||
126 | } | ||
127 | |||
128 | kperm = kperm & perm & KEY_ALL; | ||
129 | |||
130 | return kperm == perm; | ||
131 | |||
132 | } | 51 | } |
133 | 52 | ||
134 | extern key_ref_t lookup_user_key(struct task_struct *context, | 53 | extern key_ref_t lookup_user_key(struct task_struct *context, |
diff --git a/kernel/signal.c b/kernel/signal.c index 619b027e92b5..c135f5aa2c2d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -578,7 +578,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
578 | * is to alert stop-signal processing code when another | 578 | * is to alert stop-signal processing code when another |
579 | * processor has come along and cleared the flag. | 579 | * processor has come along and cleared the flag. |
580 | */ | 580 | */ |
581 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | 581 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) |
582 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | ||
582 | } | 583 | } |
583 | if ( signr && | 584 | if ( signr && |
584 | ((info->si_code & __SI_MASK) == __SI_TIMER) && | 585 | ((info->si_code & __SI_MASK) == __SI_TIMER) && |
diff --git a/security/keys/Makefile b/security/keys/Makefile index c392d750b208..5145adfb6a05 100644 --- a/security/keys/Makefile +++ b/security/keys/Makefile | |||
@@ -6,6 +6,7 @@ obj-y := \ | |||
6 | key.o \ | 6 | key.o \ |
7 | keyring.o \ | 7 | keyring.o \ |
8 | keyctl.o \ | 8 | keyctl.o \ |
9 | permission.o \ | ||
9 | process_keys.o \ | 10 | process_keys.o \ |
10 | request_key.o \ | 11 | request_key.o \ |
11 | request_key_auth.o \ | 12 | request_key_auth.o \ |
diff --git a/security/keys/permission.c b/security/keys/permission.c new file mode 100644 index 000000000000..03db073ba45c --- /dev/null +++ b/security/keys/permission.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* permission.c: key permission determination | ||
2 | * | ||
3 | * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include "internal.h" | ||
14 | |||
15 | /*****************************************************************************/ | ||
16 | /* | ||
17 | * check to see whether permission is granted to use a key in the desired way, | ||
18 | * but permit the security modules to override | ||
19 | */ | ||
20 | int key_task_permission(const key_ref_t key_ref, | ||
21 | struct task_struct *context, | ||
22 | key_perm_t perm) | ||
23 | { | ||
24 | struct key *key; | ||
25 | key_perm_t kperm; | ||
26 | int ret; | ||
27 | |||
28 | key = key_ref_to_ptr(key_ref); | ||
29 | |||
30 | /* use the second 8-bits of permissions for keys the caller owns */ | ||
31 | if (key->uid == context->fsuid) { | ||
32 | kperm = key->perm >> 16; | ||
33 | goto use_these_perms; | ||
34 | } | ||
35 | |||
36 | /* use the third 8-bits of permissions for keys the caller has a group | ||
37 | * membership in common with */ | ||
38 | if (key->gid != -1 && key->perm & KEY_GRP_ALL) { | ||
39 | if (key->gid == context->fsgid) { | ||
40 | kperm = key->perm >> 8; | ||
41 | goto use_these_perms; | ||
42 | } | ||
43 | |||
44 | task_lock(context); | ||
45 | ret = groups_search(context->group_info, key->gid); | ||
46 | task_unlock(context); | ||
47 | |||
48 | if (ret) { | ||
49 | kperm = key->perm >> 8; | ||
50 | goto use_these_perms; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /* otherwise use the least-significant 8-bits */ | ||
55 | kperm = key->perm; | ||
56 | |||
57 | use_these_perms: | ||
58 | /* use the top 8-bits of permissions for keys the caller possesses | ||
59 | * - possessor permissions are additive with other permissions | ||
60 | */ | ||
61 | if (is_key_possessed(key_ref)) | ||
62 | kperm |= key->perm >> 24; | ||
63 | |||
64 | kperm = kperm & perm & KEY_ALL; | ||
65 | |||
66 | return kperm == perm; | ||
67 | |||
68 | } /* end key_task_permission() */ | ||
69 | |||
70 | EXPORT_SYMBOL(key_task_permission); | ||
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index e6dd366d43a3..5cc4bba70db6 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | ||
11 | * See Documentation/keys-request-key.txt | ||
10 | */ | 12 | */ |
11 | 13 | ||
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 1ecd3d3fa9f8..a8e4069d48cb 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | ||
11 | * See Documentation/keys-request-key.txt | ||
10 | */ | 12 | */ |
11 | 13 | ||
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -96,6 +98,7 @@ static void request_key_auth_destroy(struct key *key) | |||
96 | kenter("{%d}", key->serial); | 98 | kenter("{%d}", key->serial); |
97 | 99 | ||
98 | key_put(rka->target_key); | 100 | key_put(rka->target_key); |
101 | kfree(rka); | ||
99 | 102 | ||
100 | } /* end request_key_auth_destroy() */ | 103 | } /* end request_key_auth_destroy() */ |
101 | 104 | ||