diff options
Diffstat (limited to 'security/keys/keyctl.c')
| -rw-r--r-- | security/keys/keyctl.c | 29 | 
1 files changed, 21 insertions, 8 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 6261745e445..b2b0998d6ab 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -505,13 +505,11 @@ okay:  	ret = snprintf(tmpbuf, PAGE_SIZE - 1,  		       "%s;%d;%d;%08x;%s", -		       key_ref_to_ptr(key_ref)->type->name, -		       key_ref_to_ptr(key_ref)->uid, -		       key_ref_to_ptr(key_ref)->gid, -		       key_ref_to_ptr(key_ref)->perm, -		       key_ref_to_ptr(key_ref)->description ? -		       key_ref_to_ptr(key_ref)->description : "" -		       ); +		       key->type->name, +		       key->uid, +		       key->gid, +		       key->perm, +		       key->description ?: "");  	/* include a NUL char at the end of the data */  	if (ret > PAGE_SIZE - 1) @@ -1091,7 +1089,7 @@ error:  long keyctl_set_timeout(key_serial_t id, unsigned timeout)  {  	struct timespec now; -	struct key *key; +	struct key *key, *instkey;  	key_ref_t key_ref;  	time_t expiry;  	long ret; @@ -1099,10 +1097,25 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)  	key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,  				  KEY_SETATTR);  	if (IS_ERR(key_ref)) { +		/* setting the timeout on a key under construction is permitted +		 * if we have the authorisation token handy */ +		if (PTR_ERR(key_ref) == -EACCES) { +			instkey = key_get_instantiation_authkey(id); +			if (!IS_ERR(instkey)) { +				key_put(instkey); +				key_ref = lookup_user_key(id, +							  KEY_LOOKUP_PARTIAL, +							  0); +				if (!IS_ERR(key_ref)) +					goto okay; +			} +		} +  		ret = PTR_ERR(key_ref);  		goto error;  	} +okay:  	key = key_ref_to_ptr(key_ref);  	/* make the changes with the locks held to prevent races */  |