Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2d37d09 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge branch 'android11-5.4' into 'android11-5.4-lts'



Sync up with android11-5.4 for the following commits:

b0f930a5 BACKPORT: f2fs: relocate inline conversion from mmap() to mkwrite()
4f4602b7 BACKPORT: f2fs: support RO feature
e6fd4c5c BACKPORT: f2fs: fix wrong total_sections check and fsmeta check
ce664fbd BACKPORT: FROMGIT: binder: fix freeze race
b1232b02 FROMGIT: binder: BINDER_GET_FROZEN_INFO ioctl
a02d0f68 FROMGIT: binder: use EINTR for interrupted wait for work
e658e9e4 BACKPORT: FROMGIT: binder: BINDER_FREEZE ioctl
63ef4447 ANDROID: usb: gadget: f_accessory: Mitgate handling of non-existent USB request
50c9c8cb FROMGIT: binder: fix test regression due to sender_euid change
1c1f5718 BACKPORT: binder: use cred instead of task for getsecid
ea1a2391 BACKPORT: binder: use cred instead of task for selinux checks
1fe8a2bb BACKPORT: binder: use euid from cred instead of using task
a0800501 ANDROID: setlocalversion: make KMI_GENERATION optional
e785a25f Revert "ANDROID: GKI: Enable CHACHA20POLY1305 and XCBC"

Change-Id: Ica7d80e62dcd4b12f7294bcc4b5c9291491ad37b
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parents 0bbf0a06 b0f930a5
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -557,9 +557,7 @@ CONFIG_STATIC_USERMODEHELPER_PATH=""
CONFIG_SECURITY_SELINUX=y
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_CRYPTO_CHACHA20POLY1305=y
CONFIG_CRYPTO_ADIANTUM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_BLAKE2B=y
CONFIG_CRYPTO_LZ4=y
CONFIG_CRYPTO_ZSTD=y
+0 −2
Original line number Diff line number Diff line
@@ -485,9 +485,7 @@ CONFIG_STATIC_USERMODEHELPER_PATH=""
CONFIG_SECURITY_SELINUX=y
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_CRYPTO_CHACHA20POLY1305=y
CONFIG_CRYPTO_ADIANTUM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_BLAKE2B=y
CONFIG_CRYPTO_SHA256_SSSE3=y
CONFIG_CRYPTO_AES_NI_INTEL=y
+226 −20
Original line number Diff line number Diff line
@@ -1628,6 +1628,12 @@ static void binder_free_transaction(struct binder_transaction *t)

	if (target_proc) {
		binder_inner_proc_lock(target_proc);
		target_proc->outstanding_txns--;
		if (target_proc->outstanding_txns < 0)
			pr_warn("%s: Unexpected outstanding_txns %d\n",
				__func__, target_proc->outstanding_txns);
		if (!target_proc->outstanding_txns && target_proc->is_frozen)
			wake_up_interruptible_all(&target_proc->freeze_wait);
		if (t->buffer)
			t->buffer->transaction = NULL;
		binder_inner_proc_unlock(target_proc);
@@ -2168,7 +2174,8 @@ static int binder_translate_binder(struct flat_binder_object *fp,
		ret = -EINVAL;
		goto done;
	}
	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
	if (security_binder_transfer_binder(binder_get_cred(proc),
					    binder_get_cred(target_proc))) {
		ret = -EPERM;
		goto done;
	}
@@ -2214,7 +2221,8 @@ static int binder_translate_handle(struct flat_binder_object *fp,
				  proc->pid, thread->pid, fp->handle);
		return -EINVAL;
	}
	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
	if (security_binder_transfer_binder(binder_get_cred(proc),
					    binder_get_cred(target_proc))) {
		ret = -EPERM;
		goto done;
	}
