• David Howells's avatar
    KEYS: Do LRU discard in full keyrings · 31d5a79d
    David Howells authored
    Do an LRU discard in keyrings that are full rather than returning ENFILE.  To
    perform this, a time_t is added to the key struct and updated by the creation
    of a link to a key and by a key being found as the result of a search.  At the
    completion of a successful search, the keyrings in the path between the root of
    the search and the first found link to it also have their last-used times
    updated.
    
    Note that discarding a link to a key from a keyring does not necessarily
    destroy the key as there may be references held by other places.
    
    An alternate discard method that might suffice is to perform FIFO discard from
    the keyring, using the spare 2-byte hole in the keylist header as the index of
    the next link to be discarded.
    
    This is useful when using a keyring as a cache for DNS results or foreign
    filesystem IDs.
    
    
    This can be tested by the following.  As root do:
    
    	echo 1000 >/proc/sys/kernel/keys/root_maxkeys
    
    	kr=`keyctl newring foo @s`
    	for ((i=0; i<2000; i++)); do keyctl add user a$i a $kr; done
    
    Without this patch ENFILE should be reported when the keyring fills up.  With
    this patch, the keyring discards keys in an LRU fashion.  Note that the stored
    LRU time has a granularity of 1s.
    
    After doing this, /proc/key-users can be observed and should show that most of
    the 2000 keys have been discarded:
    
    	[root@andromeda ~]# cat /proc/key-users
    	    0:   517 516/516 513/1000 5249/20000
    
    The "513/1000" here is the number of quota-accounted keys present for this user
    out of the maximum permitted.
    
    In /proc/keys, the keyring shows the number of keys it has and the number of
    slots it has allocated:
    
    	[root@andromeda ~]# grep foo /proc/keys
    	200c64c4 I--Q--     1 perm 3b3f0000     0     0 keyring   foo: 509/509
    
    The maximum is (PAGE_SIZE - header) / key pointer size.  That's typically 509
    on a 64-bit system and 1020 on a 32-bit system.
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    31d5a79d
process_keys.c 20.7 KB