diff options
author | Elena Reshetova <elena.reshetova@intel.com> | 2017-05-02 10:16:05 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2017-05-02 10:16:05 -0400 |
commit | bd120ded6a6af61ad342a8a95b36b64bd1e2f9e6 (patch) | |
tree | 8e3c4a2e444669f6355c3ec69940f8489f5eecfd /kernel/audit_watch.c | |
parent | 9d2378f8c8f1a3fcfab681fd90c139d90dca7b69 (diff) |
audit: convert audit_watch.count from atomic_t to refcount_t
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
[PM: fix subject line, add #include]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'kernel/audit_watch.c')
-rw-r--r-- | kernel/audit_watch.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index e293165dd063..e0656bd63036 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/fsnotify_backend.h> | 28 | #include <linux/fsnotify_backend.h> |
29 | #include <linux/namei.h> | 29 | #include <linux/namei.h> |
30 | #include <linux/netlink.h> | 30 | #include <linux/netlink.h> |
31 | #include <linux/refcount.h> | ||
31 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
33 | #include <linux/security.h> | 34 | #include <linux/security.h> |
@@ -46,7 +47,7 @@ | |||
46 | */ | 47 | */ |
47 | 48 | ||
48 | struct audit_watch { | 49 | struct audit_watch { |
49 | atomic_t count; /* reference count */ | 50 | refcount_t count; /* reference count */ |
50 | dev_t dev; /* associated superblock device */ | 51 | dev_t dev; /* associated superblock device */ |
51 | char *path; /* insertion path */ | 52 | char *path; /* insertion path */ |
52 | unsigned long ino; /* associated inode number */ | 53 | unsigned long ino; /* associated inode number */ |
@@ -111,12 +112,12 @@ static inline struct audit_parent *audit_find_parent(struct inode *inode) | |||
111 | 112 | ||
112 | void audit_get_watch(struct audit_watch *watch) | 113 | void audit_get_watch(struct audit_watch *watch) |
113 | { | 114 | { |
114 | atomic_inc(&watch->count); | 115 | refcount_inc(&watch->count); |
115 | } | 116 | } |
116 | 117 | ||
117 | void audit_put_watch(struct audit_watch *watch) | 118 | void audit_put_watch(struct audit_watch *watch) |
118 | { | 119 | { |
119 | if (atomic_dec_and_test(&watch->count)) { | 120 | if (refcount_dec_and_test(&watch->count)) { |
120 | WARN_ON(watch->parent); | 121 | WARN_ON(watch->parent); |
121 | WARN_ON(!list_empty(&watch->rules)); | 122 | WARN_ON(!list_empty(&watch->rules)); |
122 | kfree(watch->path); | 123 | kfree(watch->path); |
@@ -178,7 +179,7 @@ static struct audit_watch *audit_init_watch(char *path) | |||
178 | return ERR_PTR(-ENOMEM); | 179 | return ERR_PTR(-ENOMEM); |
179 | 180 | ||
180 | INIT_LIST_HEAD(&watch->rules); | 181 | INIT_LIST_HEAD(&watch->rules); |
181 | atomic_set(&watch->count, 1); | 182 | refcount_set(&watch->count, 1); |
182 | watch->path = path; | 183 | watch->path = path; |
183 | watch->dev = AUDIT_DEV_UNSET; | 184 | watch->dev = AUDIT_DEV_UNSET; |
184 | watch->ino = AUDIT_INO_UNSET; | 185 | watch->ino = AUDIT_INO_UNSET; |