@@ -2302,7 +2310,8 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
		ret = -EBADF;
		goto err_fget;
	}
	ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
	ret = security_binder_transfer_file(binder_get_cred(proc),
					    binder_get_cred(target_proc), file);
	if (ret < 0) {
		ret = -EPERM;
		goto err_security;
@@ -2458,10 +2467,11 @@ static int binder_fixup_parent(struct binder_transaction *t,
 * If the @thread parameter is not NULL, the transaction is always queued
 * to the waitlist of that specific thread.
 *
 * Return:	true if the transactions was successfully queued
 *		false if the target process or thread is dead
 * Return:	0 if the transaction was successfully queued
 *		BR_DEAD_REPLY if the target process or thread is dead
 *		BR_FROZEN_REPLY if the target process or thread is frozen
 */
static bool binder_proc_transaction(struct binder_transaction *t,
static int binder_proc_transaction(struct binder_transaction *t,
				    struct binder_proc *proc,
				    struct binder_thread *thread)
{
@@ -2485,11 +2495,16 @@ static bool binder_proc_transaction(struct binder_transaction *t,
	}

	binder_inner_proc_lock(proc);
	if (proc->is_frozen) {
		proc->sync_recv |= !oneway;
		proc->async_recv |= oneway;
	}

	if (proc->is_dead || (thread && thread->is_dead)) {
	if ((proc->is_frozen && !oneway) || proc->is_dead ||
			(thread && thread->is_dead)) {
		binder_inner_proc_unlock(proc);
		binder_node_unlock(node);
		return false;
		return proc->is_frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY;
	}

	if (!thread && !pending_async)
@@ -2508,10 +2523,11 @@ static bool binder_proc_transaction(struct binder_transaction *t,
	if (!pending_async)
		binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */);

	proc->outstanding_txns++;
	binder_inner_proc_unlock(proc);
	binder_node_unlock(node);

	return true;
	return 0;
}

/**
@@ -2701,8 +2717,8 @@ static void binder_transaction(struct binder_proc *proc,
			goto err_dead_binder;
		}
		e->to_node = target_node->debug_id;
		if (security_binder_transaction(proc->tsk,
						target_proc->tsk) < 0) {
		if (security_binder_transaction(binder_get_cred(proc),
						binder_get_cred(target_proc)) < 0) {
			return_error = BR_FAILED_REPLY;
			return_error_param = -EPERM;
			return_error_line = __LINE__;
@@ -2837,7 +2853,7 @@ static void binder_transaction(struct binder_proc *proc,
		u32 secid;
		size_t added_size;

		security_task_getsecid(proc->tsk, &secid);
		security_cred_getsecid(binder_get_cred(proc), &secid);
		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
		if (ret) {
			return_error = BR_FAILED_REPLY;
@@ -3151,12 +3167,14 @@ static void binder_transaction(struct binder_proc *proc,
		binder_enqueue_thread_work(thread, tcomplete);
		binder_inner_proc_lock(target_proc);
		if (target_thread->is_dead) {
			return_error = BR_DEAD_REPLY;
			binder_inner_proc_unlock(target_proc);
			goto err_dead_proc_or_thread;
		}
		BUG_ON(t->buffer->async_transaction != 0);
		binder_pop_transaction_ilocked(target_thread, in_reply_to);
		binder_enqueue_thread_work_ilocked(target_thread, &t->work);
		target_proc->outstanding_txns++;
		binder_inner_proc_unlock(target_proc);
		wake_up_interruptible_sync(&target_thread->wait);
		trace_android_vh_binder_restore_priority(in_reply_to, current);
@@ -3177,7 +3195,9 @@ static void binder_transaction(struct binder_proc *proc,
		t->from_parent = thread->transaction_stack;
		thread->transaction_stack = t;
		binder_inner_proc_unlock(proc);
		if (!binder_proc_transaction(t, target_proc, target_thread)) {
		return_error = binder_proc_transaction(t,
				target_proc, target_thread);
		if (return_error) {
			binder_inner_proc_lock(proc);
			binder_pop_transaction_ilocked(thread, t);
			binder_inner_proc_unlock(proc);
@@ -3187,7 +3207,8 @@ static void binder_transaction(struct binder_proc *proc,
		BUG_ON(target_node == NULL);
		BUG_ON(t->buffer->async_transaction != 1);
		binder_enqueue_thread_work(thread, tcomplete);
		if (!binder_proc_transaction(t, target_proc, NULL))
		return_error = binder_proc_transaction(t, target_proc, NULL);
		if (return_error)
			goto err_dead_proc_or_thread;
	}
	if (target_thread)
@@ -3204,7 +3225,6 @@ static void binder_transaction(struct binder_proc *proc,
	return;

err_dead_proc_or_thread:
	return_error = BR_DEAD_REPLY;
	return_error_line = __LINE__;
	binder_dequeue_work(proc, tcomplete);
err_translate_failed:
@@ -3830,7 +3850,7 @@ static int binder_wait_for_work(struct binder_thread *thread,
		binder_inner_proc_lock(proc);
		list_del_init(&thread->waiting_thread_node);
		if (signal_pending(current)) {
			ret = -ERESTARTSYS;
			ret = -EINTR;
			break;
		}
	}
@@ -4430,9 +4450,14 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc)
static void binder_free_proc(struct binder_proc *proc)
{
	struct binder_device *device;
	struct binder_proc_ext *eproc =
		container_of(proc, struct binder_proc_ext, proc);

	BUG_ON(!list_empty(&proc->todo));
	BUG_ON(!list_empty(&proc->delivered_death));
	if (proc->outstanding_txns)
		pr_warn("%s: Unexpected outstanding_txns %d\n",
			__func__, proc->outstanding_txns);
	device = container_of(proc->context, struct binder_device, context);
	if (refcount_dec_and_test(&device->ref)) {
		kfree(proc->context->name);
@@ -4440,8 +4465,9 @@ static void binder_free_proc(struct binder_proc *proc)
	}
	binder_alloc_deferred_release(&proc->alloc);
	put_task_struct(proc->tsk);
	put_cred(eproc->cred);
	binder_stats_deleted(BINDER_STAT_PROC);
	kfree(proc);
	kfree(eproc);
}

static void binder_free_thread(struct binder_thread *thread)
@@ -4495,6 +4521,7 @@ static int binder_thread_release(struct binder_proc *proc,
			     (t->to_thread == thread) ? "in" : "out");

		if (t->to_thread == thread) {
			thread->proc->outstanding_txns--;
			t->to_proc = NULL;
			t->to_thread = NULL;
			if (t->buffer) {
@@ -4651,7 +4678,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp,
		ret = -EBUSY;
		goto out;
	}
	ret = security_binder_set_context_mgr(proc->tsk);
	ret = security_binder_set_context_mgr(binder_get_cred(proc));
	if (ret < 0)
		goto out;
	if (uid_valid(context->binder_context_mgr_uid)) {
@@ -4745,6 +4772,100 @@ static int binder_ioctl_get_node_debug_info(struct binder_proc *proc,
	return 0;
}

static bool binder_txns_pending_ilocked(struct binder_proc *proc)
{
	struct rb_node *n;
	struct binder_thread *thread;

	if (proc->outstanding_txns > 0)
		return true;

	for (n = rb_first(&proc->threads); n; n = rb_next(n)) {
		thread = rb_entry(n, struct binder_thread, rb_node);
		if (thread->transaction_stack)
			return true;
	}
	return false;
}

static int binder_ioctl_freeze(struct binder_freeze_info *info,
			       struct binder_proc *target_proc)
{
	int ret = 0;

	if (!info->enable) {
		binder_inner_proc_lock(target_proc);
		target_proc->sync_recv = false;
		target_proc->async_recv = false;
		target_proc->is_frozen = false;
		binder_inner_proc_unlock(target_proc);
		return 0;
	}

	/*
	 * Freezing the target. Prevent new transactions by
	 * setting frozen state. If timeout specified, wait
	 * for transactions to drain.
	 */
	binder_inner_proc_lock(target_proc);
	target_proc->sync_recv = false;
	target_proc->async_recv = false;
	target_proc->is_frozen = true;
	binder_inner_proc_unlock(target_proc);

	if (info->timeout_ms > 0)
		ret = wait_event_interruptible_timeout(
			target_proc->freeze_wait,
			(!target_proc->outstanding_txns),
			msecs_to_jiffies(info->timeout_ms));

	/* Check pending transactions that wait for reply */
	if (ret >= 0) {
		binder_inner_proc_lock(target_proc);
		if (binder_txns_pending_ilocked(target_proc))
			ret = -EAGAIN;
		binder_inner_proc_unlock(target_proc);
	}

	if (ret < 0) {
		binder_inner_proc_lock(target_proc);
		target_proc->is_frozen = false;
		binder_inner_proc_unlock(target_proc);
	}

	return ret;
}

static int binder_ioctl_get_freezer_info(
				struct binder_frozen_status_info *info)
{
	struct binder_proc *target_proc;
	bool found = false;
	__u32 txns_pending;

	info->sync_recv = 0;
	info->async_recv = 0;

	mutex_lock(&binder_procs_lock);
	hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
		if (target_proc->pid == info->pid) {
			found = true;
			binder_inner_proc_lock(target_proc);
			txns_pending = binder_txns_pending_ilocked(target_proc);
			info->sync_recv |= target_proc->sync_recv |
					(txns_pending << 1);
			info->async_recv |= target_proc->async_recv;
			binder_inner_proc_unlock(target_proc);
		}
	}
	mutex_unlock(&binder_procs_lock);

	if (!found)
		return -EINVAL;

	return 0;
}

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int ret;
@@ -4863,6 +4984,84 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
		}
		break;
	}
	case BINDER_FREEZE: {
		struct binder_freeze_info info;
		struct binder_proc **target_procs = NULL, *target_proc;
		int target_procs_count = 0, i = 0;

		ret = 0;

		if (copy_from_user(&info, ubuf, sizeof(info))) {
			ret = -EFAULT;
			goto err;
		}

		mutex_lock(&binder_procs_lock);
		hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
			if (target_proc->pid == info.pid)
				target_procs_count++;
		}

		if (target_procs_count == 0) {
			mutex_unlock(&binder_procs_lock);
			ret = -EINVAL;
			goto err;
		}

		target_procs = kcalloc(target_procs_count,
				       sizeof(struct binder_proc *),
				       GFP_KERNEL);

		if (!target_procs) {
			mutex_unlock(&binder_procs_lock);
			ret = -ENOMEM;
			goto err;
		}

		hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
			if (target_proc->pid != info.pid)
				continue;

			binder_inner_proc_lock(target_proc);
			target_proc->tmp_ref++;
			binder_inner_proc_unlock(target_proc);

			target_procs[i++] = target_proc;
		}
		mutex_unlock(&binder_procs_lock);

		for (i = 0; i < target_procs_count; i++) {
			if (ret >= 0)
				ret = binder_ioctl_freeze(&info,
							  target_procs[i]);

			binder_proc_dec_tmpref(target_procs[i]);
		}

		kfree(target_procs);

		if (ret < 0)
			goto err;
		break;
	}
	case BINDER_GET_FROZEN_INFO: {
		struct binder_frozen_status_info info;

		if (copy_from_user(&info, ubuf, sizeof(info))) {
			ret = -EFAULT;
			goto err;
		}

		ret = binder_ioctl_get_freezer_info(&info);
		if (ret < 0)
			goto err;

		if (copy_to_user(ubuf, &info, sizeof(info))) {
			ret = -EFAULT;
			goto err;
		}
		break;
	}
	default:
		ret = -EINVAL;
		goto err;
