tkernel: initial support and nonpriv_bind
Upstream: no - /proc/tkernel/nonpriv_netbind: Contain list of ports allowed for nonpriv bind echo +80 > /proc/tkernel/nonpriv_netbind echo -80 > /proc/tkernel/nonpriv_netbind Controls whether allow/deny nonpriv user bind to specified port. Signed-off-by: Samuel Liao <samuelliao@tencent.com> Signed-off-by: Xiaoming Gao <newtongao@tencent.com> Signed-off-by: katrinzhou <katrinzhou@tencent.com> Signed-off-by: Kairui Song <kasong@tencent.com>
This commit is contained in:
parent
95c98461d1
commit
0585394287
|
@ -0,0 +1,18 @@
|
|||
#include <linux/sysctl.h>
|
||||
#include <linux/proc_fs.h>
|
||||
extern struct proc_dir_entry *proc_tkernel;
|
||||
extern const struct ctl_path tkernel_ctl_path[];
|
||||
|
||||
/* prot_sock_flag */
|
||||
#ifdef CONFIG_TKERNEL_NONPRIV_NETBIND
|
||||
extern bool nonpriv_prot_sock_flag[];
|
||||
static inline bool check_nonpriv_prot_sock(int num)
|
||||
{
|
||||
return nonpriv_prot_sock_flag[num];
|
||||
}
|
||||
#else
|
||||
static inline bool check_nonpriv_prot_sock(int num)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
|
@ -1968,6 +1968,7 @@ config ASN1
|
|||
functions to call on what tags.
|
||||
|
||||
source "kernel/Kconfig.locks"
|
||||
source "kernel/Kconfig.tkernel"
|
||||
|
||||
config ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
|
||||
bool
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
source "kernel/tkernel/Kconfig"
|
|
@ -114,6 +114,7 @@ obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
|
|||
obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o
|
||||
obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call_inline.o
|
||||
obj-$(CONFIG_CFI_CLANG) += cfi.o
|
||||
obj-$(CONFIG_TKERNEL) += tkernel/
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += events/
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menuconfig TKERNEL
|
||||
bool "Tencent Kernel Features"
|
||||
default n
|
||||
|
||||
if TKERNEL
|
||||
|
||||
config TKERNEL_NONPRIV_NETBIND
|
||||
bool "Allow non-privileged user to bind specific low ports"
|
||||
default n
|
||||
|
||||
endif
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_TKERNEL) += base.o
|
||||
obj-$(CONFIG_TKERNEL_NONPRIV_NETBIND) += netbind.o
|
|
@ -0,0 +1,19 @@
|
|||
#include <linux/proc_fs.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/tkernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
struct proc_dir_entry *proc_tkernel;
|
||||
EXPORT_SYMBOL(proc_tkernel);
|
||||
|
||||
static struct ctl_table placeholder_vars[] = {
|
||||
{},
|
||||
};
|
||||
|
||||
static int __init tkernel_init(void)
|
||||
{
|
||||
proc_tkernel = proc_mkdir("tkernel", NULL);
|
||||
register_sysctl_init("tkernel", placeholder_vars);
|
||||
return 0;
|
||||
}
|
||||
early_initcall(tkernel_init);
|
|
@ -0,0 +1,89 @@
|
|||
#include <linux/tkernel.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
bool nonpriv_prot_sock_flag[PROT_SOCK];
|
||||
EXPORT_SYMBOL(nonpriv_prot_sock_flag);
|
||||
|
||||
static int netbind_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < PROT_SOCK; i++) {
|
||||
if (nonpriv_prot_sock_flag[i])
|
||||
seq_printf(m, "%d\n", i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netbind_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, netbind_proc_show, NULL);
|
||||
}
|
||||
|
||||
static ssize_t netbind_proc_write(struct file *file, const char __user *buf,
|
||||
size_t length, loff_t *ppos)
|
||||
{
|
||||
int port, en;
|
||||
char *buffer, *p;
|
||||
int err;
|
||||
|
||||
if (!buf || length > PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
buffer = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
err = -EFAULT;
|
||||
if (copy_from_user(buffer, buf, length))
|
||||
goto out;
|
||||
|
||||
err = -EINVAL;
|
||||
if (length < PAGE_SIZE)
|
||||
buffer[length] = '\0';
|
||||
else if (buffer[PAGE_SIZE-1])
|
||||
goto out;
|
||||
|
||||
en = 1;
|
||||
p = buffer;
|
||||
if (*p == '+') {
|
||||
p++;
|
||||
} else if (*p == '-') {
|
||||
en = 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p < '0' || *p > '9')
|
||||
goto out;
|
||||
|
||||
port = simple_strtoul(p, &p, 0);
|
||||
if (*p != '\n' && *p != '\r' && *p != '\0')
|
||||
goto out;
|
||||
|
||||
if (port <= 0 || port >= PROT_SOCK)
|
||||
goto out;
|
||||
|
||||
nonpriv_prot_sock_flag[port] = en;
|
||||
err = length;
|
||||
|
||||
out:
|
||||
free_page((unsigned long)buffer);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct proc_ops netbind_proc_ops = {
|
||||
.proc_open = netbind_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_write = netbind_proc_write,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
|
||||
static int __init nonpriv_netbind_init(void)
|
||||
{
|
||||
proc_create("nonpriv_netbind", 0, proc_tkernel, &netbind_proc_ops);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(nonpriv_netbind_init);
|
|
@ -121,6 +121,7 @@
|
|||
#include <net/compat.h>
|
||||
|
||||
#include <trace/events/sock.h>
|
||||
#include <linux/tkernel.h>
|
||||
|
||||
/* The inetsw table contains everything that inet_create needs to
|
||||
* build a new socket.
|
||||
|
@ -505,7 +506,7 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
|
|||
snum = ntohs(addr->sin_port);
|
||||
err = -EACCES;
|
||||
if (!(flags & BIND_NO_CAP_NET_BIND_SERVICE) &&
|
||||
snum && inet_port_requires_bind_service(net, snum) &&
|
||||
snum && inet_port_requires_bind_service(net, snum) && !check_nonpriv_prot_sock(snum) &&
|
||||
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/mroute6.h>
|
||||
#include <linux/tkernel.h>
|
||||
|
||||
#include "ip6_offload.h"
|
||||
|
||||
|
@ -296,7 +297,7 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
|
|||
|
||||
snum = ntohs(addr->sin6_port);
|
||||
if (!(flags & BIND_NO_CAP_NET_BIND_SERVICE) &&
|
||||
snum && inet_port_requires_bind_service(net, snum) &&
|
||||
snum && inet_port_requires_bind_service(net, snum) && !check_nonpriv_prot_sock(snum) &&
|
||||
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
|
||||
return -EACCES;
|
||||
|
||||
|
|
Loading…
Reference in New Issue