Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
494b9ae7
Commit
494b9ae7
authored
Oct 19, 2017
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'tags/keys-fixes-20171018' into fixes-v4.14-rc5
parents
73d3393a
68a1fdbb
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
168 additions
and
80 deletions
+168
-80
crypto/asymmetric_keys/asymmetric_type.c
crypto/asymmetric_keys/asymmetric_type.c
+3
-1
crypto/asymmetric_keys/pkcs7_parser.c
crypto/asymmetric_keys/pkcs7_parser.c
+3
-0
fs/crypto/keyinfo.c
fs/crypto/keyinfo.c
+5
-0
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/ecryptfs_kernel.h
+17
-7
fs/ecryptfs/keystore.c
fs/ecryptfs/keystore.c
+8
-1
fs/fscache/object-list.c
fs/fscache/object-list.c
+7
-0
include/linux/key.h
include/linux/key.h
+30
-17
lib/digsig.c
lib/digsig.c
+6
-0
net/dns_resolver/dns_key.c
net/dns_resolver/dns_key.c
+1
-1
security/keys/Kconfig
security/keys/Kconfig
+1
-0
security/keys/big_key.c
security/keys/big_key.c
+2
-2
security/keys/encrypted-keys/encrypted.c
security/keys/encrypted-keys/encrypted.c
+8
-1
security/keys/gc.c
security/keys/gc.c
+4
-4
security/keys/key.c
security/keys/key.c
+30
-11
security/keys/keyctl.c
security/keys/keyctl.c
+4
-5
security/keys/keyring.c
security/keys/keyring.c
+8
-6
security/keys/permission.c
security/keys/permission.c
+4
-3
security/keys/proc.c
security/keys/proc.c
+19
-12
security/keys/process_keys.c
security/keys/process_keys.c
+1
-1
security/keys/request_key.c
security/keys/request_key.c
+3
-4
security/keys/request_key_auth.c
security/keys/request_key_auth.c
+1
-1
security/keys/trusted.c
security/keys/trusted.c
+1
-1
security/keys/user_defined.c
security/keys/user_defined.c
+2
-2
No files found.
crypto/asymmetric_keys/asymmetric_type.c
View file @
494b9ae7
...
@@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring,
...
@@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring,
char
*
req
,
*
p
;
char
*
req
,
*
p
;
int
len
;
int
len
;
BUG_ON
(
!
id_0
&&
!
id_1
);
if
(
id_0
)
{
if
(
id_0
)
{
lookup
=
id_0
->
data
;
lookup
=
id_0
->
data
;
len
=
id_0
->
len
;
len
=
id_0
->
len
;
...
@@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring,
...
@@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring,
if
(
id_0
&&
id_1
)
{
if
(
id_0
&&
id_1
)
{
const
struct
asymmetric_key_ids
*
kids
=
asymmetric_key_ids
(
key
);
const
struct
asymmetric_key_ids
*
kids
=
asymmetric_key_ids
(
key
);
if
(
!
kids
->
id
[
0
])
{
if
(
!
kids
->
id
[
1
])
{
pr_debug
(
"First ID matches, but second is missing
\n
"
);
pr_debug
(
"First ID matches, but second is missing
\n
"
);
goto
reject
;
goto
reject
;
}
}
...
...
crypto/asymmetric_keys/pkcs7_parser.c
View file @
494b9ae7
...
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
...
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
bool
want
=
false
;
bool
want
=
false
;
sinfo
=
msg
->
signed_infos
;
sinfo
=
msg
->
signed_infos
;
if
(
!
sinfo
)
goto
inconsistent
;
if
(
sinfo
->
authattrs
)
{
if
(
sinfo
->
authattrs
)
{
want
=
true
;
want
=
true
;
msg
->
have_authattrs
=
true
;
msg
->
have_authattrs
=
true
;
...
...
fs/crypto/keyinfo.c
View file @
494b9ae7
...
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
...
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
goto
out
;
goto
out
;
}
}
ukp
=
user_key_payload_locked
(
keyring_key
);
ukp
=
user_key_payload_locked
(
keyring_key
);
if
(
!
ukp
)
{
/* key was revoked before we acquired its semaphore */
res
=
-
EKEYREVOKED
;
goto
out
;
}
if
(
ukp
->
datalen
!=
sizeof
(
struct
fscrypt_key
))
{
if
(
ukp
->
datalen
!=
sizeof
(
struct
fscrypt_key
))
{
res
=
-
EINVAL
;
res
=
-
EINVAL
;
goto
out
;
goto
out
;
...
...
fs/ecryptfs/ecryptfs_kernel.h
View file @
494b9ae7
...
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
...
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
static
inline
struct
ecryptfs_auth_tok
*
static
inline
struct
ecryptfs_auth_tok
*
ecryptfs_get_encrypted_key_payload_data
(
struct
key
*
key
)
ecryptfs_get_encrypted_key_payload_data
(
struct
key
*
key
)
{
{
if
(
key
->
type
==
&
key_type_encrypted
)
struct
encrypted_key_payload
*
payload
;
return
(
struct
ecryptfs_auth_tok
*
)
(
&
((
struct
encrypted_key_payload
*
)
key
->
payload
.
data
[
0
])
->
payload_data
);
if
(
key
->
type
!=
&
key_type_encrypted
)
else
return
NULL
;
return
NULL
;
payload
=
key
->
payload
.
data
[
0
];
if
(
!
payload
)
return
ERR_PTR
(
-
EKEYREVOKED
);
return
(
struct
ecryptfs_auth_tok
*
)
payload
->
payload_data
;
}
}
static
inline
struct
key
*
ecryptfs_get_encrypted_key
(
char
*
sig
)
static
inline
struct
key
*
ecryptfs_get_encrypted_key
(
char
*
sig
)
...
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
...
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
ecryptfs_get_key_payload_data
(
struct
key
*
key
)
ecryptfs_get_key_payload_data
(
struct
key
*
key
)
{
{
struct
ecryptfs_auth_tok
*
auth_tok
;
struct
ecryptfs_auth_tok
*
auth_tok
;
struct
user_key_payload
*
ukp
;
auth_tok
=
ecryptfs_get_encrypted_key_payload_data
(
key
);
auth_tok
=
ecryptfs_get_encrypted_key_payload_data
(
key
);
if
(
!
auth_tok
)
if
(
auth_tok
)
return
(
struct
ecryptfs_auth_tok
*
)
user_key_payload_locked
(
key
)
->
data
;
else
return
auth_tok
;
return
auth_tok
;
ukp
=
user_key_payload_locked
(
key
);
if
(
!
ukp
)
return
ERR_PTR
(
-
EKEYREVOKED
);
return
(
struct
ecryptfs_auth_tok
*
)
ukp
->
data
;
}
}
#define ECRYPTFS_MAX_KEYSET_SIZE 1024
#define ECRYPTFS_MAX_KEYSET_SIZE 1024
...
...
fs/ecryptfs/keystore.c
View file @
494b9ae7
...
@@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version)
...
@@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version)
* @auth_tok_key: key containing the authentication token
* @auth_tok_key: key containing the authentication token
* @auth_tok: authentication token
* @auth_tok: authentication token
*
*
* Returns zero on valid auth tok; -EINVAL otherwise
* Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
* -EKEYREVOKED if the key was revoked before we acquired its semaphore.
*/
*/
static
int
static
int
ecryptfs_verify_auth_tok_from_key
(
struct
key
*
auth_tok_key
,
ecryptfs_verify_auth_tok_from_key
(
struct
key
*
auth_tok_key
,
...
@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
...
@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
int
rc
=
0
;
int
rc
=
0
;
(
*
auth_tok
)
=
ecryptfs_get_key_payload_data
(
auth_tok_key
);
(
*
auth_tok
)
=
ecryptfs_get_key_payload_data
(
auth_tok_key
);
if
(
IS_ERR
(
*
auth_tok
))
{
rc
=
PTR_ERR
(
*
auth_tok
);
*
auth_tok
=
NULL
;
goto
out
;
}
if
(
ecryptfs_verify_version
((
*
auth_tok
)
->
version
))
{
if
(
ecryptfs_verify_version
((
*
auth_tok
)
->
version
))
{
printk
(
KERN_ERR
"Data structure version mismatch. Userspace "
printk
(
KERN_ERR
"Data structure version mismatch. Userspace "
"tools must match eCryptfs kernel module with major "
"tools must match eCryptfs kernel module with major "
...
...
fs/fscache/object-list.c
View file @
494b9ae7
...
@@ -331,6 +331,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
...
@@ -331,6 +331,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
rcu_read_lock
();
rcu_read_lock
();
confkey
=
user_key_payload_rcu
(
key
);
confkey
=
user_key_payload_rcu
(
key
);
if
(
!
confkey
)
{
/* key was revoked */
rcu_read_unlock
();
key_put
(
key
);
goto
no_config
;
}
buf
=
confkey
->
data
;
buf
=
confkey
->
data
;
for
(
len
=
confkey
->
datalen
-
1
;
len
>=
0
;
len
--
)
{
for
(
len
=
confkey
->
datalen
-
1
;
len
>=
0
;
len
--
)
{
...
...
include/linux/key.h
View file @
494b9ae7
...
@@ -138,6 +138,11 @@ struct key_restriction {
...
@@ -138,6 +138,11 @@ struct key_restriction {
struct
key_type
*
keytype
;
struct
key_type
*
keytype
;
};
};
enum
key_state
{
KEY_IS_UNINSTANTIATED
,
KEY_IS_POSITIVE
,
/* Positively instantiated */
};
/*****************************************************************************/
/*****************************************************************************/
/*
/*
* authentication token / access credential / keyring
* authentication token / access credential / keyring
...
@@ -169,6 +174,7 @@ struct key {
...
@@ -169,6 +174,7 @@ struct key {
* - may not match RCU dereferenced payload
* - may not match RCU dereferenced payload
* - payload should contain own length
* - payload should contain own length
*/
*/
short
state
;
/* Key state (+) or rejection error (-) */
#ifdef KEY_DEBUGGING
#ifdef KEY_DEBUGGING
unsigned
magic
;
unsigned
magic
;
...
@@ -176,18 +182,16 @@ struct key {
...
@@ -176,18 +182,16 @@ struct key {
#endif
#endif
unsigned
long
flags
;
/* status flags (change with bitops) */
unsigned
long
flags
;
/* status flags (change with bitops) */
#define KEY_FLAG_INSTANTIATED 0
/* set if key has been instantiated */
#define KEY_FLAG_DEAD 0
/* set if key type has been deleted */
#define KEY_FLAG_DEAD 1
/* set if key type has been deleted */
#define KEY_FLAG_REVOKED 1
/* set if key had been revoked */
#define KEY_FLAG_REVOKED 2
/* set if key had been revoked */
#define KEY_FLAG_IN_QUOTA 2
/* set if key consumes quota */
#define KEY_FLAG_IN_QUOTA 3
/* set if key consumes quota */
#define KEY_FLAG_USER_CONSTRUCT 3
/* set if key is being constructed in userspace */
#define KEY_FLAG_USER_CONSTRUCT 4
/* set if key is being constructed in userspace */
#define KEY_FLAG_ROOT_CAN_CLEAR 4
/* set if key can be cleared by root without permission */
#define KEY_FLAG_NEGATIVE 5
/* set if key is negative */
#define KEY_FLAG_INVALIDATED 5
/* set if key has been invalidated */
#define KEY_FLAG_ROOT_CAN_CLEAR 6
/* set if key can be cleared by root without permission */
#define KEY_FLAG_BUILTIN 6
/* set if key is built in to the kernel */
#define KEY_FLAG_INVALIDATED 7
/* set if key has been invalidated */
#define KEY_FLAG_ROOT_CAN_INVAL 7
/* set if key can be invalidated by root without permission */
#define KEY_FLAG_BUILTIN 8
/* set if key is built in to the kernel */
#define KEY_FLAG_KEEP 8
/* set if key should not be removed */
#define KEY_FLAG_ROOT_CAN_INVAL 9
/* set if key can be invalidated by root without permission */
#define KEY_FLAG_UID_KEYRING 9
/* set if key is a user or user session keyring */
#define KEY_FLAG_KEEP 10
/* set if key should not be removed */
#define KEY_FLAG_UID_KEYRING 11
/* set if key is a user or user session keyring */
/* the key type and key description string
/* the key type and key description string
* - the desc is used to match a key against search criteria
* - the desc is used to match a key against search criteria
...
@@ -213,7 +217,6 @@ struct key {
...
@@ -213,7 +217,6 @@ struct key {
struct
list_head
name_link
;
struct
list_head
name_link
;
struct
assoc_array
keys
;
struct
assoc_array
keys
;
};
};
int
reject_error
;
};
};
/* This is set on a keyring to restrict the addition of a link to a key
/* This is set on a keyring to restrict the addition of a link to a key
...
@@ -353,17 +356,27 @@ extern void key_set_timeout(struct key *, unsigned);
...
@@ -353,17 +356,27 @@ extern void key_set_timeout(struct key *, unsigned);
#define KEY_NEED_SETATTR 0x20
/* Require permission to change attributes */
#define KEY_NEED_SETATTR 0x20
/* Require permission to change attributes */
#define KEY_NEED_ALL 0x3f
/* All the above permissions */
#define KEY_NEED_ALL 0x3f
/* All the above permissions */
static
inline
short
key_read_state
(
const
struct
key
*
key
)
{
/* Barrier versus mark_key_instantiated(). */
return
smp_load_acquire
(
&
key
->
state
);
}
/**
/**
* key_is_
instantiated
- Determine if a key has been positively instantiated
* key_is_
positive
- Determine if a key has been positively instantiated
* @key: The key to check.
* @key: The key to check.
*
*
* Return true if the specified key has been positively instantiated, false
* Return true if the specified key has been positively instantiated, false
* otherwise.
* otherwise.
*/
*/
static
inline
bool
key_is_instantiated
(
const
struct
key
*
key
)
static
inline
bool
key_is_positive
(
const
struct
key
*
key
)
{
return
key_read_state
(
key
)
==
KEY_IS_POSITIVE
;
}
static
inline
bool
key_is_negative
(
const
struct
key
*
key
)
{
{
return
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
&&
return
key_read_state
(
key
)
<
0
;
!
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
);
}
}
#define dereference_key_rcu(KEY) \
#define dereference_key_rcu(KEY) \
...
...
lib/digsig.c
View file @
494b9ae7
...
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key,
...
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key,
down_read
(
&
key
->
sem
);
down_read
(
&
key
->
sem
);
ukp
=
user_key_payload_locked
(
key
);
ukp
=
user_key_payload_locked
(
key
);
if
(
!
ukp
)
{
/* key was revoked before we acquired its semaphore */
err
=
-
EKEYREVOKED
;
goto
err1
;
}
if
(
ukp
->
datalen
<
sizeof
(
*
pkh
))
if
(
ukp
->
datalen
<
sizeof
(
*
pkh
))
goto
err1
;
goto
err1
;
...
...
net/dns_resolver/dns_key.c
View file @
494b9ae7
...
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data)
...
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data)
static
void
dns_resolver_describe
(
const
struct
key
*
key
,
struct
seq_file
*
m
)
static
void
dns_resolver_describe
(
const
struct
key
*
key
,
struct
seq_file
*
m
)
{
{
seq_puts
(
m
,
key
->
description
);
seq_puts
(
m
,
key
->
description
);
if
(
key_is_
instantiated
(
key
))
{
if
(
key_is_
positive
(
key
))
{
int
err
=
PTR_ERR
(
key
->
payload
.
data
[
dns_key_error
]);
int
err
=
PTR_ERR
(
key
->
payload
.
data
[
dns_key_error
]);
if
(
err
)
if
(
err
)
...
...
security/keys/Kconfig
View file @
494b9ae7
...
@@ -45,6 +45,7 @@ config BIG_KEYS
...
@@ -45,6 +45,7 @@ config BIG_KEYS
bool "Large payload keys"
bool "Large payload keys"
depends on KEYS
depends on KEYS
depends on TMPFS
depends on TMPFS
select CRYPTO
select CRYPTO_AES
select CRYPTO_AES
select CRYPTO_GCM
select CRYPTO_GCM
help
help
...
...
security/keys/big_key.c
View file @
494b9ae7
...
@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key)
...
@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key)
/* clear the quota */
/* clear the quota */
key_payload_reserve
(
key
,
0
);
key_payload_reserve
(
key
,
0
);
if
(
key_is_
instantiated
(
key
)
&&
if
(
key_is_
positive
(
key
)
&&
(
size_t
)
key
->
payload
.
data
[
big_key_len
]
>
BIG_KEY_FILE_THRESHOLD
)
(
size_t
)
key
->
payload
.
data
[
big_key_len
]
>
BIG_KEY_FILE_THRESHOLD
)
vfs_truncate
(
path
,
0
);
vfs_truncate
(
path
,
0
);
}
}
...
@@ -279,7 +279,7 @@ void big_key_describe(const struct key *key, struct seq_file *m)
...
@@ -279,7 +279,7 @@ void big_key_describe(const struct key *key, struct seq_file *m)
seq_puts
(
m
,
key
->
description
);
seq_puts
(
m
,
key
->
description
);
if
(
key_is_
instantiated
(
key
))
if
(
key_is_
positive
(
key
))
seq_printf
(
m
,
": %zu [%s]"
,
seq_printf
(
m
,
": %zu [%s]"
,
datalen
,
datalen
,
datalen
>
BIG_KEY_FILE_THRESHOLD
?
"file"
:
"buff"
);
datalen
>
BIG_KEY_FILE_THRESHOLD
?
"file"
:
"buff"
);
...
...
security/keys/encrypted-keys/encrypted.c
View file @
494b9ae7
...
@@ -309,6 +309,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
...
@@ -309,6 +309,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
down_read
(
&
ukey
->
sem
);
down_read
(
&
ukey
->
sem
);
upayload
=
user_key_payload_locked
(
ukey
);
upayload
=
user_key_payload_locked
(
ukey
);
if
(
!
upayload
)
{
/* key was revoked before we acquired its semaphore */
up_read
(
&
ukey
->
sem
);
key_put
(
ukey
);
ukey
=
ERR_PTR
(
-
EKEYREVOKED
);
goto
error
;
}
*
master_key
=
upayload
->
data
;
*
master_key
=
upayload
->
data
;
*
master_keylen
=
upayload
->
datalen
;
*
master_keylen
=
upayload
->
datalen
;
error:
error:
...
@@ -847,7 +854,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
...
@@ -847,7 +854,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
size_t
datalen
=
prep
->
datalen
;
size_t
datalen
=
prep
->
datalen
;
int
ret
=
0
;
int
ret
=
0
;
if
(
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
))
if
(
key_is_negative
(
key
))
return
-
ENOKEY
;
return
-
ENOKEY
;
if
(
datalen
<=
0
||
datalen
>
32767
||
!
prep
->
data
)
if
(
datalen
<=
0
||
datalen
>
32767
||
!
prep
->
data
)
return
-
EINVAL
;
return
-
EINVAL
;
...
...
security/keys/gc.c
View file @
494b9ae7
...
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
...
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
while
(
!
list_empty
(
keys
))
{
while
(
!
list_empty
(
keys
))
{
struct
key
*
key
=
struct
key
*
key
=
list_entry
(
keys
->
next
,
struct
key
,
graveyard_link
);
list_entry
(
keys
->
next
,
struct
key
,
graveyard_link
);
short
state
=
key
->
state
;
list_del
(
&
key
->
graveyard_link
);
list_del
(
&
key
->
graveyard_link
);
kdebug
(
"- %u"
,
key
->
serial
);
kdebug
(
"- %u"
,
key
->
serial
);
key_check
(
key
);
key_check
(
key
);
/* Throw away the key data if the key is instantiated */
/* Throw away the key data if the key is instantiated */
if
(
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
&&
if
(
state
==
KEY_IS_POSITIVE
&&
key
->
type
->
destroy
)
!
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
)
&&
key
->
type
->
destroy
)
key
->
type
->
destroy
(
key
);
key
->
type
->
destroy
(
key
);
security_key_free
(
key
);
security_key_free
(
key
);
...
@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
...
@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
}
}
atomic_dec
(
&
key
->
user
->
nkeys
);
atomic_dec
(
&
key
->
user
->
nkeys
);
if
(
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
)
if
(
state
!=
KEY_IS_UNINSTANTIATED
)
atomic_dec
(
&
key
->
user
->
nikeys
);
atomic_dec
(
&
key
->
user
->
nikeys
);
key_user_put
(
key
->
user
);
key_user_put
(
key
->
user
);
...
...
security/keys/key.c
View file @
494b9ae7
...
@@ -401,6 +401,18 @@ int key_payload_reserve(struct key *key, size_t datalen)
...
@@ -401,6 +401,18 @@ int key_payload_reserve(struct key *key, size_t datalen)
}
}
EXPORT_SYMBOL
(
key_payload_reserve
);
EXPORT_SYMBOL
(
key_payload_reserve
);
/*
* Change the key state to being instantiated.
*/
static
void
mark_key_instantiated
(
struct
key
*
key
,
int
reject_error
)
{
/* Commit the payload before setting the state; barrier versus
* key_read_state().
*/
smp_store_release
(
&
key
->
state
,
(
reject_error
<
0
)
?
reject_error
:
KEY_IS_POSITIVE
);
}
/*
/*
* Instantiate a key and link it into the target keyring atomically. Must be
* Instantiate a key and link it into the target keyring atomically. Must be
* called with the target keyring's semaphore writelocked. The target key's
* called with the target keyring's semaphore writelocked. The target key's
...
@@ -424,14 +436,14 @@ static int __key_instantiate_and_link(struct key *key,
...
@@ -424,14 +436,14 @@ static int __key_instantiate_and_link(struct key *key,
mutex_lock
(
&
key_construction_mutex
);
mutex_lock
(
&
key_construction_mutex
);
/* can't instantiate twice */
/* can't instantiate twice */
if
(
!
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
)
{
if
(
key
->
state
==
KEY_IS_UNINSTANTIATED
)
{
/* instantiate the key */
/* instantiate the key */
ret
=
key
->
type
->
instantiate
(
key
,
prep
);
ret
=
key
->
type
->
instantiate
(
key
,
prep
);
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
/* mark the key as being instantiated */
/* mark the key as being instantiated */
atomic_inc
(
&
key
->
user
->
nikeys
);
atomic_inc
(
&
key
->
user
->
nikeys
);
set_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
);
mark_key_instantiated
(
key
,
0
);
if
(
test_and_clear_bit
(
KEY_FLAG_USER_CONSTRUCT
,
&
key
->
flags
))
if
(
test_and_clear_bit
(
KEY_FLAG_USER_CONSTRUCT
,
&
key
->
flags
))
awaken
=
1
;
awaken
=
1
;
...
@@ -577,13 +589,10 @@ int key_reject_and_link(struct key *key,
...
@@ -577,13 +589,10 @@ int key_reject_and_link(struct key *key,
mutex_lock
(
&
key_construction_mutex
);
mutex_lock
(
&
key_construction_mutex
);
/* can't instantiate twice */
/* can't instantiate twice */
if
(
!
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
)
{
if
(
key
->
state
==
KEY_IS_UNINSTANTIATED
)
{
/* mark the key as being negatively instantiated */
/* mark the key as being negatively instantiated */
atomic_inc
(
&
key
->
user
->
nikeys
);
atomic_inc
(
&
key
->
user
->
nikeys
);
key
->
reject_error
=
-
error
;
mark_key_instantiated
(
key
,
-
error
);
smp_wmb
();
set_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
);
set_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
);
now
=
current_kernel_time
();
now
=
current_kernel_time
();
key
->
expiry
=
now
.
tv_sec
+
timeout
;
key
->
expiry
=
now
.
tv_sec
+
timeout
;
key_schedule_gc
(
key
->
expiry
+
key_gc_delay
);
key_schedule_gc
(
key
->
expiry
+
key_gc_delay
);
...
@@ -752,8 +761,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
...
@@ -752,8 +761,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
ret
=
key
->
type
->
update
(
key
,
prep
);
ret
=
key
->
type
->
update
(
key
,
prep
);
if
(
ret
==
0
)
if
(
ret
==
0
)
/*
updating a negative ke
y instantiates it */
/*
Updating a negative key positivel
y instantiates it */
clear_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
);
mark_key_instantiated
(
key
,
0
);
up_write
(
&
key
->
sem
);
up_write
(
&
key
->
sem
);
...
@@ -936,6 +945,16 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
...
@@ -936,6 +945,16 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
*/
*/
__key_link_end
(
keyring
,
&
index_key
,
edit
);
__key_link_end
(
keyring
,
&
index_key
,
edit
);
key
=
key_ref_to_ptr
(
key_ref
);
if
(
test_bit
(
KEY_FLAG_USER_CONSTRUCT
,
&
key
->
flags
))
{
ret
=
wait_for_key_construction
(
key
,
true
);
if
(
ret
<
0
)
{
key_ref_put
(
key_ref
);
key_ref
=
ERR_PTR
(
ret
);
goto
error_free_prep
;
}
}
key_ref
=
__key_update
(
key_ref
,
&
prep
);
key_ref
=
__key_update
(
key_ref
,
&
prep
);
goto
error_free_prep
;
goto
error_free_prep
;
}
}
...
@@ -986,8 +1005,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
...
@@ -986,8 +1005,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
ret
=
key
->
type
->
update
(
key
,
&
prep
);
ret
=
key
->
type
->
update
(
key
,
&
prep
);
if
(
ret
==
0
)
if
(
ret
==
0
)
/*
updating a negative ke
y instantiates it */
/*
Updating a negative key positivel
y instantiates it */
clear_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
);
mark_key_instantiated
(
key
,
0
);
up_write
(
&
key
->
sem
);
up_write
(
&
key
->
sem
);
...
...
security/keys/keyctl.c
View file @
494b9ae7
...
@@ -766,10 +766,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
...
@@ -766,10 +766,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
key
=
key_ref_to_ptr
(
key_ref
);
key
=
key_ref_to_ptr
(
key_ref
);
if
(
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
))
{
ret
=
key_read_state
(
key
);
ret
=
-
ENOKEY
;
if
(
ret
<
0
)
goto
error2
;
goto
error2
;
/* Negatively instantiated */
}
/* see if we can read it directly */
/* see if we can read it directly */
ret
=
key_permission
(
key_ref
,
KEY_NEED_READ
);
ret
=
key_permission
(
key_ref
,
KEY_NEED_READ
);
...
@@ -901,7 +900,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
...
@@ -901,7 +900,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
atomic_dec
(
&
key
->
user
->
nkeys
);
atomic_dec
(
&
key
->
user
->
nkeys
);
atomic_inc
(
&
newowner
->
nkeys
);
atomic_inc
(
&
newowner
->
nkeys
);
if
(
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
)
{
if
(
key
->
state
!=
KEY_IS_UNINSTANTIATED
)
{
atomic_dec
(
&
key
->
user
->
nikeys
);
atomic_dec
(
&
key
->
user
->
nikeys
);
atomic_inc
(
&
newowner
->
nikeys
);
atomic_inc
(
&
newowner
->
nikeys
);
}
}
...
...
security/keys/keyring.c
View file @
494b9ae7
...
@@ -414,7 +414,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
...
@@ -414,7 +414,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
else
else
seq_puts
(
m
,
"[anon]"
);
seq_puts
(
m
,
"[anon]"
);
if
(
key_is_
instantiated
(
keyring
))
{
if
(
key_is_
positive
(
keyring
))
{
if
(
keyring
->
keys
.
nr_leaves_on_tree
!=
0
)
if
(
keyring
->
keys
.
nr_leaves_on_tree
!=
0
)
seq_printf
(
m
,
": %lu"
,
keyring
->
keys
.
nr_leaves_on_tree
);
seq_printf
(
m
,
": %lu"
,
keyring
->
keys
.
nr_leaves_on_tree
);
else
else
...
@@ -553,7 +553,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
...
@@ -553,7 +553,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
{
{
struct
keyring_search_context
*
ctx
=
iterator_data
;
struct
keyring_search_context
*
ctx
=
iterator_data
;
const
struct
key
*
key
=
keyring_ptr_to_key
(
object
);
const
struct
key
*
key
=
keyring_ptr_to_key
(
object
);
unsigned
long
kflags
=
key
->
flags
;
unsigned
long
kflags
=
READ_ONCE
(
key
->
flags
);
short
state
=
READ_ONCE
(
key
->
state
);
kenter
(
"{%d}"
,
key
->
serial
);
kenter
(
"{%d}"
,
key
->
serial
);
...
@@ -565,6 +566,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
...
@@ -565,6 +566,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
/* skip invalidated, revoked and expired keys */
/* skip invalidated, revoked and expired keys */
if
(
ctx
->
flags
&
KEYRING_SEARCH_DO_STATE_CHECK
)
{
if
(
ctx
->
flags
&
KEYRING_SEARCH_DO_STATE_CHECK
)
{
time_t
expiry
=
READ_ONCE
(
key
->
expiry
);
if
(
kflags
&
((
1
<<
KEY_FLAG_INVALIDATED
)
|
if
(
kflags
&
((
1
<<
KEY_FLAG_INVALIDATED
)
|
(
1
<<
KEY_FLAG_REVOKED
)))
{
(
1
<<
KEY_FLAG_REVOKED
)))
{
ctx
->
result
=
ERR_PTR
(
-
EKEYREVOKED
);
ctx
->
result
=
ERR_PTR
(
-
EKEYREVOKED
);
...
@@ -572,7 +575,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
...
@@ -572,7 +575,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
goto
skipped
;
goto
skipped
;
}
}
if
(
key
->
expiry
&&
ctx
->
now
.
tv_sec
>=
key
->
expiry
)
{
if
(
expiry
&&
ctx
->
now
.
tv_sec
>=
expiry
)
{
if
(
!
(
ctx
->
flags
&
KEYRING_SEARCH_SKIP_EXPIRED
))
if
(
!
(
ctx
->
flags
&
KEYRING_SEARCH_SKIP_EXPIRED
))
ctx
->
result
=
ERR_PTR
(
-
EKEYEXPIRED
);
ctx
->
result
=
ERR_PTR
(
-
EKEYEXPIRED
);
kleave
(
" = %d [expire]"
,
ctx
->
skipped_ret
);
kleave
(
" = %d [expire]"
,
ctx
->
skipped_ret
);
...
@@ -597,9 +600,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
...
@@ -597,9 +600,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
if
(
ctx
->
flags
&
KEYRING_SEARCH_DO_STATE_CHECK
)
{
if
(
ctx
->
flags
&
KEYRING_SEARCH_DO_STATE_CHECK
)
{
/* we set a different error code if we pass a negative key */
/* we set a different error code if we pass a negative key */
if
(
kflags
&
(
1
<<
KEY_FLAG_NEGATIVE
))
{
if
(
state
<
0
)
{
smp_rmb
();
ctx
->
result
=
ERR_PTR
(
state
);
ctx
->
result
=
ERR_PTR
(
key
->
reject_error
);
kleave
(
" = %d [neg]"
,
ctx
->
skipped_ret
);
kleave
(
" = %d [neg]"
,
ctx
->
skipped_ret
);
goto
skipped
;
goto
skipped
;
}
}
...
...
security/keys/permission.c
View file @
494b9ae7
...
@@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission);
...
@@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission);
*/
*/
int
key_validate
(
const
struct
key
*
key
)
int
key_validate
(
const
struct
key
*
key
)
{
{
unsigned
long
flags
=
key
->
flags
;
unsigned
long
flags
=
READ_ONCE
(
key
->
flags
);
time_t
expiry
=
READ_ONCE
(
key
->
expiry
);
if
(
flags
&
(
1
<<
KEY_FLAG_INVALIDATED
))
if
(
flags
&
(
1
<<
KEY_FLAG_INVALIDATED
))
return
-
ENOKEY
;
return
-
ENOKEY
;
...
@@ -99,9 +100,9 @@ int key_validate(const struct key *key)
...
@@ -99,9 +100,9 @@ int key_validate(const struct key *key)
return
-
EKEYREVOKED
;
return
-
EKEYREVOKED
;
/* check it hasn't expired */
/* check it hasn't expired */
if
(
key
->
expiry
)
{
if
(
expiry
)
{
struct
timespec
now
=
current_kernel_time
();
struct
timespec
now
=
current_kernel_time
();
if
(
now
.
tv_sec
>=
key
->
expiry
)
if
(
now
.
tv_sec
>=
expiry
)
return
-
EKEYEXPIRED
;
return
-
EKEYEXPIRED
;
}
}
...
...
security/keys/proc.c
View file @
494b9ae7
...
@@ -179,9 +179,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
...
@@ -179,9 +179,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
struct
rb_node
*
_p
=
v
;
struct
rb_node
*
_p
=
v
;
struct
key
*
key
=
rb_entry
(
_p
,
struct
key
,
serial_node
);
struct
key
*
key
=
rb_entry
(
_p
,
struct
key
,
serial_node
);
struct
timespec
now
;
struct
timespec
now
;
time_t
expiry
;
unsigned
long
timo
;
unsigned
long
timo
;
unsigned
long
flags
;
key_ref_t
key_ref
,
skey_ref
;
key_ref_t
key_ref
,
skey_ref
;
char
xbuf
[
16
];
char
xbuf
[
16
];
short
state
;
int
rc
;
int
rc
;
struct
keyring_search_context
ctx
=
{
struct
keyring_search_context
ctx
=
{
...
@@ -217,12 +220,13 @@ static int proc_keys_show(struct seq_file *m, void *v)
...
@@ -217,12 +220,13 @@ static int proc_keys_show(struct seq_file *m, void *v)
rcu_read_lock
();
rcu_read_lock
();
/* come up with a suitable timeout value */
/* come up with a suitable timeout value */
if
(
key
->
expiry
==
0
)
{
expiry
=
READ_ONCE
(
key
->
expiry
);
if
(
expiry
==
0
)
{
memcpy
(
xbuf
,
"perm"
,
5
);
memcpy
(
xbuf
,
"perm"
,
5
);
}
else
if
(
now
.
tv_sec
>=
key
->
expiry
)
{
}
else
if
(
now
.
tv_sec
>=
expiry
)
{
memcpy
(
xbuf
,
"expd"
,
5
);
memcpy
(
xbuf
,
"expd"
,
5
);
}
else
{
}
else
{
timo
=
key
->
expiry
-
now
.
tv_sec
;
timo
=
expiry
-
now
.
tv_sec
;
if
(
timo
<
60
)
if
(
timo
<
60
)
sprintf
(
xbuf
,
"%lus"
,
timo
);
sprintf
(
xbuf
,
"%lus"
,
timo
);
...
@@ -236,18 +240,21 @@ static int proc_keys_show(struct seq_file *m, void *v)
...
@@ -236,18 +240,21 @@ static int proc_keys_show(struct seq_file *m, void *v)
sprintf
(
xbuf
,
"%luw"
,
timo
/
(
60
*
60
*
24
*
7
));
sprintf
(
xbuf
,
"%luw"
,
timo
/
(
60
*
60
*
24
*
7
));
}
}
#define showflag(KEY, LETTER, FLAG) \
state
=
key_read_state
(
key
);
(test_bit(FLAG, &(KEY)->flags) ? LETTER : '-')
#define showflag(FLAGS, LETTER, FLAG) \
((FLAGS & (1 << FLAG)) ? LETTER : '-')
flags
=
READ_ONCE
(
key
->
flags
);
seq_printf
(
m
,
"%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s "
,
seq_printf
(
m
,
"%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s "
,
key
->
serial
,
key
->
serial
,
s
howflag
(
key
,
'I'
,
KEY_FLAG_INSTANTIATED
)
,
s
tate
!=
KEY_IS_UNINSTANTIATED
?
'I'
:
'-'
,
showflag
(
key
,
'R'
,
KEY_FLAG_REVOKED
),
showflag
(
flags
,
'R'
,
KEY_FLAG_REVOKED
),
showflag
(
key
,
'D'
,
KEY_FLAG_DEAD
),
showflag
(
flags
,
'D'
,
KEY_FLAG_DEAD
),
showflag
(
key
,
'Q'
,
KEY_FLAG_IN_QUOTA
),
showflag
(
flags
,
'Q'
,
KEY_FLAG_IN_QUOTA
),
showflag
(
key
,
'U'
,
KEY_FLAG_USER_CONSTRUCT
),
showflag
(
flags
,
'U'
,
KEY_FLAG_USER_CONSTRUCT
),
s
howflag
(
key
,
'N'
,
KEY_FLAG_NEGATIVE
)
,
s
tate
<
0
?
'N'
:
'-'
,
showflag
(
key
,
'i'
,
KEY_FLAG_INVALIDATED
),
showflag
(
flags
,
'i'
,
KEY_FLAG_INVALIDATED
),
refcount_read
(
&
key
->
usage
),
refcount_read
(
&
key
->
usage
),
xbuf
,
xbuf
,
key
->
perm
,
key
->
perm
,
...
...
security/keys/process_keys.c
View file @
494b9ae7
...
@@ -730,7 +730,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
...
@@ -730,7 +730,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
ret
=
-
EIO
;
ret
=
-
EIO
;
if
(
!
(
lflags
&
KEY_LOOKUP_PARTIAL
)
&&
if
(
!
(
lflags
&
KEY_LOOKUP_PARTIAL
)
&&
!
test_bit
(
KEY_FLAG_INSTANTIATED
,
&
key
->
flags
)
)
key_read_state
(
key
)
==
KEY_IS_UNINSTANTIATED
)
goto
invalid_key
;
goto
invalid_key
;
/* check the permissions */
/* check the permissions */
...
...
security/keys/request_key.c
View file @
494b9ae7
...
@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr)
...
@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr)
intr
?
TASK_INTERRUPTIBLE
:
TASK_UNINTERRUPTIBLE
);
intr
?
TASK_INTERRUPTIBLE
:
TASK_UNINTERRUPTIBLE
);
if
(
ret
)
if
(
ret
)
return
-
ERESTARTSYS
;
return
-
ERESTARTSYS
;
if
(
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
))
{
ret
=
key_read_state
(
key
);
smp_rmb
();
if
(
ret
<
0
)
return
key
->
reject_error
;
return
ret
;
}
return
key_validate
(
key
);
return
key_validate
(
key
);
}
}
EXPORT_SYMBOL
(
wait_for_key_construction
);
EXPORT_SYMBOL
(
wait_for_key_construction
);
...
...
security/keys/request_key_auth.c
View file @
494b9ae7
...
@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key,
...
@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key,
seq_puts
(
m
,
"key:"
);
seq_puts
(
m
,
"key:"
);
seq_puts
(
m
,
key
->
description
);
seq_puts
(
m
,
key
->
description
);
if
(
key_is_
instantiated
(
key
))
if
(
key_is_
positive
(
key
))
seq_printf
(
m
,
" pid:%d ci:%zu"
,
rka
->
pid
,
rka
->
callout_len
);
seq_printf
(
m
,
" pid:%d ci:%zu"
,
rka
->
pid
,
rka
->
callout_len
);
}
}
...
...
security/keys/trusted.c
View file @
494b9ae7
...
@@ -1066,7 +1066,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
...
@@ -1066,7 +1066,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
char
*
datablob
;
char
*
datablob
;
int
ret
=
0
;
int
ret
=
0
;
if
(
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
))
if
(
key_is_negative
(
key
))
return
-
ENOKEY
;
return
-
ENOKEY
;
p
=
key
->
payload
.
data
[
0
];
p
=
key
->
payload
.
data
[
0
];
if
(
!
p
->
migratable
)
if
(
!
p
->
migratable
)
...
...
security/keys/user_defined.c
View file @
494b9ae7
...
@@ -114,7 +114,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
...
@@ -114,7 +114,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
/* attach the new data, displacing the old */
/* attach the new data, displacing the old */
key
->
expiry
=
prep
->
expiry
;
key
->
expiry
=
prep
->
expiry
;
if
(
!
test_bit
(
KEY_FLAG_NEGATIVE
,
&
key
->
flags
))
if
(
key_is_positive
(
key
))
zap
=
dereference_key_locked
(
key
);
zap
=
dereference_key_locked
(
key
);
rcu_assign_keypointer
(
key
,
prep
->
payload
.
data
[
0
]);
rcu_assign_keypointer
(
key
,
prep
->
payload
.
data
[
0
]);
prep
->
payload
.
data
[
0
]
=
NULL
;
prep
->
payload
.
data
[
0
]
=
NULL
;
...
@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy);
...
@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy);
void
user_describe
(
const
struct
key
*
key
,
struct
seq_file
*
m
)
void
user_describe
(
const
struct
key
*
key
,
struct
seq_file
*
m
)
{
{
seq_puts
(
m
,
key
->
description
);
seq_puts
(
m
,
key
->
description
);
if
(
key_is_
instantiated
(
key
))
if
(
key_is_
positive
(
key
))
seq_printf
(
m
,
": %u"
,
key
->
datalen
);
seq_printf
(
m
,
": %u"
,
key
->
datalen
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment