tkernel: make the code for the kill block feature cleaner
No functional changes, just making the code cleaner. Signed-off-by: Yongliang Gao <leonylgao@tencent.com> Reviewed-by: Jianping Liu <frankjpliu@tencent.com>
This commit is contained in:
parent
3cc17b97d8
commit
757f8aaf97
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/tkernel/killblock/kill_block.c
|
||||
* kernel/tkernel/killblock/kill_block.c
|
||||
*
|
||||
* Copyright (C) 2023 Hongbo Li <herberthbli@tencent.com>
|
||||
*/
|
||||
|
@ -15,13 +15,25 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <linux/cgroup.h>
|
||||
#include <linux/kill_hook.h>
|
||||
#include "kill_block.h"
|
||||
|
||||
int sysctl_sig_kill_block;
|
||||
#define KILL_BLOCK_DIR "kill_block"
|
||||
#define KILL_BLOCK_CMD_LEN 128
|
||||
#define KILL_BLOCK_CGRP_LEN 64
|
||||
#define KILL_BLOCK_RULES_MAX_CNT 1024
|
||||
|
||||
struct kb_whitelist_rule {
|
||||
struct list_head node;
|
||||
char src_comm[TASK_COMM_LEN];
|
||||
char dst_comm[TASK_COMM_LEN];
|
||||
char dst_cgrp[KILL_BLOCK_CGRP_LEN];
|
||||
};
|
||||
|
||||
static unsigned int two = 2;
|
||||
static unsigned int sysctl_sig_kill_block;
|
||||
static atomic64_t kb_cnt_root = ATOMIC64_INIT(0);
|
||||
static atomic64_t kb_cnt_child = ATOMIC64_INIT(0);
|
||||
static atomic_t kb_rule_cnt = ATOMIC_INIT(0);
|
||||
static struct proc_dir_entry *kb_proc_dir;
|
||||
static struct proc_dir_entry *kb_proc_dir;
|
||||
static struct proc_dir_entry *whitelist_entry;
|
||||
static struct proc_dir_entry *stat_entry;
|
||||
static struct ctl_table_header *kb_sysctl_header;
|
||||
|
@ -32,22 +44,19 @@ static struct kill_hook kill_block_hook;
|
|||
static ssize_t whitelist_write(struct file *file, const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char cmd[KILL_BLOCK_CMD_LEN], _str[KILL_BLOCK_CMD_LEN];
|
||||
char cmd[KILL_BLOCK_CMD_LEN] = {0};
|
||||
char *token[4], *str;
|
||||
int cnt, i = 0;
|
||||
int cnt, i;
|
||||
struct kb_whitelist_rule *rule, *tmp;
|
||||
|
||||
memset(cmd, 0, KILL_BLOCK_CMD_LEN);
|
||||
|
||||
cnt = min_t(size_t, count, KILL_BLOCK_CMD_LEN - 1);
|
||||
if (strncpy_from_user(cmd, ubuf, cnt) < 0)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
|
||||
if (strlen(cmd) < 1)
|
||||
return -EINVAL;
|
||||
|
||||
strcpy(_str, cmd);
|
||||
str = _str;
|
||||
str = cmd;
|
||||
str[cnt - 1] = '\0';
|
||||
|
||||
i = 0;
|
||||
|
@ -61,15 +70,14 @@ static ssize_t whitelist_write(struct file *file, const char __user *ubuf,
|
|||
|
||||
if (i == 1) {
|
||||
if (!strcmp(token[0], "flush")) {
|
||||
write_lock_bh(&whitelist_lock);
|
||||
list_for_each_entry_safe(rule, tmp, &whitelist_list,
|
||||
node) {
|
||||
write_lock(&whitelist_lock);
|
||||
list_for_each_entry_safe(rule, tmp, &whitelist_list, node) {
|
||||
list_del(&rule->node);
|
||||
kfree(rule);
|
||||
}
|
||||
write_unlock_bh(&whitelist_lock);
|
||||
write_unlock(&whitelist_lock);
|
||||
atomic_set(&kb_rule_cnt, 0);
|
||||
return cnt;
|
||||
return count;
|
||||
}
|
||||
return -EINVAL;
|
||||
} else if (i != 4) {
|
||||
|
@ -79,7 +87,7 @@ static ssize_t whitelist_write(struct file *file, const char __user *ubuf,
|
|||
if (!strcmp(token[0], "add")) {
|
||||
if (atomic_read(&kb_rule_cnt) >= KILL_BLOCK_RULES_MAX_CNT)
|
||||
return -ENOMEM;
|
||||
rule = kzalloc(sizeof(*rule), GFP_KERNEL);
|
||||
rule = kzalloc(sizeof(struct kb_whitelist_rule), GFP_KERNEL);
|
||||
if (!rule)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -92,32 +100,34 @@ static ssize_t whitelist_write(struct file *file, const char __user *ubuf,
|
|||
cnt = min_t(size_t, KILL_BLOCK_CGRP_LEN - 1, strlen(token[3]));
|
||||
strncpy(rule->dst_cgrp, token[3], cnt);
|
||||
rule->dst_cgrp[cnt] = '\0';
|
||||
write_lock_bh(&whitelist_lock);
|
||||
write_lock(&whitelist_lock);
|
||||
list_for_each_entry(tmp, &whitelist_list, node) {
|
||||
if (!strcasecmp(tmp->src_comm, rule->src_comm) &&
|
||||
!strcasecmp(tmp->dst_comm, rule->dst_comm) &&
|
||||
!strcasecmp(tmp->dst_cgrp, rule->dst_cgrp)) {
|
||||
write_unlock_bh(&whitelist_lock);
|
||||
write_unlock(&whitelist_lock);
|
||||
kfree(rule);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
list_add(&rule->node, &whitelist_list);
|
||||
write_unlock_bh(&whitelist_lock);
|
||||
write_unlock(&whitelist_lock);
|
||||
atomic_inc(&kb_rule_cnt);
|
||||
} else if (!strcmp(token[0], "del")) {
|
||||
write_lock_bh(&whitelist_lock);
|
||||
write_lock(&whitelist_lock);
|
||||
list_for_each_entry_safe(rule, tmp, &whitelist_list, node) {
|
||||
if (!strcasecmp(rule->src_comm, token[1]) &&
|
||||
!strcasecmp(rule->dst_comm, token[2]) &&
|
||||
!strcasecmp(rule->dst_cgrp, token[3])) {
|
||||
list_del(&rule->node);
|
||||
write_unlock(&whitelist_lock);
|
||||
kfree(rule);
|
||||
atomic_dec(&kb_rule_cnt);
|
||||
break;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
write_unlock_bh(&whitelist_lock);
|
||||
write_unlock(&whitelist_lock);
|
||||
return -ESRCH;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -127,7 +137,7 @@ static ssize_t whitelist_write(struct file *file, const char __user *ubuf,
|
|||
|
||||
static void *whitelist_seq_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
read_lock_bh(&whitelist_lock);
|
||||
read_lock(&whitelist_lock);
|
||||
return seq_list_start_head(&whitelist_list, *pos);
|
||||
}
|
||||
|
||||
|
@ -138,7 +148,7 @@ static void *whitelist_seq_next(struct seq_file *m, void *v, loff_t *pos)
|
|||
|
||||
static void whitelist_seq_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
read_unlock_bh(&whitelist_lock);
|
||||
read_unlock(&whitelist_lock);
|
||||
}
|
||||
|
||||
static int whitelist_seq_show(struct seq_file *m, void *v)
|
||||
|
@ -185,18 +195,6 @@ static int stat_proc_show(struct seq_file *m, void *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int stat_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, stat_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct proc_ops stat_fops = {
|
||||
.proc_open = stat_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
|
||||
/* get the length of podid, not include '\0' */
|
||||
static unsigned int kill_block_get_podid_len(char *podid_start)
|
||||
{
|
||||
|
@ -215,19 +213,17 @@ static unsigned int kill_block_get_podid_len(char *podid_start)
|
|||
return podid_len;
|
||||
}
|
||||
|
||||
int kill_block_whitelist_match(struct task_struct *p, int sig,
|
||||
bool kill_block_whitelist_match(struct task_struct *p, int sig,
|
||||
char *src_cgrp_path, char *src_cgrp_name,
|
||||
char *dst_cgrp_path, char *dst_cgrp_name)
|
||||
{
|
||||
struct kb_whitelist_rule *rule;
|
||||
char *src_podid_start, *dst_podid_start;
|
||||
unsigned int src_podid_len, dst_podid_len;
|
||||
int match = 1;
|
||||
bool match = true;
|
||||
|
||||
if (!sysctl_sig_kill_block) {
|
||||
match = 0;
|
||||
goto out;
|
||||
}
|
||||
if (sysctl_sig_kill_block == 0)
|
||||
return false;
|
||||
|
||||
/* check whether the src and dst cgrp are pods */
|
||||
if (glob_match("*kubepods*", src_cgrp_path) &&
|
||||
|
@ -246,13 +242,13 @@ int kill_block_whitelist_match(struct task_struct *p, int sig,
|
|||
|
||||
/* src and dst are in a same pod */
|
||||
if (!strncmp(src_podid_start, dst_podid_start, src_podid_len)) {
|
||||
match = 0;
|
||||
match = false;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
check_rule:
|
||||
read_lock_bh(&whitelist_lock);
|
||||
read_lock(&whitelist_lock);
|
||||
if (list_empty(&whitelist_list))
|
||||
goto out_unlock;
|
||||
|
||||
|
@ -261,12 +257,12 @@ check_rule:
|
|||
glob_match(rule->dst_comm, p->comm) &&
|
||||
(glob_match(rule->dst_cgrp, dst_cgrp_name) ||
|
||||
glob_match(rule->dst_cgrp, dst_cgrp_path))) {
|
||||
match = 0;
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
out_unlock:
|
||||
read_unlock_bh(&whitelist_lock);
|
||||
read_unlock(&whitelist_lock);
|
||||
out:
|
||||
if (match) {
|
||||
if (glob_match("*kubepods*", dst_cgrp_path))
|
||||
|
@ -295,7 +291,7 @@ static int kill_block_hook_func(int sig, struct kernel_siginfo *info, struct tas
|
|||
char src_cgrp_name[KILL_BLOCK_CGRP_NAME_LEN];
|
||||
char dst_cgrp_name[KILL_BLOCK_CGRP_NAME_LEN];
|
||||
int ret = 0;
|
||||
int block = 0;
|
||||
bool block = false;
|
||||
|
||||
if (sig != SIGKILL && sig != SIGTERM)
|
||||
return 0;
|
||||
|
@ -330,16 +326,18 @@ static int register_kill_block_hook(void)
|
|||
|
||||
static void unregister_kill_block_hook(void)
|
||||
{
|
||||
unregister_kill_hook(&kill_block_hook);
|
||||
(void)unregister_kill_hook(&kill_block_hook);
|
||||
}
|
||||
|
||||
static struct ctl_table kb_sysctl_table[] = {
|
||||
{
|
||||
.procname = "sig_kill_block",
|
||||
.data = &sysctl_sig_kill_block,
|
||||
.maxlen = sizeof(int),
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.proc_handler = proc_douintvec_minmax,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = &two,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
@ -367,7 +365,7 @@ static int __init kill_block_mod_init(void)
|
|||
goto out_entry;
|
||||
}
|
||||
|
||||
stat_entry = proc_create("stat", 0, kb_proc_dir, &stat_fops);
|
||||
stat_entry = proc_create_single("stat", 0644, kb_proc_dir, stat_proc_show);
|
||||
if (!stat_entry) {
|
||||
pr_err("Couldn't create stat proc entry\n");
|
||||
goto out_entry;
|
||||
|
@ -397,12 +395,12 @@ static void __exit kill_block_mod_exit(void)
|
|||
unregister_kill_block_hook();
|
||||
|
||||
remove_proc_subtree(KILL_BLOCK_DIR, NULL);
|
||||
write_lock_bh(&whitelist_lock);
|
||||
write_lock(&whitelist_lock);
|
||||
list_for_each_entry_safe(rule, tmp, &whitelist_list, node) {
|
||||
list_del(&rule->node);
|
||||
kfree(rule);
|
||||
}
|
||||
write_unlock_bh(&whitelist_lock);
|
||||
write_unlock(&whitelist_lock);
|
||||
unregister_sysctl_table(kb_sysctl_header);
|
||||
|
||||
pr_info("signal kill block module exit\n");
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_KILL_BLOCK_H
|
||||
#define _LINUX_KILL_BLOCK_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define KILL_BLOCK_DIR "kill_block"
|
||||
#define KILL_BLOCK_CMD_LEN 128
|
||||
#define KILL_BLOCK_CGRP_LEN 64
|
||||
#define KILL_BLOCK_RULES_MAX_CNT 1024
|
||||
|
||||
struct kb_whitelist_rule {
|
||||
struct list_head node;
|
||||
char src_comm[TASK_COMM_LEN];
|
||||
char dst_comm[TASK_COMM_LEN];
|
||||
char dst_cgrp[KILL_BLOCK_CGRP_LEN];
|
||||
};
|
||||
|
||||
extern int sysctl_sig_kill_block;
|
||||
|
||||
#endif /*_LINUX_KILL_BLOCK_H*/
|
Loading…
Reference in New Issue