Skip to content

Commit

Permalink
Merge tag 'ASB-2022-07-05_12-5.10' of https://android.googlesource.co…
Browse files Browse the repository at this point in the history
…m/kernel/common into lineage-21

https://source.android.com/security/bulletin/2022-07-01
CVE-2020-29374
CVE-2022-20227

* tag 'ASB-2022-07-05_12-5.10' of https://android.googlesource.com/kernel/common:
  ANDROID: GKI: Add symbols to abi_gki_aarch64_transsion
  BACKPORT: nfc: nfcmrvl: main: reorder destructive operations in nfcmrvl_nci_unregister_dev to avoid bugs
  ANDROID: vendor_hook: Add hook in __free_pages()
  ANDROID: create and export is_swap_slot_cache_enabled
  ANDROID: vendor_hook: Add hook in swap_slots
  ANDROID: mm: export swapcache_free_entries
  ANDROID: mm: export symbols used in vendor hook android_vh_get_swap_page()
  ANDROID: vendor_hooks: Add hooks to extend struct swap_slots_cache
  ANDROID: mm: export swap_type_to_swap_info
  ANDROID: vendor_hook: Add hook in si_swapinfo()
  ANDROID: vendor_hooks: Add hooks to extend the struct swap_info_struct
  ANDROID: vendor_hook: Add hooks in unuse_pte_range() and try_to_unuse()
  ANDROID: vendor_hook: Add hooks in free_swap_slot()
  ANDROID: vendor_hook: Add hook to update nr_swap_pages and total_swap_pages
  ANDROID: vendor_hook: Add hook in page_referenced_one()
  ANDROID: vendor_hooks: Add hooks to record the I/O statistics of swap:
  ANDROID: vendor_hook: Add hook in migrate_page_states()
  ANDROID: vendor_hook: Add hook in __migration_entry_wait()
  ANDROID: vendor_hook: Add hook in handle_pte_fault()
  ANDROID: vendor_hook: Add hook in do_swap_page()
  ANDROID: vendor_hook: Add hook in wp_page_copy()
  ANDROID: vendor_hooks: Add hooks to madvise_cold_or_pageout_pte_range()
  ANDROID: vendor_hook: Add hook in snapshot_refaults()
  ANDROID: vendor_hook: Add hook in inactive_is_low()
  FROMGIT: usb: gadget: f_fs: change ep->ep safe in ffs_epfile_io()
  FROMGIT: usb: gadget: f_fs: change ep->status safe in ffs_epfile_io()
  ANDROID: GKI: forward declare struct cgroup_taskset in vendor hooks
  ANDROID: Fix build error with CONFIG_UCLAMP_TASK disabled
  ANDROID: GKI: include more type definitions in vendor hooks
  ANDROID: Update symbol list for mtk
  ANDROID: dma/debug: fix warning of check_sync
  FROMGIT: usb: common: usb-conn-gpio: Allow wakeup from system suspend
  BACKPORT: FROMLIST: usb: gadget: uvc: fix list double add in uvcg_video_pump
  BACKPORT: exfat: improve write performance when dirsync enabled
  FROMLIST: devcoredump : Serialize devcd_del work
  FROMGIT: usb: gadget: uvc: calculate the number of request depending on framesize
  ANDROID: GKI: Add tracing_is_on interface into symbol list
  UPSTREAM: usb: gadget: f_mass_storage: Make CD-ROM emulation work with Mac OS-X
  BACKPORT: io_uring: fix race between timeout flush and removal

Change-Id: Idf573019f8241cbd8e51c48acbf34d7bd59f6a2f
Signed-off-by: bengris32 <[email protected]>
  • Loading branch information
bengris32 committed Jun 21, 2024
2 parents f2db226 + b389838 commit b0dad26
Show file tree
Hide file tree
Showing 66 changed files with 3,752 additions and 2,109 deletions.
4,402 changes: 2,417 additions & 1,985 deletions android/abi_gki_aarch64.xml

Large diffs are not rendered by default.

634 changes: 627 additions & 7 deletions android/abi_gki_aarch64_mtk

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions android/abi_gki_aarch64_oplus
Original file line number Diff line number Diff line change
Expand Up @@ -3103,6 +3103,7 @@
trace_raw_output_prep
trace_seq_printf
trace_seq_putc
tracing_is_on
tracing_off
truncate_inode_pages_range
truncate_pagecache_range
Expand Down
8 changes: 8 additions & 0 deletions android/abi_gki_aarch64_transsion
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[abi_symbol_list]
get_mem_cgroup_from_mm
is_swap_slot_cache_enabled
swapcache_free_entries
swap_type_to_swap_info
scan_swap_map_slots
swap_alloc_cluster
check_cache_active
1 change: 1 addition & 0 deletions build.config.gki.aarch64
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ android/abi_gki_aarch64_virtual_device
android/abi_gki_aarch64_vivo
android/abi_gki_aarch64_xiaomi
android/abi_gki_aarch64_asus
android/abi_gki_aarch64_transsion
"

