af_unix: Block perfd from writing to the logd socket

The logcat spam from perfd when the kernel doesn't have everything it
wants destroys logcats and creates excessive logd overhead from the sheer
number of logs it prints.

Block perfd from writing to the logd socket so that it cannot write to
logcat at all. This way, all perfd attempts to write to logcat are
killed early on before they can incur overhead, which solves the excessive
logd overhead problem.

Change-Id: I9489c5eb8c041b998affd154d1beca82459b5fcc
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
Signed-off-by: Richard Raya <rdxzv.dev@gmail.com>
This commit is contained in:
Sultan Alsawaf 2024-02-10 22:51:30 -08:00 committed by Richard Raya
parent 34084e75c4
commit f696289f34
3 changed files with 34 additions and 0 deletions

View File

@ -74,6 +74,28 @@
int suid_dumpable = 0;
#define PERFD_BIN "/vendor/bin/hw/vendor.qti.hardware.perf2-hal-service"
static struct task_struct *perfd_tsk;
bool task_is_perfd(struct task_struct *p)
{
struct task_struct *tsk;
bool ret;
rcu_read_lock();
tsk = READ_ONCE(perfd_tsk);
ret = tsk && same_thread_group(p, tsk);
rcu_read_unlock();
return ret;
}
void dead_special_task(void)
{
if (unlikely(current == perfd_tsk))
WRITE_ONCE(perfd_tsk, NULL);
}
static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);
@ -1912,6 +1934,9 @@ static int do_execveat_common(int fd, struct filename *filename,
current->flags |= PF_PERF_CRITICAL;
set_cpus_allowed_ptr(current, cpu_perf_mask);
}
else if (unlikely(!strcmp(filename->name, PERFD_BIN))) {
WRITE_ONCE(perfd_tsk, current);
}
else if (unlikely(!strcmp(filename->name, ZYGOTE32_BIN))) {
zygote32_sig = current->signal;
}

View File

@ -790,11 +790,14 @@ void profile_task_exit(struct task_struct *tsk)
}
#endif
void dead_special_task(void);
void __noreturn do_exit(long code)
{
struct task_struct *tsk = current;
int group_dead;
dead_special_task();
/*
* We can get here from a kernel oops, sometimes with preemption off.
* Start by checking for critical errors.

View File

@ -1189,6 +1189,7 @@ static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
unix_state_unlock(sk2);
}
bool task_is_perfd(struct task_struct *p);
static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
int alen, int flags)
{
@ -1213,6 +1214,11 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
goto out;
alen = err;
/* Block perfd from writing to logd (i.e., logcat) */
if (task_is_perfd(current) &&
!strncmp(sunaddr->sun_path, "/dev/socket/logdw", alen))
return -EINVAL;
if (test_bit(SOCK_PASSCRED, &sock->flags) &&
!unix_sk(sk)->addr) {
err = unix_autobind(sk);