Skip to content

Commit 957f3f8

Browse files
committed
Merge tag 'char-misc-6.4-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc fixes from Greg KH: "Here are some small driver fixes for 6.4-rc4. They are just two different types: - binder fixes and reverts for reported problems and regressions in the binder "driver". - coresight driver fixes for reported problems. All of these have been in linux-next for over a week with no reported problems" * tag 'char-misc-6.4-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: binder: fix UAF of alloc->vma in race with munmap() binder: add lockless binder_alloc_(set|get)_vma() Revert "android: binder: stop saving a pointer to the VMA" Revert "binder_alloc: add missing mmap_lock calls when using the VMA" binder: fix UAF caused by faulty buffer cleanup coresight: perf: Release Coresight path when alloc trace id failed coresight: Fix signedness bug in tmc_etr_buf_insert_barrier_packet()
2 parents 49572d5 + d1d8875 commit 957f3f8

File tree

6 files changed

+55
-46
lines changed

6 files changed

+55
-46
lines changed

drivers/android/binder.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,24 +1934,23 @@ static void binder_deferred_fd_close(int fd)
19341934
static void binder_transaction_buffer_release(struct binder_proc *proc,
19351935
struct binder_thread *thread,
19361936
struct binder_buffer *buffer,
1937-
binder_size_t failed_at,
1937+
binder_size_t off_end_offset,
19381938
bool is_failure)
19391939
{
19401940
int debug_id = buffer->debug_id;
1941-
binder_size_t off_start_offset, buffer_offset, off_end_offset;
1941+
binder_size_t off_start_offset, buffer_offset;
19421942

19431943
binder_debug(BINDER_DEBUG_TRANSACTION,
19441944
"%d buffer release %d, size %zd-%zd, failed at %llx\n",
19451945
proc->pid, buffer->debug_id,
19461946
buffer->data_size, buffer->offsets_size,
1947-
(unsigned long long)failed_at);
1947+
(unsigned long long)off_end_offset);
19481948

19491949
if (buffer->target_node)
19501950
binder_dec_node(buffer->target_node, 1, 0);
19511951

19521952
off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
1953-
off_end_offset = is_failure && failed_at ? failed_at :
1954-
off_start_offset + buffer->offsets_size;
1953+
19551954
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
19561955
buffer_offset += sizeof(binder_size_t)) {
19571956
struct binder_object_header *hdr;
@@ -2111,6 +2110,21 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
21112110
}
21122111
}
21132112

2113+
/* Clean up all the objects in the buffer */
2114+
static inline void binder_release_entire_buffer(struct binder_proc *proc,
2115+
struct binder_thread *thread,
2116+
struct binder_buffer *buffer,
2117+
bool is_failure)
2118+
{
2119+
binder_size_t off_end_offset;
2120+
2121+
off_end_offset = ALIGN(buffer->data_size, sizeof(void *));
2122+
off_end_offset += buffer->offsets_size;
2123+
2124+
binder_transaction_buffer_release(proc, thread, buffer,
2125+
off_end_offset, is_failure);
2126+
}
2127+
21142128
static int binder_translate_binder(struct flat_binder_object *fp,
21152129
struct binder_transaction *t,
21162130
struct binder_thread *thread)
@@ -2806,7 +2820,7 @@ static int binder_proc_transaction(struct binder_transaction *t,
28062820
t_outdated->buffer = NULL;
28072821
buffer->transaction = NULL;
28082822
trace_binder_transaction_update_buffer_release(buffer);
2809-
binder_transaction_buffer_release(proc, NULL, buffer, 0, 0);
2823+
binder_release_entire_buffer(proc, NULL, buffer, false);
28102824
binder_alloc_free_buf(&proc->alloc, buffer);
28112825
kfree(t_outdated);
28122826
binder_stats_deleted(BINDER_STAT_TRANSACTION);
@@ -3775,7 +3789,7 @@ binder_free_buf(struct binder_proc *proc,
37753789
binder_node_inner_unlock(buf_node);
37763790
}
37773791
trace_binder_transaction_buffer_release(buffer);
3778-
binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);
3792+
binder_release_entire_buffer(proc, thread, buffer, is_failure);
37793793
binder_alloc_free_buf(&proc->alloc, buffer);
37803794
}
37813795

drivers/android/binder_alloc.c

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
212212
mm = alloc->mm;
213213

214214
if (mm) {
215-
mmap_read_lock(mm);
216-
vma = vma_lookup(mm, alloc->vma_addr);
215+
mmap_write_lock(mm);
216+
vma = alloc->vma;
217217
}
218218

219219
if (!vma && need_mm) {
@@ -270,7 +270,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
270270
trace_binder_alloc_page_end(alloc, index);
271271
}
272272
if (mm) {
273-
mmap_read_unlock(mm);
273+
mmap_write_unlock(mm);
274274
mmput(mm);
275275
}
276276
return 0;
@@ -303,21 +303,24 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
303303
}
304304
err_no_vma:
305305
if (mm) {
306-
mmap_read_unlock(mm);
306+
mmap_write_unlock(mm);
307307
mmput(mm);
308308
}
309309
return vma ? -ENOMEM : -ESRCH;
310310
}
311311

312+
static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
313+
struct vm_area_struct *vma)
314+
{
315+
/* pairs with smp_load_acquire in binder_alloc_get_vma() */
316+
smp_store_release(&alloc->vma, vma);
317+
}
318+
312319
static inline struct vm_area_struct *binder_alloc_get_vma(
313320
struct binder_alloc *alloc)
314321
{
315-
struct vm_area_struct *vma = NULL;
316-
317-
if (alloc->vma_addr)
318-
vma = vma_lookup(alloc->mm, alloc->vma_addr);
319-
320-
return vma;
322+
/* pairs with smp_store_release in binder_alloc_set_vma() */
323+
return smp_load_acquire(&alloc->vma);
321324
}
322325

