Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+55 -46
+21 -7
drivers/android/binder.c
··· 1934 1934 static void binder_transaction_buffer_release(struct binder_proc *proc, 1935 1935 struct binder_thread *thread, 1936 1936 struct binder_buffer *buffer, 1937 - binder_size_t failed_at, 1937 + binder_size_t off_end_offset, 1938 1938 bool is_failure) 1939 1939 { 1940 1940 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; 1942 1942 1943 1943 binder_debug(BINDER_DEBUG_TRANSACTION, 1944 1944 "%d buffer release %d, size %zd-%zd, failed at %llx\n", 1945 1945 proc->pid, buffer->debug_id, 1946 1946 buffer->data_size, buffer->offsets_size, 1947 - (unsigned long long)failed_at); 1947 + (unsigned long long)off_end_offset); 1948 1948 1949 1949 if (buffer->target_node) 1950 1950 binder_dec_node(buffer->target_node, 1, 0); 1951 1951 1952 1952 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 + 1955 1954 for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; 1956 1955 buffer_offset += sizeof(binder_size_t)) { 1957 1956 struct binder_object_header *hdr; ··· 2108 2109 break; 2109 2110 } 2110 2111 } 2112 + } 2113 + 2114 + /* Clean up all the objects in the buffer */ 2115 + static inline void binder_release_entire_buffer(struct binder_proc *proc, 2116 + struct binder_thread *thread, 2117 + struct binder_buffer *buffer, 2118 + bool is_failure) 2119 + { 2120 + binder_size_t off_end_offset; 2121 + 2122 + off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); 2123 + off_end_offset += buffer->offsets_size; 2124 + 2125 + binder_transaction_buffer_release(proc, thread, buffer, 2126 + off_end_offset, is_failure); 2111 2127 } 2112 2128 2113 2129 static int binder_translate_binder(struct flat_binder_object *fp, ··· 2820 2806 t_outdated->buffer = NULL; 2821 2807 buffer->transaction = NULL; 2822 2808 trace_binder_transaction_update_buffer_release(buffer); 2823 - binder_transaction_buffer_release(proc, NULL, buffer, 0, 0); 2809 + binder_release_entire_buffer(proc, NULL, buffer, false); 2824 2810 binder_alloc_free_buf(&proc->alloc, buffer); 2825 2811 kfree(t_outdated); 2826 2812 binder_stats_deleted(BINDER_STAT_TRANSACTION); ··· 3789 3775 binder_node_inner_unlock(buf_node); 3790 3776 } 3791 3777 trace_binder_transaction_buffer_release(buffer); 3792 - binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure); 3778 + binder_release_entire_buffer(proc, thread, buffer, is_failure); 3793 3779 binder_alloc_free_buf(&proc->alloc, buffer); 3794 3780 } 3795 3781
+29 -35
drivers/android/binder_alloc.c
··· 212 212 mm = alloc->mm; 213 213 214 214 if (mm) { 215 - mmap_read_lock(mm); 216 - vma = vma_lookup(mm, alloc->vma_addr); 215 + mmap_write_lock(mm); 216 + vma = alloc->vma; 217 217 } 218 218 219 219 if (!vma && need_mm) { ··· 270 270 trace_binder_alloc_page_end(alloc, index); 271 271 } 272 272 if (mm) { 273 - mmap_read_unlock(mm); 273 + mmap_write_unlock(mm); 274 274 mmput(mm); 275 275 } 276 276 return 0; ··· 303 303 } 304 304 err_no_vma: 305 305 if (mm) { 306 - mmap_read_unlock(mm); 306 + mmap_write_unlock(mm); 307 307 mmput(mm); 308 308 } 309 309 return vma ? -ENOMEM : -ESRCH; 310 310 } 311 311 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 + 312 319 static inline struct vm_area_struct *binder_alloc_get_vma( 313 320 struct binder_alloc *alloc) 314 321 { 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); 321 324 } 322 325 323 326 static bool debug_low_async_space_locked(struct binder_alloc *alloc, int pid) ··· 383 380 size_t size, data_offsets_size; 384 381 int ret; 385 382 386 - mmap_read_lock(alloc->mm); 383 + /* Check binder_alloc is fully initialized */ 387 384 if (!binder_alloc_get_vma(alloc)) { 388 - mmap_read_unlock(alloc->mm); 389 385 binder_alloc_debug(BINDER_DEBUG_USER_ERROR, 390 386 "%d: binder_alloc_buf, no vma\n", 391 387 alloc->pid); 392 388 return ERR_PTR(-ESRCH); 393 389 } 394 - mmap_read_unlock(alloc->mm); 395 390 396 391 data_offsets_size = ALIGN(data_size, sizeof(void *)) + 397 392 ALIGN(offsets_size, sizeof(void *)); ··· 779 778 buffer->free = 1; 780 779 binder_insert_free_buffer(alloc, buffer); 781 780 alloc->free_async_space = alloc->buffer_size / 2; 782 - alloc->vma_addr = vma->vm_start; 781 + 782 + /* Signal binder_alloc is fully initialized */ 783 + binder_alloc_set_vma(alloc, vma); 783 784 784 785 return 0; 785 786 ··· 811 808 812 809 buffers = 0; 813 810 mutex_lock(&alloc->mutex); 814 - BUG_ON(alloc->vma_addr && 815 - vma_lookup(alloc->mm, alloc->vma_addr)); 811 + BUG_ON(alloc->vma); 816 812 817 813 while ((n = rb_first(&alloc->allocated_buffers))) { 818 814 buffer = rb_entry(n, struct binder_buffer, rb_node); ··· 918 916 * Make sure the binder_alloc is fully initialized, otherwise we might 919 917 * read inconsistent state. 920 918 */ 921 - 922 - mmap_read_lock(alloc->mm); 923 - if (binder_alloc_get_vma(alloc) == NULL) { 924 - mmap_read_unlock(alloc->mm); 925 - goto uninitialized; 919 + if (binder_alloc_get_vma(alloc) != NULL) { 920 + for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { 921 + page = &alloc->pages[i]; 922 + if (!page->page_ptr) 923 + free++; 924 + else if (list_empty(&page->lru)) 925 + active++; 926 + else 927 + lru++; 928 + } 926 929 } 927 - 928 - mmap_read_unlock(alloc->mm); 929 - for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { 930 - page = &alloc->pages[i]; 931 - if (!page->page_ptr) 932 - free++; 933 - else if (list_empty(&page->lru)) 934 - active++; 935 - else 936 - lru++; 937 - } 938 - 939 - uninitialized: 940 930 mutex_unlock(&alloc->mutex); 941 931 seq_printf(m, " pages: %d:%d:%d\n", active, lru, free); 942 932 seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high); ··· 963 969 */ 964 970 void binder_alloc_vma_close(struct binder_alloc *alloc) 965 971 { 966 - alloc->vma_addr = 0; 972 + binder_alloc_set_vma(alloc, NULL); 967 973 } 968 974 969 975 /**
+2 -2
drivers/android/binder_alloc.h
··· 75 75 /** 76 76 * struct binder_alloc - per-binder proc state for binder allocator 77 77 * @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 79 79 * (invariant after mmap) 80 80 * @mm: copy of task->mm (invariant after open) 81 81 * @buffer: base of per-proc address space mapped via mmap ··· 99 99 */ 100 100 struct binder_alloc { 101 101 struct mutex mutex; 102 - unsigned long vma_addr; 102 + struct vm_area_struct *vma; 103 103 struct mm_struct *mm; 104 104 void __user *buffer; 105 105 struct list_head buffers;
+1 -1
drivers/android/binder_alloc_selftest.c
··· 287 287 if (!binder_selftest_run) 288 288 return; 289 289 mutex_lock(&binder_selftest_lock); 290 - if (!binder_selftest_run || !alloc->vma_addr) 290 + if (!binder_selftest_run || !alloc->vma) 291 291 goto done; 292 292 pr_info("STARTED\n"); 293 293 binder_selftest_alloc_offset(alloc, end_offset, 0);
+1
drivers/hwtracing/coresight/coresight-etm-perf.c
··· 402 402 trace_id = coresight_trace_id_get_cpu_id(cpu); 403 403 if (!IS_VALID_CS_TRACE_ID(trace_id)) { 404 404 cpumask_clear_cpu(cpu, mask); 405 + coresight_release_path(path); 405 406 continue; 406 407 } 407 408
+1 -1
drivers/hwtracing/coresight/coresight-tmc-etr.c
··· 942 942 943 943 len = tmc_etr_buf_get_data(etr_buf, offset, 944 944 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)) 946 946 return -EINVAL; 947 947 coresight_insert_barrier_packet(bufp); 948 948 return offset + CORESIGHT_BARRIER_PKT_SIZE;