@@ -4872,7 +5071,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
	if (thread)
		thread->looper_need_return = false;
	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
	if (ret && ret != -ERESTARTSYS)
	if (ret && ret != -EINTR)
		pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
err_unlocked:
	trace_binder_ioctl_done(ret);
@@ -4953,6 +5152,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
static int binder_open(struct inode *nodp, struct file *filp)
{
	struct binder_proc *proc, *itr;
	struct binder_proc_ext *eproc;
	struct binder_device *binder_dev;
	struct binderfs_info *info;
	struct dentry *binder_binderfs_dir_entry_proc = NULL;
@@ -4961,14 +5161,17 @@ static int binder_open(struct inode *nodp, struct file *filp)
	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__,
		     current->group_leader->pid, current->pid);

	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
	eproc = kzalloc(sizeof(*eproc), GFP_KERNEL);
	proc = &eproc->proc;
	if (proc == NULL)
		return -ENOMEM;
	spin_lock_init(&proc->inner_lock);
	spin_lock_init(&proc->outer_lock);
	get_task_struct(current->group_leader);
	proc->tsk = current->group_leader;
	eproc->cred = get_cred(filp->f_cred);
	INIT_LIST_HEAD(&proc->todo);
	init_waitqueue_head(&proc->freeze_wait);
	if (binder_supported_policy(current->policy)) {
		proc->default_priority.sched_policy = current->policy;
		proc->default_priority.prio = current->normal_prio;
@@ -5188,6 +5391,9 @@ static void binder_deferred_release(struct binder_proc *proc)
	proc->tmp_ref++;

	proc->is_dead = true;
	proc->is_frozen = false;
	proc->sync_recv = false;
	proc->async_recv = false;
	threads = 0;
	active_transactions = 0;
	while ((n = rb_first(&proc->threads))) {
+43 −0
Original line number Diff line number Diff line
@@ -388,9 +388,24 @@ struct binder_priority {
 *                        (protected by binder_deferred_lock)
 * @deferred_work:        bitmap of deferred work to perform
 *                        (protected by binder_deferred_lock)
 * @outstanding_txns:     number of transactions to be transmitted before
 *                        processes in freeze_wait are woken up
 *                        (protected by @inner_lock)
 * @is_dead:              process is dead and awaiting free
 *                        when outstanding transactions are cleaned up
 *                        (protected by @inner_lock)
 * @is_frozen:            process is frozen and unable to service
 *                        binder transactions
 *                        (protected by @inner_lock)
 * @sync_recv:            process received sync transactions since last frozen
 *                        bit 0: received sync transaction after being frozen
 *                        bit 1: new pending sync transaction during freezing
 *                        (protected by @inner_lock)
 * @async_recv:           process received async transactions since last frozen
 *                        (protected by @inner_lock)
 * @freeze_wait:          waitqueue of processes waiting for all outstanding
 *                        transactions to be processed
 *                        (protected by @inner_lock)
 * @todo:                 list of work for this process
 *                        (protected by @inner_lock)
 * @stats:                per-process binder statistics
@@ -431,7 +446,12 @@ struct binder_proc {
	struct task_struct *tsk;
	struct hlist_node deferred_work_node;
	int deferred_work;
	int outstanding_txns;
	bool is_dead;
	bool is_frozen;
	bool sync_recv;
	bool async_recv;
	wait_queue_head_t freeze_wait;

	struct list_head todo;
	struct binder_stats stats;
@@ -449,6 +469,29 @@ struct binder_proc {
	struct dentry *binderfs_entry;
};

/**
 * struct binder_proc_ext - binder process bookkeeping
 * @proc:            element for binder_procs list
 * @cred                  struct cred associated with the `struct file`
 *                        in binder_open()
 *                        (invariant after initialized)
 *
 * Extended binder_proc -- needed to add the "cred" field without
 * changing the KMI for binder_proc.
 */
struct binder_proc_ext {
	struct binder_proc proc;
	const struct cred *cred;
};

static inline const struct cred *binder_get_cred(struct binder_proc *proc)
{
	struct binder_proc_ext *eproc;

	eproc = container_of(proc, struct binder_proc_ext, proc);
	return eproc->cred;
}

/**
 * struct binder_thread - binder thread bookkeeping
 * @proc:                 binder process for this thread
+13 −2
Original line number Diff line number Diff line
@@ -601,8 +601,11 @@ static int create_bulk_endpoints(struct acc_dev *dev,
	pr_err("acc_bind() could not allocate requests\n");
	while ((req = req_get(dev, &dev->tx_idle)))
		acc_request_free(req, dev->ep_in);
	for (i = 0; i < RX_REQ_MAX; i++)
	for (i = 0; i < RX_REQ_MAX; i++) {
		acc_request_free(dev->rx_req[i], dev->ep_out);
		dev->rx_req[i] = NULL;
	}

	return -1;
}

@@ -634,6 +637,12 @@ static ssize_t acc_read(struct file *fp, char __user *buf,
		goto done;
	}

	if (!dev->rx_req[0]) {
		pr_warn("acc_read: USB request already handled/freed");
		r = -EINVAL;
		goto done;
	}

	/*
	 * Calculate the data length by considering termination character.
	 * Then compansite the difference of rounding up to
@@ -1098,8 +1107,10 @@ acc_function_unbind(struct usb_configuration *c, struct usb_function *f)

	while ((req = req_get(dev, &dev->tx_idle)))
		acc_request_free(req, dev->ep_in);
	for (i = 0; i < RX_REQ_MAX; i++)
	for (i = 0; i < RX_REQ_MAX; i++) {
		acc_request_free(dev->rx_req[i], dev->ep_out);
		dev->rx_req[i] = NULL;
	}

	acc_hid_unbind(dev);
}
Loading