323326
static bool debug_low_async_space_locked(struct binder_alloc *alloc, int pid)
@@ -380,15 +383,13 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
380383
size_t size, data_offsets_size;
381384
int ret;
382385

383-
mmap_read_lock(alloc->mm);
386+
/* Check binder_alloc is fully initialized */
384387
if (!binder_alloc_get_vma(alloc)) {
385-
mmap_read_unlock(alloc->mm);
386388
binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
387389
"%d: binder_alloc_buf, no vma\n",
388390
alloc->pid);
389391
return ERR_PTR(-ESRCH);
390392
}
391-
mmap_read_unlock(alloc->mm);
392393

393394
data_offsets_size = ALIGN(data_size, sizeof(void *)) +
394395
ALIGN(offsets_size, sizeof(void *));
@@ -778,7 +779,9 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
778779
buffer->free = 1;
779780
binder_insert_free_buffer(alloc, buffer);
780781
alloc->free_async_space = alloc->buffer_size / 2;
781-
alloc->vma_addr = vma->vm_start;
782+
783+
/* Signal binder_alloc is fully initialized */
784+
binder_alloc_set_vma(alloc, vma);
782785

783786
return 0;
784787

@@ -808,8 +811,7 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
808811

809812
buffers = 0;
810813
mutex_lock(&alloc->mutex);
811-
BUG_ON(alloc->vma_addr &&
812-
vma_lookup(alloc->mm, alloc->vma_addr));
814+
BUG_ON(alloc->vma);
813815

814816
while ((n = rb_first(&alloc->allocated_buffers))) {
815817
buffer = rb_entry(n, struct binder_buffer, rb_node);
@@ -916,25 +918,17 @@ void binder_alloc_print_pages(struct seq_file *m,
916918
* Make sure the binder_alloc is fully initialized, otherwise we might
917919
* read inconsistent state.
918920
*/
919-
920-
mmap_read_lock(alloc->mm);
921-
if (binder_alloc_get_vma(alloc) == NULL) {
922-
mmap_read_unlock(alloc->mm);
923-
goto uninitialized;
924-
}
925-
926-
mmap_read_unlock(alloc->mm);
927-
for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) {
928-
page = &alloc->pages[i];
929-
if (!page->page_ptr)
930-
free++;
931-
else if (list_empty(&page->lru))
932-
active++;
933-
else
934-
lru++;
921+
if (binder_alloc_get_vma(alloc) != NULL) {
922+
for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) {
923+
page = &alloc->pages[i];
924+
if (!page->page_ptr)
925+
free++;
926+
else if (list_empty(&page->lru))
927+
active++;
928+
else
929+
lru++;
930+
}
935931
}
936-
937-
uninitialized:
938932
mutex_unlock(&alloc->mutex);
939933
seq_printf(m, " pages: %d:%d:%d\n", active, lru, free);
940934
seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high);
@@ -969,7 +963,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
969963
*/
970964
void binder_alloc_vma_close(struct binder_alloc *alloc)
971965
{
972-
alloc->vma_addr = 0;
966+
binder_alloc_set_vma(alloc, NULL);
973967
}
974968

975969
/**

drivers/android/binder_alloc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct binder_lru_page {
7575
/**
7676
* struct binder_alloc - per-binder proc state for binder allocator
7777
* @mutex: protects binder_alloc fields
78-
* @vma_addr: vm_area_struct->vm_start passed to mmap_handler
78+
* @vma: vm_area_struct passed to mmap_handler
7979
* (invariant after mmap)
8080
* @mm: copy of task->mm (invariant after open)
8181
* @buffer: base of per-proc address space mapped via mmap
@@ -99,7 +99,7 @@ struct binder_lru_page {
9999
*/
100100
struct binder_alloc {
101101
struct mutex mutex;
102-
unsigned long vma_addr;
102+
struct vm_area_struct *vma;
103103
struct mm_struct *mm;
104104
void __user *buffer;
105105
struct list_head buffers;

drivers/android/binder_alloc_selftest.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ void binder_selftest_alloc(struct binder_alloc *alloc)
287287
if (!binder_selftest_run)
288288
return;
289289
mutex_lock(&binder_selftest_lock);
290-
if (!binder_selftest_run || !alloc->vma_addr)
290+
if (!binder_selftest_run || !alloc->vma)
291291
goto done;
292292
pr_info("STARTED\n");
293293
binder_selftest_alloc_offset(alloc, end_offset, 0);

drivers/hwtracing/coresight/coresight-etm-perf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
402402
trace_id = coresight_trace_id_get_cpu_id(cpu);
403403
if (!IS_VALID_CS_TRACE_ID(trace_id)) {
404404
cpumask_clear_cpu(cpu, mask);
405+
coresight_release_path(path);
405406
continue;
406407
}
407408

drivers/hwtracing/coresight/coresight-tmc-etr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ tmc_etr_buf_insert_barrier_packet(struct etr_buf *etr_buf, u64 offset)
942942

943943
len = tmc_etr_buf_get_data(etr_buf, offset,
944944
CORESIGHT_BARRIER_PKT_SIZE, &bufp);
945-
if (WARN_ON(len < CORESIGHT_BARRIER_PKT_SIZE))
945+
if (WARN_ON(len < 0 || len < CORESIGHT_BARRIER_PKT_SIZE))
946946
return -EINVAL;
947947
coresight_insert_barrier_packet(bufp);
948948
return offset + CORESIGHT_BARRIER_PKT_SIZE;

0 commit comments

Comments
 (0)