FILES="${FILES}
Expand Down
23 changes: 23 additions & 0 deletions drivers/android/vendor_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,26 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_tlb_conf);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_node_memcgs);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ra_tuning_max_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_memcg_scan_type);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_pte_fault_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cow_user_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swapin_add_anon_rmap);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_waiting_for_page_migration);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_migrate_page_states);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_referenced_one_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpin);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpout);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_swpout_vm_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swap_slot_cache_active);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_drain_slots_cache_cpu);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_swap_slot_cache);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_swap_slot);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_swap_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_inactive_is_low);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snapshot_refaults);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_account_swap_pages);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unuse_swap_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_init_swap_info_struct);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_si);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages);
83 changes: 81 additions & 2 deletions drivers/base/devcoredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,47 @@ struct devcd_entry {
struct device devcd_dev;
void *data;
size_t datalen;
/*
* Here, mutex is required to serialize the calls to del_wk work between
* user/kernel space which happens when devcd is added with device_add()
* and that sends uevent to user space. User space reads the uevents,
* and calls to devcd_data_write() which try to modify the work which is
* not even initialized/queued from devcoredump.
*
*
*
* cpu0(X) cpu1(Y)
*
* dev_coredump() uevent sent to user space
* device_add() ======================> user space process Y reads the
* uevents writes to devcd fd
* which results into writes to
*
* devcd_data_write()
* mod_delayed_work()
* try_to_grab_pending()
* del_timer()
* debug_assert_init()
* INIT_DELAYED_WORK()
* schedule_delayed_work()
*
*
* Also, mutex alone would not be enough to avoid scheduling of
* del_wk work after it get flush from a call to devcd_free()
* mentioned as below.
*
* disabled_store()
* devcd_free()
* mutex_lock() devcd_data_write()
* flush_delayed_work()
* mutex_unlock()
* mutex_lock()
* mod_delayed_work()
* mutex_unlock()
* So, delete_work flag is required.
*/
struct mutex mutex;
bool delete_work;
struct module *owner;
ssize_t (*read)(char *buffer, loff_t offset, size_t count,
void *data, size_t datalen);
Expand Down Expand Up @@ -88,7 +129,12 @@ static ssize_t devcd_data_write(struct file *filp, struct kobject *kobj,
struct device *dev = kobj_to_dev(kobj);
struct devcd_entry *devcd = dev_to_devcd(dev);

mod_delayed_work(system_wq, &devcd->del_wk, 0);
mutex_lock(&devcd->mutex);
if (!devcd->delete_work) {
devcd->delete_work = true;
mod_delayed_work(system_wq, &devcd->del_wk, 0);
}
mutex_unlock(&devcd->mutex);

return count;
}
Expand Down Expand Up @@ -116,7 +162,12 @@ static int devcd_free(struct device *dev, void *data)
{
struct devcd_entry *devcd = dev_to_devcd(dev);

mutex_lock(&devcd->mutex);
if (!devcd->delete_work)
devcd->delete_work = true;

flush_delayed_work(&devcd->del_wk);
mutex_unlock(&devcd->mutex);
return 0;
}

Expand All @@ -126,6 +177,30 @@ static ssize_t disabled_show(struct class *class, struct class_attribute *attr,
return sysfs_emit(buf, "%d\n", devcd_disabled);
}

/*
*
* disabled_store() worker()
* class_for_each_device(&devcd_class,
* NULL, NULL, devcd_free)
* ...
* ...
* while ((dev = class_dev_iter_next(&iter))
* devcd_del()
* device_del()
* put_device() <- last reference
* error = fn(dev, data) devcd_dev_release()
* devcd_free(dev, data) kfree(devcd)
* mutex_lock(&devcd->mutex);
*
*
* In the above diagram, It looks like disabled_store() would be racing with parallely
* running devcd_del() and result in memory abort while acquiring devcd->mutex which
* is called after kfree of devcd memory after dropping its last reference with
* put_device(). However, this will not happens as fn(dev, data) runs
* with its own reference to device via klist_node so it is not its last reference.
* so, above situation would not occur.
*/

static ssize_t disabled_store(struct class *class, struct class_attribute *attr,
const char *buf, size_t count)
{
Expand Down Expand Up @@ -282,13 +357,16 @@ void dev_coredumpm(struct device *dev, struct module *owner,
devcd->read = read;
devcd->free = free;
devcd->failing_dev = get_device(dev);
devcd->delete_work = false;

mutex_init(&devcd->mutex);
device_initialize(&devcd->devcd_dev);

dev_set_name(&devcd->devcd_dev, "devcd%d",
atomic_inc_return(&devcd_count));
devcd->devcd_dev.class = &devcd_class;

mutex_lock(&devcd->mutex);
if (device_add(&devcd->devcd_dev))
goto put_device;

Expand All @@ -302,10 +380,11 @@ void dev_coredumpm(struct device *dev, struct module *owner,

INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT);

mutex_unlock(&devcd->mutex);
return;
put_device:
put_device(&devcd->devcd_dev);
mutex_unlock(&devcd->mutex);
put_module:
module_put(owner);
free:
Expand Down
2 changes: 1 addition & 1 deletion drivers/nfc/nfcmrvl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
{
struct nci_dev *ndev = priv->ndev;

nci_unregister_device(ndev);
if (priv->ndev->nfc_dev->fw_download_in_progress)
nfcmrvl_fw_dnld_abort(priv);

Expand All @@ -202,7 +203,6 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
if (gpio_is_valid(priv->config.reset_n_io))
gpio_free(priv->config.reset_n_io);

nci_unregister_device(ndev);
nci_free_device(ndev);
kfree(priv);
}
Expand Down
17 changes: 17 additions & 0 deletions drivers/usb/common/usb-conn-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ static int usb_conn_probe(struct platform_device *pdev)
}

platform_set_drvdata(pdev, info);
device_set_wakeup_capable(&pdev->dev, true);

/* Perform initial detection */
usb_conn_queue_dwork(info, 0);
Expand Down Expand Up @@ -304,6 +305,14 @@ static int __maybe_unused usb_conn_suspend(struct device *dev)
{
struct usb_conn_info *info = dev_get_drvdata(dev);

if (device_may_wakeup(dev)) {
if (info->id_gpiod)
enable_irq_wake(info->id_irq);
if (info->vbus_gpiod)
enable_irq_wake(info->vbus_irq);
return 0;
}

if (info->id_gpiod)
disable_irq(info->id_irq);
if (info->vbus_gpiod)
Expand All @@ -318,6 +327,14 @@ static int __maybe_unused usb_conn_resume(struct device *dev)
{
struct usb_conn_info *info = dev_get_drvdata(dev);

if (device_may_wakeup(dev)) {
if (info->id_gpiod)
disable_irq_wake(info->id_irq);
if (info->vbus_gpiod)
disable_irq_wake(info->vbus_irq);
return 0;
}

pinctrl_pm_select_default_state(dev);

if (info->id_gpiod)
Expand Down
40 changes: 25 additions & 15 deletions drivers/usb/gadget/function/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ struct ffs_ep {
struct usb_endpoint_descriptor *descs[3];

u8 num;

int status; /* P: epfile->mutex */
};

struct ffs_epfile {
Expand Down Expand Up @@ -227,6 +225,9 @@ struct ffs_io_data {
bool use_sg;

struct ffs_data *ffs;

int status;
struct completion done;
};

struct ffs_desc_helper {
Expand Down Expand Up @@ -705,12 +706,15 @@ static const struct file_operations ffs_ep0_operations = {

static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)
{
struct ffs_io_data *io_data = req->context;

ENTER();
if (likely(req->context)) {
struct ffs_ep *ep = _ep->driver_data;
ep->status = req->status ? req->status : req->actual;
complete(req->context);
}
if (req->status)
io_data->status = req->status;
else
io_data->status = req->actual;

complete(&io_data->done);
}

static ssize_t ffs_copy_to_iter(void *data, int data_len, struct iov_iter *iter)
Expand Down Expand Up @@ -1048,7 +1052,6 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
WARN(1, "%s: data_len == -EINVAL\n", __func__);
ret = -EINVAL;
} else if (!io_data->aio) {
DECLARE_COMPLETION_ONSTACK(done);
bool interrupted = false;

req = ep->req;
Expand All @@ -1064,7 +1067,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)

io_data->buf = data;

req->context = &done;
init_completion(&io_data->done);
req->context = io_data;
req->complete = ffs_epfile_io_complete;

ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);
Expand All @@ -1073,25 +1077,31 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)

spin_unlock_irq(&epfile->ffs->eps_lock);

if (unlikely(wait_for_completion_interruptible(&done))) {
if (unlikely(wait_for_completion_interruptible(&io_data->done))) {
spin_lock_irq(&epfile->ffs->eps_lock);
if (epfile->ep != ep) {
ret = -ESHUTDOWN;
goto error_lock;
}
/*
* To avoid race condition with ffs_epfile_io_complete,
* dequeue the request first then check
* status. usb_ep_dequeue API should guarantee no race
* condition with req->complete callback.
*/
usb_ep_dequeue(ep->ep, req);
wait_for_completion(&done);
interrupted = ep->status < 0;
spin_unlock_irq(&epfile->ffs->eps_lock);
wait_for_completion(&io_data->done);
interrupted = io_data->status < 0;
}

if (interrupted)
ret = -EINTR;
else if (io_data->read && ep->status > 0)
ret = __ffs_epfile_read_data(epfile, data, ep->status,
else if (io_data->read && io_data->status > 0)
ret = __ffs_epfile_read_data(epfile, data, io_data->status,
&io_data->data);
else
ret = ep->status;
ret = io_data->status;
goto error_mutex;
} else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) {
ret = -ENOMEM;
Expand Down
Loading

0 comments on commit b0dad26

Please sign in to comment.