diff options
Diffstat (limited to 'security/keys/request_key_auth.c')
| -rw-r--r-- | security/keys/request_key_auth.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index cce6ba6b0323..cb9817ced3fd 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | static int request_key_auth_instantiate(struct key *, const void *, size_t); | 21 | static int request_key_auth_instantiate(struct key *, const void *, size_t); |
| 22 | static void request_key_auth_describe(const struct key *, struct seq_file *); | 22 | static void request_key_auth_describe(const struct key *, struct seq_file *); |
| 23 | static void request_key_auth_revoke(struct key *); | ||
| 23 | static void request_key_auth_destroy(struct key *); | 24 | static void request_key_auth_destroy(struct key *); |
| 24 | static long request_key_auth_read(const struct key *, char __user *, size_t); | 25 | static long request_key_auth_read(const struct key *, char __user *, size_t); |
| 25 | 26 | ||
| @@ -31,6 +32,7 @@ struct key_type key_type_request_key_auth = { | |||
| 31 | .def_datalen = sizeof(struct request_key_auth), | 32 | .def_datalen = sizeof(struct request_key_auth), |
| 32 | .instantiate = request_key_auth_instantiate, | 33 | .instantiate = request_key_auth_instantiate, |
| 33 | .describe = request_key_auth_describe, | 34 | .describe = request_key_auth_describe, |
| 35 | .revoke = request_key_auth_revoke, | ||
| 34 | .destroy = request_key_auth_destroy, | 36 | .destroy = request_key_auth_destroy, |
| 35 | .read = request_key_auth_read, | 37 | .read = request_key_auth_read, |
| 36 | }; | 38 | }; |
| @@ -93,6 +95,24 @@ static long request_key_auth_read(const struct key *key, | |||
| 93 | 95 | ||
| 94 | /*****************************************************************************/ | 96 | /*****************************************************************************/ |
| 95 | /* | 97 | /* |
| 98 | * handle revocation of an authorisation token key | ||
| 99 | * - called with the key sem write-locked | ||
| 100 | */ | ||
| 101 | static void request_key_auth_revoke(struct key *key) | ||
| 102 | { | ||
| 103 | struct request_key_auth *rka = key->payload.data; | ||
| 104 | |||
| 105 | kenter("{%d}", key->serial); | ||
| 106 | |||
| 107 | if (rka->context) { | ||
| 108 | put_task_struct(rka->context); | ||
| 109 | rka->context = NULL; | ||
| 110 | } | ||
| 111 | |||
| 112 | } /* end request_key_auth_revoke() */ | ||
| 113 | |||
| 114 | /*****************************************************************************/ | ||
| 115 | /* | ||
| 96 | * destroy an instantiation authorisation token key | 116 | * destroy an instantiation authorisation token key |
| 97 | */ | 117 | */ |
| 98 | static void request_key_auth_destroy(struct key *key) | 118 | static void request_key_auth_destroy(struct key *key) |
| @@ -101,6 +121,11 @@ static void request_key_auth_destroy(struct key *key) | |||
| 101 | 121 | ||
| 102 | kenter("{%d}", key->serial); | 122 | kenter("{%d}", key->serial); |
| 103 | 123 | ||
| 124 | if (rka->context) { | ||
| 125 | put_task_struct(rka->context); | ||
| 126 | rka->context = NULL; | ||
| 127 | } | ||
| 128 | |||
| 104 | key_put(rka->target_key); | 129 | key_put(rka->target_key); |
| 105 | kfree(rka); | 130 | kfree(rka); |
| 106 | 131 | ||
| @@ -131,14 +156,26 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
| 131 | * another process */ | 156 | * another process */ |
| 132 | if (current->request_key_auth) { | 157 | if (current->request_key_auth) { |
| 133 | /* it is - use that instantiation context here too */ | 158 | /* it is - use that instantiation context here too */ |
| 159 | down_read(¤t->request_key_auth->sem); | ||
| 160 | |||
| 161 | /* if the auth key has been revoked, then the key we're | ||
| 162 | * servicing is already instantiated */ | ||
| 163 | if (test_bit(KEY_FLAG_REVOKED, | ||
| 164 | ¤t->request_key_auth->flags)) | ||
| 165 | goto auth_key_revoked; | ||
| 166 | |||
| 134 | irka = current->request_key_auth->payload.data; | 167 | irka = current->request_key_auth->payload.data; |
| 135 | rka->context = irka->context; | 168 | rka->context = irka->context; |
| 136 | rka->pid = irka->pid; | 169 | rka->pid = irka->pid; |
| 170 | get_task_struct(rka->context); | ||
| 171 | |||
| 172 | up_read(¤t->request_key_auth->sem); | ||
| 137 | } | 173 | } |
| 138 | else { | 174 | else { |
| 139 | /* it isn't - use this process as the context */ | 175 | /* it isn't - use this process as the context */ |
| 140 | rka->context = current; | 176 | rka->context = current; |
| 141 | rka->pid = current->pid; | 177 | rka->pid = current->pid; |
| 178 | get_task_struct(rka->context); | ||
| 142 | } | 179 | } |
| 143 | 180 | ||
| 144 | rka->target_key = key_get(target); | 181 | rka->target_key = key_get(target); |
| @@ -148,7 +185,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
| 148 | sprintf(desc, "%x", target->serial); | 185 | sprintf(desc, "%x", target->serial); |
| 149 | 186 | ||
| 150 | authkey = key_alloc(&key_type_request_key_auth, desc, | 187 | authkey = key_alloc(&key_type_request_key_auth, desc, |
| 151 | current->fsuid, current->fsgid, | 188 | current->fsuid, current->fsgid, current, |
| 152 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | | 189 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | |
| 153 | KEY_USR_VIEW, 1); | 190 | KEY_USR_VIEW, 1); |
| 154 | if (IS_ERR(authkey)) { | 191 | if (IS_ERR(authkey)) { |
| @@ -161,9 +198,15 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
| 161 | if (ret < 0) | 198 | if (ret < 0) |
| 162 | goto error_inst; | 199 | goto error_inst; |
| 163 | 200 | ||
| 164 | kleave(" = {%d})", authkey->serial); | 201 | kleave(" = {%d}", authkey->serial); |
| 165 | return authkey; | 202 | return authkey; |
| 166 | 203 | ||
| 204 | auth_key_revoked: | ||
| 205 | up_read(¤t->request_key_auth->sem); | ||
| 206 | kfree(rka); | ||
| 207 | kleave("= -EKEYREVOKED"); | ||
| 208 | return ERR_PTR(-EKEYREVOKED); | ||
| 209 | |||
| 167 | error_inst: | 210 | error_inst: |
| 168 | key_revoke(authkey); | 211 | key_revoke(authkey); |
| 169 | key_put(authkey); | 212 | key_put(authkey); |
