1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-03-09 15:40:20 +00:00

Fix RUTX support

This commit is contained in:
Ycarus (Yannick Chabanois) 2022-03-07 20:21:35 +01:00
parent 6fc4d11e09
commit 0b14e36374
98 changed files with 11611 additions and 893 deletions

View file

@ -0,0 +1,80 @@
Index: linux-5.4.147/kernel/bpf/syscall.c
===================================================================
--- linux-5.4.147.orig/kernel/bpf/syscall.c
+++ linux-5.4.147/kernel/bpf/syscall.c
@@ -593,6 +593,11 @@ static int map_create(union bpf_attr *at
err = PTR_ERR(btf);
goto free_map;
}
+ if (btf_is_kernel(btf)) {
+ btf_put(btf);
+ err = -EACCES;
+ goto free_map;
+ }
err = map_check_btf(map, btf, attr->btf_key_type_id,
attr->btf_value_type_id);
Index: linux-5.4.147/kernel/bpf/verifier.c
===================================================================
--- linux-5.4.147.orig/kernel/bpf/verifier.c
+++ linux-5.4.147/kernel/bpf/verifier.c
@@ -6959,6 +6959,11 @@ static int check_btf_info(struct bpf_ver
btf = btf_get_by_fd(attr->prog_btf_fd);
if (IS_ERR(btf))
return PTR_ERR(btf);
+ if (btf_is_kernel(btf)) {
+ btf_put(btf);
+ return -EACCES;
+ }
+
env->prog->aux->btf = btf;
err = check_btf_func(env, attr, uattr);
Index: linux-5.4.147/include/linux/btf.h
===================================================================
--- linux-5.4.147.orig/include/linux/btf.h
+++ linux-5.4.147/include/linux/btf.h
@@ -47,6 +47,7 @@ void btf_type_seq_show(const struct btf
struct seq_file *m);
int btf_get_fd_by_id(u32 id);
u32 btf_id(const struct btf *btf);
+bool btf_is_kernel(const struct btf *btf);
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
const struct btf_member *m,
u32 expected_offset, u32 expected_size);
Index: linux-5.4.147/kernel/bpf/btf.c
===================================================================
--- linux-5.4.147.orig/kernel/bpf/btf.c
+++ linux-5.4.147/kernel/bpf/btf.c
@@ -212,6 +212,7 @@ struct btf {
refcount_t refcnt;
u32 id;
struct rcu_head rcu;
+ bool kernel_btf;
};
enum verifier_phase {
@@ -352,6 +353,11 @@ static bool btf_type_nosize(const struct
btf_type_is_func(t) || btf_type_is_func_proto(t);
}
+bool btf_is_kernel(const struct btf *btf)
+{
+ return btf->kernel_btf;
+}
+
static bool btf_type_nosize_or_null(const struct btf_type *t)
{
return !t || btf_type_nosize(t);
Index: linux-5.4.147/include/uapi/linux/bpf.h
===================================================================
--- linux-5.4.147.orig/include/uapi/linux/bpf.h
+++ linux-5.4.147/include/uapi/linux/bpf.h
@@ -3275,6 +3275,7 @@ struct bpf_btf_info {
__aligned_u64 btf;
__u32 btf_size;
__u32 id;
+ __u32 kernel_btf;
} __attribute__((aligned(8)));
/* User bpf_sock_addr struct to access socket fields and sockaddr struct passed

View file

@ -0,0 +1,53 @@
From: Bui Quang Minh @ 2021-01-26 8:26 UTC (permalink / raw)
To: ast, daniel, davem, kuba, hawk, john.fastabend, andrii, kafai,
songliubraving, yhs, kpsingh, jakub, lmb
Cc: netdev, bpf, linux-kernel, minhquangbui99
In 32-bit architecture, the result of sizeof() is a 32-bit integer so
the expression becomes the multiplication between 2 32-bit integer which
can potentially leads to integer overflow. As a result,
bpf_map_area_alloc() allocates less memory than needed.
Fix this by casting 1 operand to u64.
Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
---
kernel/bpf/devmap.c | 4 ++--
net/core/sock_map.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
Index: linux-5.4.147/kernel/bpf/devmap.c
===================================================================
--- linux-5.4.147.orig/kernel/bpf/devmap.c
+++ linux-5.4.147/kernel/bpf/devmap.c
@@ -94,7 +94,7 @@ static struct hlist_head *dev_map_create
int i;
struct hlist_head *hash;
- hash = bpf_map_area_alloc(entries * sizeof(*hash), numa_node);
+ hash = bpf_map_area_alloc((u64) entries * sizeof(*hash), numa_node);
if (hash != NULL)
for (i = 0; i < entries; i++)
INIT_HLIST_HEAD(&hash[i]);
@@ -159,7 +159,7 @@ static int dev_map_init_map(struct bpf_d
spin_lock_init(&dtab->index_lock);
} else {
- dtab->netdev_map = bpf_map_area_alloc(dtab->map.max_entries *
+ dtab->netdev_map = bpf_map_area_alloc((u64) dtab->map.max_entries *
sizeof(struct bpf_dtab_netdev *),
dtab->map.numa_node);
if (!dtab->netdev_map)
Index: linux-5.4.147/net/core/sock_map.c
===================================================================
--- linux-5.4.147.orig/net/core/sock_map.c
+++ linux-5.4.147/net/core/sock_map.c
@@ -48,7 +48,7 @@ static struct bpf_map *sock_map_alloc(un
if (err)
goto free_stab;
- stab->sks = bpf_map_area_alloc(stab->map.max_entries *
+ stab->sks = bpf_map_area_alloc((u64) stab->map.max_entries *
sizeof(struct sock *),
stab->map.numa_node);
if (stab->sks)

View file

@ -0,0 +1,48 @@
From 05acefb4872dae89e772729efb194af754c877e8 Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <mszeredi@redhat.com>
Date: Tue, 2 Jun 2020 22:20:26 +0200
Subject: ovl: check permission to open real file
Call inode_permission() on real inode before opening regular file on one of
the underlying layers.
In some cases ovl_permission() already checks access to an underlying file,
but it misses the metacopy case, and possibly other ones as well.
Removing the redundant permission check from ovl_permission() should be
considered later.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
fs/overlayfs/file.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
Index: linux-5.4.147/fs/overlayfs/file.c
===================================================================
--- linux-5.4.147.orig/fs/overlayfs/file.c
+++ linux-5.4.147/fs/overlayfs/file.c
@@ -34,10 +34,22 @@ static struct file *ovl_open_realfile(co
struct file *realfile;
const struct cred *old_cred;
int flags = file->f_flags | OVL_OPEN_FLAGS;
+ int acc_mode = ACC_MODE(flags);
+ int err;
+
+ if (flags & O_APPEND)
+ acc_mode |= MAY_APPEND;
old_cred = ovl_override_creds(inode->i_sb);
- realfile = open_with_fake_path(&file->f_path, flags, realinode,
- current_cred());
+ err = inode_permission(realinode, MAY_OPEN | acc_mode);
+ if (err) {
+ realfile = ERR_PTR(err);
+ } else if (!inode_owner_or_capable(realinode)) {
+ realfile = ERR_PTR(-EPERM);
+ } else {
+ realfile = open_with_fake_path(&file->f_path, flags, realinode,
+ current_cred());
+ }
revert_creds(old_cred);
pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",

View file

@ -0,0 +1,73 @@
From 48bd024b8a40d73ad6b086de2615738da0c7004f Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <mszeredi@redhat.com>
Date: Tue, 2 Jun 2020 22:20:25 +0200
Subject: ovl: switch to mounter creds in readdir
In preparation for more permission checking, override credentials for
directory operations on the underlying filesystems.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
fs/overlayfs/readdir.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
Index: linux-5.4.147/fs/overlayfs/readdir.c
===================================================================
--- linux-5.4.147.orig/fs/overlayfs/readdir.c
+++ linux-5.4.147/fs/overlayfs/readdir.c
@@ -732,8 +732,10 @@ static int ovl_iterate(struct file *file
struct ovl_dir_file *od = file->private_data;
struct dentry *dentry = file->f_path.dentry;
struct ovl_cache_entry *p;
+ const struct cred *old_cred;
int err;
+ old_cred = ovl_override_creds(dentry->d_sb);
if (!ctx->pos)
ovl_dir_reset(file);
@@ -747,17 +749,20 @@ static int ovl_iterate(struct file *file
(ovl_same_sb(dentry->d_sb) &&
(ovl_is_impure_dir(file) ||
OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
- return ovl_iterate_real(file, ctx);
+ err = ovl_iterate_real(file, ctx);
+ } else {
+ err = iterate_dir(od->realfile, ctx);
}
- return iterate_dir(od->realfile, ctx);
+ goto out;
}
if (!od->cache) {
struct ovl_dir_cache *cache;
cache = ovl_cache_get(dentry);
+ err = PTR_ERR(cache);
if (IS_ERR(cache))
- return PTR_ERR(cache);
+ goto out;
od->cache = cache;
ovl_seek_cursor(od, ctx->pos);
@@ -769,7 +774,7 @@ static int ovl_iterate(struct file *file
if (!p->ino) {
err = ovl_cache_update_ino(&file->f_path, p);
if (err)
- return err;
+ goto out;
}
if (!dir_emit(ctx, p->name, p->len, p->ino, p->type))
break;
@@ -777,7 +782,10 @@ static int ovl_iterate(struct file *file
od->cursor = p->l_node.next;
ctx->pos++;
}
- return 0;
+ err = 0;
+out:
+ revert_creds(old_cred);
+ return err;
}
static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)

View file

@ -0,0 +1,61 @@
From 56230d956739b9cb1cbde439d76227d77979a04d Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <mszeredi@redhat.com>
Date: Tue, 2 Jun 2020 22:20:26 +0200
Subject: ovl: verify permissions in ovl_path_open()
Check permission before opening a real file.
ovl_path_open() is used by readdir and copy-up routines.
ovl_permission() theoretically already checked copy up permissions, but it
doesn't hurt to re-do these checks during the actual copy-up.
For directory reading ovl_permission() only checks access to topmost
underlying layer. Readdir on a merged directory accesses layers below the
topmost one as well. Permission wasn't checked for these layers.
Note: modifying ovl_permission() to perform this check would be far more
complex and hence more bug prone. The result is less precise permissions
returned in access(2). If this turns out to be an issue, we can revisit
this bug.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
fs/overlayfs/util.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
Index: linux-5.4.147/fs/overlayfs/util.c
===================================================================
--- linux-5.4.147.orig/fs/overlayfs/util.c
+++ linux-5.4.147/fs/overlayfs/util.c
@@ -475,7 +475,29 @@ bool ovl_is_whiteout(struct dentry *dent
struct file *ovl_path_open(struct path *path, int flags)
{
- return dentry_open(path, flags | O_NOATIME, current_cred());
+ struct inode *inode = d_inode(path->dentry);
+ int err, acc_mode;
+
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ acc_mode = MAY_READ;
+ break;
+ case O_WRONLY:
+ acc_mode = MAY_WRITE;
+ break;
+ default:
+ BUG();
+ }
+
+ err = inode_permission(inode, acc_mode | MAY_OPEN);
+ if (err)
+ return ERR_PTR(err);
+
+ /* O_NOATIME is an optimization, don't fail if not permitted */
+ if (inode_owner_or_capable(inode))
+ flags |= O_NOATIME;
+
+ return dentry_open(path, flags, current_cred());
}
/* Caller should hold ovl_inode->lock */

View file

@ -0,0 +1,46 @@
From b6650dab404c701d7fe08a108b746542a934da84 Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <mszeredi@redhat.com>
Date: Mon, 14 Dec 2020 15:26:14 +0100
Subject: ovl: do not fail because of O_NOATIME
In case the file cannot be opened with O_NOATIME because of lack of
capabilities, then clear O_NOATIME instead of failing.
Remove WARN_ON(), since it would now trigger if O_NOATIME was cleared.
Noticed by Amir Goldstein.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
fs/overlayfs/file.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
Index: linux-5.4.147/fs/overlayfs/file.c
===================================================================
--- linux-5.4.147.orig/fs/overlayfs/file.c
+++ linux-5.4.147/fs/overlayfs/file.c
@@ -44,9 +44,10 @@ static struct file *ovl_open_realfile(co
err = inode_permission(realinode, MAY_OPEN | acc_mode);
if (err) {
realfile = ERR_PTR(err);
- } else if (!inode_owner_or_capable(realinode)) {
- realfile = ERR_PTR(-EPERM);
} else {
+ if (!inode_owner_or_capable(realinode))
+ flags &= ~O_NOATIME;
+
realfile = open_with_fake_path(&file->f_path, flags, realinode,
current_cred());
}
@@ -66,12 +67,6 @@ static int ovl_change_flags(struct file
struct inode *inode = file_inode(file);
int err;
- flags |= OVL_OPEN_FLAGS;
-
- /* If some flag changed that cannot be changed then something's amiss */
- if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK))
- return -EIO;
-
flags &= OVL_SETFL_MASK;
if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))

View file

@ -0,0 +1,17 @@
Index: linux-5.4.124/drivers/net/ppp/pppoe.c
===================================================================
--- linux-5.4.124.orig/drivers/net/ppp/pppoe.c
+++ linux-5.4.124/drivers/net/ppp/pppoe.c
@@ -502,6 +502,12 @@ static int pppoe_disc_rcv(struct sk_buff
if (ph->code != PADT_CODE)
goto abort;
+ // compare the dst addr to the current net device addr and ignore packet if not matching
+ // otherwise it will terminate the connection
+ if(!ether_addr_equal(eth_hdr(skb)->h_dest, dev->dev_addr)) {
+ goto abort;
+ }
+
pn = pppoe_pernet(dev_net(dev));
po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (po)