forked from Minki/linux
0896cade12
atomic_t variables are currently used to implement reference counters with the following properties: - counter is initialized to 1 using atomic_set() - a resource is freed upon counter reaching zero - once counter reaches zero, its further increments aren't allowed - counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.) Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable. The variable nfs_cache_defer_req.count is used as pure reference counter. Convert it to refcount_t and fix up the operations. Suggested-by: Kees Cook <keescook@chromium.org> Reviewed-by: David Windsor <dwindsor@gmail.com> Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
32 lines
1018 B
C
32 lines
1018 B
C
/*
|
|
* Helper routines for the NFS client caches
|
|
*
|
|
* Copyright (c) 2009 Trond Myklebust <Trond.Myklebust@netapp.com>
|
|
*/
|
|
|
|
#include <linux/completion.h>
|
|
#include <linux/sunrpc/cache.h>
|
|
#include <linux/atomic.h>
|
|
|
|
/*
|
|
* Deferred request handling
|
|
*/
|
|
struct nfs_cache_defer_req {
|
|
struct cache_req req;
|
|
struct cache_deferred_req deferred_req;
|
|
struct completion completion;
|
|
refcount_t count;
|
|
};
|
|
|
|
extern int nfs_cache_upcall(struct cache_detail *cd, char *entry_name);
|
|
extern struct nfs_cache_defer_req *nfs_cache_defer_req_alloc(void);
|
|
extern void nfs_cache_defer_req_put(struct nfs_cache_defer_req *dreq);
|
|
extern int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq);
|
|
|
|
extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd);
|
|
extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd);
|
|
extern int nfs_cache_register_sb(struct super_block *sb,
|
|
struct cache_detail *cd);
|
|
extern void nfs_cache_unregister_sb(struct super_block *sb,
|
|
struct cache_detail *cd);
|