exynos9810: kernel/drivers: remove samsung freecess

This commit is contained in:
Dylan Neve 2022-12-23 15:34:36 +03:00 committed by xxmustafacooTR
parent 1272e07f87
commit 2ffda2a073
No known key found for this signature in database
GPG key ID: 520B6FE385CBF5C9
8 changed files with 0 additions and 1035 deletions

View file

@ -4368,7 +4368,6 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
CONFIG_ANDROID_INTF_ALARM_DEV=y CONFIG_ANDROID_INTF_ALARM_DEV=y
# CONFIG_ANDROID_VSOC is not set # CONFIG_ANDROID_VSOC is not set
CONFIG_SAMSUNG_FREECESS=y
CONFIG_ION=y CONFIG_ION=y
CONFIG_ION_TEST=y CONFIG_ION_TEST=y
# CONFIG_ION_DUMMY is not set # CONFIG_ION_DUMMY is not set

View file

@ -74,9 +74,6 @@
#include <uapi/linux/android/binder.h> #include <uapi/linux/android/binder.h>
#include "binder_alloc.h" #include "binder_alloc.h"
#include "binder_trace.h" #include "binder_trace.h"
#ifdef CONFIG_SAMSUNG_FREECESS
#include <linux/freecess.h>
#endif
int system_server_pid = 0; int system_server_pid = 0;
@ -3184,13 +3181,6 @@ static void binder_transaction(struct binder_proc *proc,
goto err_dead_binder; goto err_dead_binder;
} }
e->to_node = target_node->debug_id; e->to_node = target_node->debug_id;
#ifdef CONFIG_SAMSUNG_FREECESS
if (target_proc
&& (target_proc->tsk->cred->euid.val > 10000)
&& (proc->pid != target_proc->pid)) {
binder_report(proc->tsk, target_proc->tsk, tr->flags & TF_ONE_WAY);
}
#endif
if (security_binder_transaction(proc->tsk, if (security_binder_transaction(proc->tsk,
target_proc->tsk) < 0) { target_proc->tsk) < 0) {
return_error = BR_FAILED_REPLY; return_error = BR_FAILED_REPLY;
@ -5822,81 +5812,6 @@ static void print_binder_proc(struct seq_file *m,
m->count = start_pos; m->count = start_pos;
} }
#ifdef CONFIG_SAMSUNG_FREECESS
static void binder_in_transaction(struct binder_proc *proc)
{
struct rb_node *n = NULL;
struct binder_thread *thread = NULL;
int uid = -1;
struct task_struct *tsk = NULL;
struct binder_transaction *t = NULL;
bool empty = true;
bool found = false;
//check binder threads todo and transcation_stack list
binder_inner_proc_lock(proc);
for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
thread = rb_entry(n, struct binder_thread, rb_node);
empty = binder_worklist_empty_ilocked(&thread->todo);
tsk = thread->task;
if (tsk != NULL) {
//have some binders to do
if (!empty) {
//report uid to FW, only report one time
uid = tsk->cred->euid.val;
binder_inner_proc_unlock(proc);
cfb_report(uid, "thread");
return;
}
//processing one binder call
t = thread->transaction_stack;
if (t) {
spin_lock(&t->lock);
if (t->to_thread == thread) {
//check incoming, it has one
found = true;
uid = tsk->cred->euid.val;
}
spin_unlock(&t->lock);
if (found == true){
//report uid to FW, only report one time
binder_inner_proc_unlock(proc);
cfb_report(uid, "transaction_stack");
return;
}
}
}
}
//check binder proc todo list
empty = binder_worklist_empty_ilocked(&proc->todo);
tsk = proc->tsk;
if (tsk != NULL && !empty) {
//report uid to FW
uid = tsk->cred->euid.val;
binder_inner_proc_unlock(proc);
cfb_report(uid, "proc");
}
else
binder_inner_proc_unlock(proc);
}
void binders_in_transcation(int uid)
{
struct binder_proc *itr;
mutex_lock(&binder_procs_lock);
hlist_for_each_entry(itr, &binder_procs, proc_node) {
if (itr != NULL && (itr->tsk->cred->euid.val == uid)) {
binder_in_transaction(itr);
}
}
mutex_unlock(&binder_procs_lock);
}
#endif
static const char * const binder_return_strings[] = { static const char * const binder_return_strings[] = {
"BR_ERROR", "BR_ERROR",
"BR_OK", "BR_OK",

View file

@ -51,12 +51,6 @@ config ANDROID_VSOC
a 'cuttlefish' Android image inside QEmu. The driver interacts with a 'cuttlefish' Android image inside QEmu. The driver interacts with
a QEmu ivshmem device. If built as a module, it will be called vsoc. a QEmu ivshmem device. If built as a module, it will be called vsoc.
config SAMSUNG_FREECESS
bool "thraw frozen process when recv sig"
default n
help
thraw frozen process when recv sig.
source "drivers/staging/android/ion/Kconfig" source "drivers/staging/android/ion/Kconfig"
source "drivers/staging/android/switch/Kconfig" source "drivers/staging/android/switch/Kconfig"

View file

@ -7,5 +7,3 @@ obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
obj-$(CONFIG_ANDROID_SWITCH) += switch/ obj-$(CONFIG_ANDROID_SWITCH) += switch/
obj-$(CONFIG_ANDROID_VSOC) += vsoc.o obj-$(CONFIG_ANDROID_VSOC) += vsoc.o
obj-$(CONFIG_SAMSUNG_FREECESS) += freecess.o
obj-$(CONFIG_SAMSUNG_FREECESS) += freecess_pkg.o

View file

@ -1,608 +0,0 @@
/*
* Copyright (c) Samsung Technologies Co., Ltd. 2001-2017. All rights reserved.
*
* File name: freecess.c
* Description: Use to thaw process from state 'D'
* Author: chao.gu@samsung.com
* Version: 0.2
* Date: 2017/07/17
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/freecess.h>
#include <linux/freezer.h>
#include <net/sock.h>
#include <linux/hrtimer.h>
#include <linux/proc_fs.h>
#define RET_OK 0
#define RET_ERR 1
static struct sock *kfreecess_mod_sock = NULL;
static atomic_t bind_port[MOD_END];
static atomic_t kfreecess_init_suc;
static int last_kill_pid = -1;
static struct proc_dir_entry *freecess_rootdir = NULL;
struct report_stat_s
{
spinlock_t lock;
struct {
u64 report_suc_count;
u64 report_fail_count;
u64 total_runtime;
u64 report_suc_from_windowstart;
u64 report_fail_from_windowstart;
u64 runtime_from_windowstart;
}data;
char name[32];
};
struct freecess_info_s
{
struct report_stat_s mod_reportstat[MOD_END];
} freecess_info;
static char* mod_name[MOD_END] =
{
"NULL",
"MOD_BINDER",
"MOD_SIG",
"MOD_PKG",
"MOD_CFB"
};
struct priv_data
{
int caller_pid;
int target_uid;
int flag; //MOD_SIG,MOD_BINDER
pkg_info_t pkg_info; //MOD_PKG
};
static freecess_hook mod_recv_handler[MOD_END];
static int check_msg_type(int type)
{
return (type < MSG_TYPE_END) && (type > 0);
}
static int check_mod_type(int mod)
{
return (mod < MOD_END) && (mod > 0);
}
static int thread_group_is_frozen(struct task_struct* task)
{
struct task_struct *leader = task->group_leader;
return (freezing(leader) || frozen(leader));
}
static void dump_kfreecess_msg(struct kfreecess_msg_data *msg)
{
printk(KERN_ERR "-----kfreecess msg dump-----\n");
if (!msg) {
printk(KERN_ERR "msg is NULL");
return;
}
printk(KERN_ERR "type: %d, mode: %d\n", msg->type, msg->mod);
}
int mod_sendmsg(int type, int mod, struct priv_data* data)
{
int ret, msg_len = 0;
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh = NULL;
struct kfreecess_msg_data *payload = NULL;
if (!atomic_read(&kfreecess_init_suc))
return RET_ERR;
if (!check_msg_type(type)) {
pr_err("%s: msg type is invalid! %d\n", __func__, type);
return RET_ERR;
}
if (!check_mod_type(mod)) {
pr_err("%s: mod type is invalid! %d\n", __func__, mod);
return RET_ERR;
}
msg_len = sizeof(struct kfreecess_msg_data);
skb = nlmsg_new(msg_len, GFP_ATOMIC);
if (!skb) {
pr_err("%s alloc_skb failed! %d\n", __func__, mod);
return RET_ERR;
}
nlh = nlmsg_put(skb, 0, 0, 0, msg_len, 0);
if (!nlh) {
kfree_skb(skb);
return RET_ERR;
}
payload = nlmsg_data(nlh);
payload->type = type;
payload->mod = mod;
payload->src_portid = KERNEL_ID_NETLINK;
payload->dst_portid = atomic_read(&bind_port[mod]);
if (data) {
payload->caller_pid = data->caller_pid;
payload->target_uid = data->target_uid;
if (payload->mod == MOD_PKG)
memcpy(&payload->pkg_info, &data->pkg_info, sizeof(pkg_info_t));
else
payload->flag = data->flag;
}
//dump_kfreecess_msg(payload);
if ((ret = nlmsg_unicast(kfreecess_mod_sock, skb, payload->dst_portid)) < 0) {
pr_err("nlmsg_unicast failed! %s errno %d\n", __func__ , ret);
return RET_ERR;
} else
pr_info("nlmsg_unicast snd msg success\n");
return RET_OK;
}
int sig_report(struct task_struct *caller, struct task_struct *p)
{
int ret = RET_OK;
struct priv_data data;
int target_pid = task_tgid_nr(p);
u64 walltime, timecost;
unsigned long flags;
struct report_stat_s *stat;
walltime = ktime_to_us(ktime_get());
memset(&data, 0, sizeof(struct priv_data));
data.caller_pid = task_tgid_nr(caller);
data.target_uid = task_uid(p).val;
data.flag = 0;
if (thread_group_is_frozen(p) && (target_pid != last_kill_pid)) {
last_kill_pid = target_pid;
stat = &freecess_info.mod_reportstat[MOD_SIG];
ret = mod_sendmsg(MSG_TO_USER, MOD_SIG, &data);
spin_lock_irqsave(&stat->lock, flags);
if (ret < 0) {
stat->data.report_fail_count++;
stat->data.report_fail_from_windowstart++;
pr_err("sig_report error\n");
} else {
stat->data.report_suc_count++;
stat->data.report_suc_from_windowstart++;
}
timecost = ktime_to_us(ktime_get()) - walltime;
stat->data.total_runtime += timecost;
stat->data.runtime_from_windowstart += timecost;
spin_unlock_irqrestore(&stat->lock, flags);
}
return ret;
}
int binder_report(struct task_struct *caller, struct task_struct *p, int flag)
{
int ret = RET_OK;
struct priv_data data;
u64 walltime, timecost;
unsigned long flags;
struct report_stat_s *stat;
memset(&data, 0, sizeof(struct priv_data));
data.target_uid = -1;
data.caller_pid = -1;
data.flag = flag;
if(p)
data.target_uid = task_uid(p).val;
if(caller)
data.caller_pid = task_tgid_nr(caller);
walltime = ktime_to_us(ktime_get());
if (p && thread_group_is_frozen(p)) {
ret = mod_sendmsg(MSG_TO_USER, MOD_BINDER, &data);
stat = &freecess_info.mod_reportstat[MOD_BINDER];
spin_lock_irqsave(&stat->lock, flags);
if (ret < 0) {
stat->data.report_fail_count++;
stat->data.report_fail_from_windowstart++;
pr_err("binder_report error\n");
} else {
stat->data.report_suc_count++;
stat->data.report_suc_from_windowstart++;
}
timecost = ktime_to_us(ktime_get()) - walltime;
stat->data.total_runtime += timecost;
stat->data.runtime_from_windowstart += timecost;
spin_unlock_irqrestore(&stat->lock, flags);
}
return ret;
}
int pkg_report(int target_uid)
{
int ret = RET_OK;
struct priv_data data;
u64 walltime, timecost;
unsigned long flags;
struct report_stat_s *stat;
memset(&data, 0, sizeof(struct priv_data));
data.target_uid = target_uid;
data.pkg_info.uid = (uid_t)target_uid;
walltime = ktime_to_us(ktime_get());
ret = mod_sendmsg(MSG_TO_USER, MOD_PKG, &data);
stat = &freecess_info.mod_reportstat[MOD_PKG];
spin_lock_irqsave(&stat->lock, flags);
if (ret < 0) {
stat->data.report_fail_count++;
stat->data.report_fail_from_windowstart++;
} else {
stat->data.report_suc_count++;
stat->data.report_suc_from_windowstart++;
}
timecost = ktime_to_us(ktime_get()) - walltime;
stat->data.total_runtime += timecost;
stat->data.runtime_from_windowstart += timecost;
spin_unlock_irqrestore(&stat->lock, flags);
return ret;
}
int cfb_report(int target_uid, const char *reason)
{
int ret = RET_OK;
struct priv_data data;
printk(KERN_INFO "cfb_report: uid %d frozen, reason: %s\n", target_uid, reason);
memset(&data, 0, sizeof(struct priv_data));
data.target_uid = target_uid;
ret = mod_sendmsg(MSG_TO_USER, MOD_CFB, &data);
return ret;
}
static void recv_handler(struct sk_buff *skb)
{
struct kfreecess_msg_data *payload = NULL;
struct nlmsghdr *nlh = NULL;
unsigned int msglen = 0;
uid_t uid = 0;
if (!skb) {
pr_err("recv_handler %s: skb is NULL!\n", __func__);
return;
}
uid = (*NETLINK_CREDS(skb)).uid.val;
//only allow system user to communicate with Freecess kernel part.
if (uid != 1000) {
pr_err("freecess--uid: %d, permission denied\n", uid);
return;
}
printk(KERN_ERR "kernel freecess receive msg now\n");
if (skb->len >= NLMSG_SPACE(0)) {
nlh = nlmsg_hdr(skb);
msglen = NLMSG_PAYLOAD(nlh, 0);
payload = (struct kfreecess_msg_data*)NLMSG_DATA(nlh);
if (msglen >= (sizeof(struct kfreecess_msg_data))) {
if (payload->src_portid < 0) {
pr_err("USER_HOOK_CALLBACK %s: src_portid %d is not valid!\n", __func__, payload->src_portid);
return;
}
if (payload->dst_portid != KERNEL_ID_NETLINK) {
pr_err("USER_HOOK_CALLBACK %s: dst_portid is %d not kernel!\n", __func__, payload->dst_portid);
return;
}
if (!check_mod_type(payload->mod)) {
pr_err("USER_HOOK_CALLBACK %s: mod %d is not valid!\n", __func__, payload->mod);
return;
}
switch (payload->type) {
case LOOPBACK_MSG:
atomic_set(&bind_port[payload->mod], payload->src_portid);
dump_kfreecess_msg(payload);
mod_sendmsg(LOOPBACK_MSG, payload->mod, NULL);
break;
case MSG_TO_KERN:
if (mod_recv_handler[payload->mod])
mod_recv_handler[payload->mod](payload, sizeof(struct kfreecess_msg_data));
else
dump_kfreecess_msg(payload);
break;
default:
pr_err("msg type is valid %d\n", payload->type);
break;
}
} else {
pr_err("%s: length err msglen %d struct kfreecess_msg_data %lu!\n", __func__, msglen, sizeof(struct kfreecess_msg_data));
}
}
}
/*proc and sysctl interface*/
static int freecess_window_stat_show(struct seq_file *m, void *v)
{
int i;
unsigned long flags;
struct report_stat_s *stat;
struct freecess_info_s tmp_freecess_info;
struct report_stat_s total_stat;
memset(&tmp_freecess_info, 0, sizeof(struct freecess_info_s));
memset(&total_stat, 0, sizeof(struct report_stat_s));
for(i = 1; i < MOD_END; i++) {
stat = &freecess_info.mod_reportstat[i];
spin_lock_irqsave(&stat->lock, flags);
tmp_freecess_info.mod_reportstat[i].data = stat->data;
spin_unlock_irqrestore(&stat->lock, flags);
strlcpy(tmp_freecess_info.mod_reportstat[i].name, stat->name, 32);
}
seq_printf(m, "freecess window stat show\n");
seq_printf(m, "-----------------------------\n\n");
for(i = 1; i < MOD_END; i++) {
stat = &tmp_freecess_info.mod_reportstat[i];
total_stat.data.report_suc_from_windowstart += stat->data.report_suc_from_windowstart;
total_stat.data.report_fail_from_windowstart += stat->data.report_fail_from_windowstart;
total_stat.data.runtime_from_windowstart += stat->data.runtime_from_windowstart;
seq_printf(m, "mod name: %s mod number %d:\n", stat->name, i);
seq_printf(m, "suc_count: %llu\n", stat->data.report_suc_from_windowstart);
seq_printf(m, "fail_count: %llu\n", stat->data.report_fail_from_windowstart);
seq_printf(m, "total_runtime: %llu us\n\n", stat->data.runtime_from_windowstart);
}
stat = &total_stat;
seq_printf(m, "info of all mod\n");
seq_printf(m, "-----------------------------\n");
seq_printf(m, "suc_count: %llu\n", stat->data.report_suc_from_windowstart);
seq_printf(m, "fail_count: %llu\n", stat->data.report_fail_from_windowstart);
seq_printf(m, "total_runtime: %llu us\n", stat->data.runtime_from_windowstart);
return 0;
}
static int freecess_window_stat_open(struct inode *inode, struct file *file)
{
return single_open(file, freecess_window_stat_show, NULL);
}
static void reset_window(void)
{
int i;
unsigned long flags;
struct report_stat_s *stat;
for(i = 1; i < MOD_END; i++) {
stat = &freecess_info.mod_reportstat[i];
spin_lock_irqsave(&stat->lock, flags);
stat->data.report_suc_from_windowstart = 0;
stat->data.report_fail_from_windowstart = 0;
stat->data.runtime_from_windowstart = 0;
spin_unlock_irqrestore(&stat->lock, flags);
}
}
static ssize_t freecess_window_stat_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops)
{
unsigned char tmp = 0;
int value = 0;
get_user(tmp, buf);
value = simple_strtol(&tmp, NULL, 10);
printk(KERN_WARNING "input value number: %d, if value == 1: window will reset ....\n", value);
if (value == 1)
reset_window();
printk(KERN_WARNING "window reset now\n");
return count;
}
static const struct file_operations window_stat_proc_fops = {
.open = freecess_window_stat_open,
.read = seq_read,
.write = freecess_window_stat_write,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
static int pkg_stat_open(struct inode *inode, struct file *file)
{
return single_open(file, pkg_stat_show, NULL);
}
static const struct file_operations pkg_stat_proc_fops = {
.open = pkg_stat_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int freecess_modstat_show(struct seq_file *m, void *v)
{
int i;
unsigned long flags;
struct report_stat_s *stat;
static struct freecess_info_s tmp_freecess_info;
struct report_stat_s total_stat;
memset(&tmp_freecess_info, 0, sizeof(struct freecess_info_s));
memset(&total_stat, 0, sizeof(struct report_stat_s));
for(i = 1; i < MOD_END; i++) {
stat = &freecess_info.mod_reportstat[i];
spin_lock_irqsave(&stat->lock, flags);
tmp_freecess_info.mod_reportstat[i].data = stat->data;
spin_unlock_irqrestore(&stat->lock, flags);
strlcpy(tmp_freecess_info.mod_reportstat[i].name, stat->name, 32);
}
seq_printf(m, "freecess mod stat show\n");
seq_printf(m, "-----------------------------\n\n");
for(i = 1; i < MOD_END; i++) {
stat = &tmp_freecess_info.mod_reportstat[i];
total_stat.data.report_suc_count += stat->data.report_suc_count;
total_stat.data.report_fail_count += stat->data.report_fail_count;
total_stat.data.total_runtime += stat->data.total_runtime;
seq_printf(m, "mod name: %s mod number %d:\n", stat->name, i);
seq_printf(m, "suc_count: %llu\n", stat->data.report_suc_count);
seq_printf(m, "fail_count: %llu\n", stat->data.report_fail_count);
seq_printf(m, "total_runtime: %llu us\n\n", stat->data.total_runtime);
}
stat = &total_stat;
seq_printf(m, "info of all mod:\n");
seq_printf(m, "suc_count: %llu\n", stat->data.report_suc_count);
seq_printf(m, "fail_count: %llu\n", stat->data.report_fail_count);
seq_printf(m, "total_runtime: %llu us\n", stat->data.total_runtime);
return 0;
}
static int freecess_mod_stat_open(struct inode *inode, struct file *file)
{
return single_open(file, freecess_modstat_show, NULL);
}
static const struct file_operations mod_stat_proc_fops = {
.open = freecess_mod_stat_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void freecess_runinfo_init(struct freecess_info_s *f)
{
int i;
struct report_stat_s *stat;
for(i = 1; i < MOD_END; i++) {
stat = &f->mod_reportstat[i];
spin_lock_init(&stat->lock);
stat->data.report_suc_count = 0;
stat->data.report_fail_count = 0;
stat->data.total_runtime = 0;
stat->data.report_suc_from_windowstart = 0;
stat->data.report_fail_from_windowstart = 0;
stat->data.runtime_from_windowstart = 0;
strlcpy(f->mod_reportstat[i].name, mod_name[i], 32);
}
}
int register_kfreecess_hook(int mod, freecess_hook hook)
{
if (!check_mod_type(mod)) {
pr_err("%s: mod type is invalid! %d\n", __func__, mod);
return RET_ERR;
}
if (hook)
mod_recv_handler[mod] = hook;
return RET_OK;
}
int unregister_kfreecess_hook(int mod)
{
if (!check_mod_type(mod)) {
pr_err("%s: mod type is invalid! %d\n", __func__, mod);
return RET_ERR;
}
mod_recv_handler[mod] = NULL;
return RET_OK;
}
static int __init kfreecess_init(void)
{
int ret = RET_ERR;
struct proc_dir_entry *freecess_modstat_entry = NULL;
struct proc_dir_entry *freecess_window_stat_entry = NULL;
struct proc_dir_entry *pkg_modstat_entry = NULL;
int i;
struct netlink_kernel_cfg cfg = {
.input = recv_handler,
};
kfreecess_mod_sock = netlink_kernel_create(&init_net, NETLINK_KFREECESS, &cfg);
if (!kfreecess_mod_sock) {
pr_err("%s: create kfreecess_mod_sock socket error!\n", __func__);
return ret;
}
for(i = 1; i<MOD_END; i++)
atomic_set(&bind_port[i], 0);
freecess_rootdir = proc_mkdir("freecess", NULL);
if (!freecess_rootdir)
pr_err("create /proc/freecess failed\n");
else {
freecess_window_stat_entry = proc_create("windowstat", 0644, freecess_rootdir, &window_stat_proc_fops);
if (!freecess_window_stat_entry) {
pr_err("create /proc/freecess/windowstat failed, remove /proc/freecess dir\n");
remove_proc_entry("freecess", NULL);
freecess_rootdir = NULL;
} else {
freecess_modstat_entry = proc_create("modstat", 0, freecess_rootdir, &mod_stat_proc_fops);
if (!freecess_modstat_entry) {
pr_err("create /proc/freecess/modstat failed, remove /proc/freecess dir\n");
remove_proc_entry("freecess/windowstat", NULL);
remove_proc_entry("freecess", NULL);
freecess_rootdir = NULL;
} else {
pkg_modstat_entry = proc_create("pkgstat", 0, freecess_rootdir, &pkg_stat_proc_fops);
if (!pkg_modstat_entry) {
pr_err("create /proc/freecess/pkgstat failed, remove /proc/freecess dir\n");
remove_proc_entry("freecess/windowstat", NULL);
remove_proc_entry("freecess/modstat", NULL);
remove_proc_entry("freecess", NULL);
freecess_rootdir = NULL;
}
}
}
}
freecess_runinfo_init(&freecess_info);
atomic_set(&kfreecess_init_suc, 1);
return RET_OK;
}
static void __exit kfreecess_exit(void)
{
if (kfreecess_mod_sock)
netlink_kernel_release(kfreecess_mod_sock);
if (freecess_rootdir) {
remove_proc_entry("windowstat", freecess_rootdir);
remove_proc_entry("modstat", freecess_rootdir);
remove_proc_entry("pkgstat", freecess_rootdir);
remove_proc_entry("freecess", NULL);
}
}
module_init(kfreecess_init);
module_exit(kfreecess_exit);
MODULE_LICENSE("GPL");

View file

@ -1,286 +0,0 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/file.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6.h>
#include <linux/spinlock.h>
#include <linux/rbtree.h>
#include <linux/ktime.h>
#include <linux/time.h>
#include <linux/list.h>
#include <linux/types.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/inet_hashtables.h>
#include <net/inet6_hashtables.h>
#include <linux/freecess.h>
#define MAX_REC_UID 64
static atomic_t uid_rec[MAX_REC_UID];
extern void binders_in_transcation(int uid);
int pkg_stat_show(struct seq_file *m, void *v)
{
int i;
for (i = 0; i < MAX_REC_UID; i++)
if (atomic_read(&uid_rec[i]))
seq_printf(m, "%d\t", atomic_read(&uid_rec[i]));
seq_printf(m, "\n");
return 0;
}
static void freecess_add_uid(uid_t uid)
{
int i, j;
uid_t inner_uid;
for (i = 0, j = MAX_REC_UID; i < MAX_REC_UID; i++) {
inner_uid = atomic_read(&uid_rec[i]);
if (inner_uid == 0 && j == MAX_REC_UID)
j = i;
else if (inner_uid == uid)
goto out;
}
if (j < MAX_REC_UID)
atomic_set(&uid_rec[j], uid);
else
pr_err("%s : add uid:%d failed (full)!\n", __func__, uid);
out:
return;
}
static void freecess_del_uid(uid_t uid)
{
int i;
uid_t inner_uid;
for (i = 0; i < MAX_REC_UID; i++) {
inner_uid = (uid_t)atomic_read(&uid_rec[i]);
if (inner_uid == uid) {
atomic_set(&uid_rec[i], 0);
break;
}
}
return;
}
static void freecess_clear_all(void)
{
int i;
for (i = 0; i < MAX_REC_UID; i++) {
atomic_set(&uid_rec[i], 0);
}
return;
}
static int find_and_clear_uid(uid_t uid)
{
int found = 0;
int i = 0;
uid_t inner_uid;
for (i = 0; i < MAX_REC_UID; i++) {
inner_uid = atomic_read(&uid_rec[i]);
if (unlikely (inner_uid == uid)) {
if (atomic_cmpxchg(&uid_rec[i], uid, 0) == uid)
found = 1;
break;
}
}
return found;
}
static void kfreecess_pkg_hook(void* data, unsigned int len)
{
struct kfreecess_msg_data* payload = (struct kfreecess_msg_data*)data;
switch (payload->pkg_info.cmd) {
case ADD_UID:
freecess_add_uid(payload->pkg_info.uid);
break;
case DEL_UID:
freecess_del_uid(payload->pkg_info.uid);
break;
case CLEAR_ALL_UID:
freecess_clear_all();
break;
default:
break;
}
return;
}
static void kfreecess_cfb_hook(void* data, unsigned int len)
{
struct kfreecess_msg_data* payload = (struct kfreecess_msg_data*)data;
int uid = payload->target_uid;
printk(KERN_INFO "cfb_target: uid = %d\n", uid);
binders_in_transcation(uid);
}
static uid_t __sock_i_uid(struct sock *sk)
{
uid_t uid;
if(sk && sk->sk_socket) {
uid = SOCK_INODE(sk->sk_socket)->i_uid.val;
return uid;
}
return 0;
}
static unsigned int freecess_ip4_in(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct sock *sk;
uid_t uid;
int found;
int protocol;
protocol = ip_hdr(skb)->protocol;
if (protocol != IPPROTO_TCP)
return NF_ACCEPT;
sk = skb_to_full_sk(skb);
if (sk == NULL || !sk_fullsock(sk))
return NF_ACCEPT;
uid = __sock_i_uid(sk);
if (uid < UID_MIN_VALUE)
return NF_ACCEPT;
found = find_and_clear_uid(uid);
if (!found)
return NF_ACCEPT;
else if (pkg_report((int)uid) < 0)
pr_err("%s : up report failed!\n", __func__);
return NF_ACCEPT;
}
static unsigned int freecess_ip6_in(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct sock *sk;
unsigned int thoff = 0;
unsigned short frag_off = 0;
int protohdr;
uid_t uid;
int found;
protohdr = ipv6_find_hdr(skb, &thoff, -1, &frag_off, NULL);
if (protohdr != IPPROTO_TCP)
return NF_ACCEPT;
sk = skb_to_full_sk(skb);
if (sk == NULL || !sk_fullsock(sk))
return NF_ACCEPT;
uid = __sock_i_uid(sk);
if (uid < UID_MIN_VALUE)
return NF_ACCEPT;
found = find_and_clear_uid(uid);
if (!found)
return NF_ACCEPT;
else if (pkg_report((int)uid) < 0)
pr_err("%s : up report failed!\n", __func__);
return NF_ACCEPT;
}
static inline unsigned int freecess_ip4_out(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
return NF_ACCEPT;
}
static inline unsigned int freecess_ip6_out(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
return NF_ACCEPT;
}
static struct nf_hook_ops freecess_nf_ops[] = {
{
.hook = freecess_ip4_in,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_SELINUX_LAST + 1,
},
{
.hook = freecess_ip6_in,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_SELINUX_LAST + 1,
},
{
.hook = freecess_ip4_out,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_SELINUX_LAST + 1,
},
{
.hook = freecess_ip6_out,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_SELINUX_LAST + 1,
},
};
static int __init kfreecess_pkg_init(void)
{
int ret;
int i;
for (i = 0; i < MAX_REC_UID; i++)
atomic_set(&uid_rec[i], 0);
ret = nf_register_hooks(freecess_nf_ops, ARRAY_SIZE(freecess_nf_ops));
if (ret < 0) {
pr_err("nf_register_hooks(freecess hooks) error\n");
return -1;
}
pr_err("nf_register_hooks(freecess hooks) success\n");
register_kfreecess_hook(MOD_PKG, kfreecess_pkg_hook);
register_kfreecess_hook(MOD_CFB, kfreecess_cfb_hook);
return 0;
}
static void __exit kfreecess_pkg_exit(void)
{
unregister_kfreecess_hook(MOD_PKG);
unregister_kfreecess_hook(MOD_CFB);
nf_unregister_hooks(freecess_nf_ops, ARRAY_SIZE(freecess_nf_ops));
}
module_init(kfreecess_pkg_init);
module_exit(kfreecess_pkg_exit);
MODULE_LICENSE("GPL");

View file

@ -450,40 +450,6 @@ static u64 freezer_parent_freezing_read(struct cgroup_subsys_state *css,
return (bool)(freezer->state & CGROUP_FREEZING_PARENT); return (bool)(freezer->state & CGROUP_FREEZING_PARENT);
} }
#ifdef CONFIG_SAMSUNG_FREECESS
/**
* Check if the task is allowed to be added to the freezer group
* only the admin can add the task to the freezer group.
*/
static int freezer_can_attach(struct cgroup_taskset *tset)
{
const struct cred *cred = current_cred(), *tcred;
struct task_struct *task;
struct cgroup_subsys_state *css;
cgroup_taskset_for_each(task, css, tset) {
tcred = __task_cred(task);
//Only system process and root have the permission.
if ((current != task) && !(cred->euid.val == 1000 || capable(CAP_SYS_ADMIN))) {
pr_err("Permission problem\n");
return -EACCES;
}
}
return 0;
}
/**
* Cancel the attach action when it failed. It's usually used to restore the attach action.
* But freezer attach just sends the signal, it will always success.
* So, it doesn't need to restore any action.
*/
static void freezer_cancel_attach(struct cgroup_taskset *tset)
{
}
#endif
static struct cftype files[] = { static struct cftype files[] = {
{ {
.name = "state", .name = "state",
@ -512,8 +478,4 @@ struct cgroup_subsys freezer_cgrp_subsys = {
.attach = freezer_attach, .attach = freezer_attach,
.fork = freezer_fork, .fork = freezer_fork,
.legacy_cftypes = files, .legacy_cftypes = files,
#ifdef CONFIG_SAMSUNG_FREECESS
.can_attach = freezer_can_attach,
.cancel_attach = freezer_cancel_attach,
#endif
}; };

View file

@ -46,9 +46,6 @@
#include <asm/siginfo.h> #include <asm/siginfo.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include "audit.h" /* audit_signal_info() */ #include "audit.h" /* audit_signal_info() */
#ifdef CONFIG_SAMSUNG_FREECESS
#include <linux/freecess.h>
#endif
/* /*
* SLAB caches for signal bits. * SLAB caches for signal bits.
@ -1208,12 +1205,6 @@ int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
unsigned long flags; unsigned long flags;
int ret = -ESRCH; int ret = -ESRCH;
#ifdef CONFIG_SAMSUNG_FREECESS
if ((sig == SIGKILL || sig == SIGTERM || sig == SIGABRT || sig == SIGQUIT))
sig_report(current, p);
#endif
if (lock_task_sighand(p, &flags)) { if (lock_task_sighand(p, &flags)) {
ret = send_signal(sig, info, p, group); ret = send_signal(sig, info, p, group);
unlock_task_sighand(p, &flags); unlock_task_sighand(p, &flags);