diff options
author | Elena Reshetova <elena.reshetova@intel.com> | 2017-09-08 19:17:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-08 21:26:51 -0400 |
commit | f74370b86ec1e0ee8a56ba838efe78e21d8dba23 (patch) | |
tree | 5ecda3120c2c13915cf8e1d2ee570062465479ef | |
parent | a2e0602c36ed9fe042714694dd5a889ecd8cb556 (diff) |
ipc: convert sem_undo_list.refcnt 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.
Link: http://lkml.kernel.org/r/1499417992-3238-3-git-send-email-elena.reshetova@intel.com
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>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: <arozansk@redhat.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | ipc/sem.c | 8 |
1 files changed, 4 insertions, 4 deletions
@@ -122,7 +122,7 @@ struct sem_undo { | |||
122 | * that may be shared among all a CLONE_SYSVSEM task group. | 122 | * that may be shared among all a CLONE_SYSVSEM task group. |
123 | */ | 123 | */ |
124 | struct sem_undo_list { | 124 | struct sem_undo_list { |
125 | atomic_t refcnt; | 125 | refcount_t refcnt; |
126 | spinlock_t lock; | 126 | spinlock_t lock; |
127 | struct list_head list_proc; | 127 | struct list_head list_proc; |
128 | }; | 128 | }; |
@@ -1642,7 +1642,7 @@ static inline int get_undo_list(struct sem_undo_list **undo_listp) | |||
1642 | if (undo_list == NULL) | 1642 | if (undo_list == NULL) |
1643 | return -ENOMEM; | 1643 | return -ENOMEM; |
1644 | spin_lock_init(&undo_list->lock); | 1644 | spin_lock_init(&undo_list->lock); |
1645 | atomic_set(&undo_list->refcnt, 1); | 1645 | refcount_set(&undo_list->refcnt, 1); |
1646 | INIT_LIST_HEAD(&undo_list->list_proc); | 1646 | INIT_LIST_HEAD(&undo_list->list_proc); |
1647 | 1647 | ||
1648 | current->sysvsem.undo_list = undo_list; | 1648 | current->sysvsem.undo_list = undo_list; |
@@ -2041,7 +2041,7 @@ int copy_semundo(unsigned long clone_flags, struct task_struct *tsk) | |||
2041 | error = get_undo_list(&undo_list); | 2041 | error = get_undo_list(&undo_list); |
2042 | if (error) | 2042 | if (error) |
2043 | return error; | 2043 | return error; |
2044 | atomic_inc(&undo_list->refcnt); | 2044 | refcount_inc(&undo_list->refcnt); |
2045 | tsk->sysvsem.undo_list = undo_list; | 2045 | tsk->sysvsem.undo_list = undo_list; |
2046 | } else | 2046 | } else |
2047 | tsk->sysvsem.undo_list = NULL; | 2047 | tsk->sysvsem.undo_list = NULL; |
@@ -2070,7 +2070,7 @@ void exit_sem(struct task_struct *tsk) | |||
2070 | return; | 2070 | return; |
2071 | tsk->sysvsem.undo_list = NULL; | 2071 | tsk->sysvsem.undo_list = NULL; |
2072 | 2072 | ||
2073 | if (!atomic_dec_and_test(&ulp->refcnt)) | 2073 | if (!refcount_dec_and_test(&ulp->refcnt)) |
2074 | return; | 2074 | return; |
2075 | 2075 | ||
2076 | for (;;) { | 2076 | for (;;) { |