* Re: [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag.
@ 2022-02-02 14:00 kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2022-02-02 14:00 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 14226 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20220201205534.1962784-3-haoluo@google.com>
References: <20220201205534.1962784-3-haoluo@google.com>
TO: Hao Luo <haoluo@google.com>
Hi Hao,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Hao-Luo/Extend-cgroup-interface-with-bpf/20220202-045743
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
:::::: branch date: 17 hours ago
:::::: commit date: 17 hours ago
config: i386-randconfig-c001 (https://download.01.org/0day-ci/archive/20220202/202202022147.xPerjqdl-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 6b1e844b69f15bb7dffaf9365cd2b355d2eb7579)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/f6c6ca7ed744371ccc22d4c3b945ebdb3651efaf
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Hao-Luo/Extend-cgroup-interface-with-bpf/20220202-045743
git checkout f6c6ca7ed744371ccc22d4c3b945ebdb3651efaf
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=i386 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
fs/ntfs3/fsntfs.c:1203:4: note: Taking false branch
if (buf) {
^
include/linux/compiler.h:56:23: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
fs/ntfs3/fsntfs.c:1208:4: note: '?' condition is false
if (!nb) {
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:31: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
fs/ntfs3/fsntfs.c:1208:9: note: 'nb' is null
if (!nb) {
^
include/linux/compiler.h:56:47: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~
include/linux/compiler.h:58:86: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
include/linux/compiler.h:69:3: note: expanded from macro '__trace_if_value'
(cond) ? \
^~~~
fs/ntfs3/fsntfs.c:1208:4: note: '?' condition is true
if (!nb) {
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:69: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
include/linux/compiler.h:69:2: note: expanded from macro '__trace_if_value'
(cond) ? \
^
fs/ntfs3/fsntfs.c:1208:4: note: Taking true branch
if (!nb) {
^
include/linux/compiler.h:56:23: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
fs/ntfs3/fsntfs.c:1219:8: note: Assuming 'bytes' is not equal to 0
if (!bytes)
^
include/linux/compiler.h:56:47: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~
include/linux/compiler.h:58:52: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
fs/ntfs3/fsntfs.c:1219:4: note: '?' condition is false
if (!bytes)
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:31: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
fs/ntfs3/fsntfs.c:1219:9: note: 'bytes' is not equal to 0
if (!bytes)
^
include/linux/compiler.h:56:47: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~
include/linux/compiler.h:58:86: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
include/linux/compiler.h:69:3: note: expanded from macro '__trace_if_value'
(cond) ? \
^~~~
fs/ntfs3/fsntfs.c:1219:4: note: '?' condition is false
if (!bytes)
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:69: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
include/linux/compiler.h:69:2: note: expanded from macro '__trace_if_value'
(cond) ? \
^
fs/ntfs3/fsntfs.c:1219:4: note: Taking false branch
if (!bytes)
^
include/linux/compiler.h:56:23: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
fs/ntfs3/fsntfs.c:1191:3: note: Loop condition is false. Exiting loop
do {
^
fs/ntfs3/fsntfs.c:1227:18: note: The right operand of '+' is a garbage value
vcn_next = vcn + clen;
^ ~~~~
2 warnings generated.
>> kernel/bpf/inode.c:71:2: warning: Use of memory after it is freed [clang-analyzer-unix.Malloc]
list_for_each_entry(e, &list->list, list) {
^
include/linux/list.h:640:13: note: expanded from macro 'list_for_each_entry'
pos = list_next_entry(pos, member))
^
include/linux/list.h:564:2: note: expanded from macro 'list_next_entry'
list_entry((pos)->member.next, typeof(*(pos)), member)
^
include/linux/list.h:520:2: note: expanded from macro 'list_entry'
container_of(ptr, type, member)
^
include/linux/container_of.h:18:25: note: expanded from macro 'container_of'
void *__mptr = (void *)(ptr); \
^
kernel/bpf/inode.c:571:2: note: Assuming the condition is false
if (inode_tag(dir)) {
^
include/linux/compiler.h:56:45: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler.h:58:52: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
kernel/bpf/inode.c:571:2: note: '?' condition is false
if (inode_tag(dir)) {
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:31: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
kernel/bpf/inode.c:571:2: note: '?' condition is true
if (inode_tag(dir)) {
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:69: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
include/linux/compiler.h:69:2: note: expanded from macro '__trace_if_value'
(cond) ? \
^
kernel/bpf/inode.c:571:2: note: Taking true branch
if (inode_tag(dir)) {
^
include/linux/compiler.h:56:23: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
kernel/bpf/inode.c:573:3: note: Calling 'untag_dir_inode'
untag_dir_inode(dir);
^~~~~~~~~~~~~~~~~~~~
kernel/bpf/inode.c:561:10: note: Assuming field 'type' is equal to BPF_DIR_KERNFS_REP
WARN_ON(tag->type != BPF_DIR_KERNFS_REP);
^
include/asm-generic/bug.h:121:25: note: expanded from macro 'WARN_ON'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
kernel/bpf/inode.c:561:2: note: '?' condition is false
WARN_ON(tag->type != BPF_DIR_KERNFS_REP);
^
include/asm-generic/bug.h:122:2: note: expanded from macro 'WARN_ON'
if (unlikely(__ret_warn_on)) \
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:31: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
kernel/bpf/inode.c:561:2: note: '?' condition is false
WARN_ON(tag->type != BPF_DIR_KERNFS_REP);
^
include/asm-generic/bug.h:122:2: note: expanded from macro 'WARN_ON'
if (unlikely(__ret_warn_on)) \
^
include/linux/compiler.h:56:28: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
include/linux/compiler.h:58:69: note: expanded from macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^
include/linux/compiler.h:69:2: note: expanded from macro '__trace_if_value'
(cond) ? \
^
kernel/bpf/inode.c:561:2: note: Taking false branch
WARN_ON(tag->type != BPF_DIR_KERNFS_REP);
^
include/asm-generic/bug.h:122:2: note: expanded from macro 'WARN_ON'
if (unlikely(__ret_warn_on)) \
^
include/linux/compiler.h:56:23: note: expanded from macro 'if'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^
kernel/bpf/inode.c:565:2: note: Calling 'kref_put'
kref_put(&tag->inherit_objects->refcnt, free_obj_list);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kref.h:64:2: note: Assuming the condition is false
if (refcount_dec_and_test(&kref->refcount)) {
vim +71 kernel/bpf/inode.c
b2197755b2633e Daniel Borkmann 2015-10-29 64
f6c6ca7ed74437 Hao Luo 2022-02-01 65 static void free_obj_list(struct kref *kref)
f6c6ca7ed74437 Hao Luo 2022-02-01 66 {
f6c6ca7ed74437 Hao Luo 2022-02-01 67 struct obj_list *list;
f6c6ca7ed74437 Hao Luo 2022-02-01 68 struct bpf_inherit_entry *e;
f6c6ca7ed74437 Hao Luo 2022-02-01 69
f6c6ca7ed74437 Hao Luo 2022-02-01 70 list = container_of(kref, struct obj_list, refcnt);
f6c6ca7ed74437 Hao Luo 2022-02-01 @71 list_for_each_entry(e, &list->list, list) {
f6c6ca7ed74437 Hao Luo 2022-02-01 72 list_del_rcu(&e->list);
f6c6ca7ed74437 Hao Luo 2022-02-01 73 bpf_any_put(e->obj, e->type);
f6c6ca7ed74437 Hao Luo 2022-02-01 74 kfree(e);
f6c6ca7ed74437 Hao Luo 2022-02-01 75 }
f6c6ca7ed74437 Hao Luo 2022-02-01 76 kfree(list);
f6c6ca7ed74437 Hao Luo 2022-02-01 77 }
f6c6ca7ed74437 Hao Luo 2022-02-01 78
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag.
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag Hao Luo
@ 2022-02-02 9:32 ` Dan Carpenter
-1 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2022-02-02 9:15 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 15071 bytes --]
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20220201205534.1962784-3-haoluo@google.com>
References: <20220201205534.1962784-3-haoluo@google.com>
TO: Hao Luo <haoluo@google.com>
Hi Hao,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Hao-Luo/Extend-cgroup-interface-with-bpf/20220202-045743
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
:::::: branch date: 12 hours ago
:::::: commit date: 12 hours ago
config: i386-randconfig-m021-20220131 (https://download.01.org/0day-ci/archive/20220202/202202021722.Gftmgh6J-lkp(a)intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
kernel/bpf/inode.c:71 free_obj_list() error: dereferencing freed memory 'e'
kernel/bpf/inode.c:251 populate_dir() error: uninitialized symbol 'ret'.
vim +/e +71 kernel/bpf/inode.c
b2197755b2633e Daniel Borkmann 2015-10-29 64
f6c6ca7ed74437 Hao Luo 2022-02-01 65 static void free_obj_list(struct kref *kref)
f6c6ca7ed74437 Hao Luo 2022-02-01 66 {
f6c6ca7ed74437 Hao Luo 2022-02-01 67 struct obj_list *list;
f6c6ca7ed74437 Hao Luo 2022-02-01 68 struct bpf_inherit_entry *e;
f6c6ca7ed74437 Hao Luo 2022-02-01 69
f6c6ca7ed74437 Hao Luo 2022-02-01 70 list = container_of(kref, struct obj_list, refcnt);
f6c6ca7ed74437 Hao Luo 2022-02-01 @71 list_for_each_entry(e, &list->list, list) {
f6c6ca7ed74437 Hao Luo 2022-02-01 72 list_del_rcu(&e->list);
f6c6ca7ed74437 Hao Luo 2022-02-01 73 bpf_any_put(e->obj, e->type);
f6c6ca7ed74437 Hao Luo 2022-02-01 74 kfree(e);
f6c6ca7ed74437 Hao Luo 2022-02-01 75 }
f6c6ca7ed74437 Hao Luo 2022-02-01 76 kfree(list);
f6c6ca7ed74437 Hao Luo 2022-02-01 77 }
f6c6ca7ed74437 Hao Luo 2022-02-01 78
b2197755b2633e Daniel Borkmann 2015-10-29 79 static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type)
b2197755b2633e Daniel Borkmann 2015-10-29 80 {
b2197755b2633e Daniel Borkmann 2015-10-29 81 void *raw;
b2197755b2633e Daniel Borkmann 2015-10-29 82
c9da161c6517ba Daniel Borkmann 2015-11-24 83 raw = bpf_map_get_with_uref(ufd);
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 84 if (!IS_ERR(raw)) {
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 85 *type = BPF_TYPE_MAP;
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 86 return raw;
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 87 }
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 88
b2197755b2633e Daniel Borkmann 2015-10-29 89 raw = bpf_prog_get(ufd);
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 90 if (!IS_ERR(raw)) {
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 91 *type = BPF_TYPE_PROG;
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 92 return raw;
b2197755b2633e Daniel Borkmann 2015-10-29 93 }
b2197755b2633e Daniel Borkmann 2015-10-29 94
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 95 raw = bpf_link_get_from_fd(ufd);
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 96 if (!IS_ERR(raw)) {
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 97 *type = BPF_TYPE_LINK;
b2197755b2633e Daniel Borkmann 2015-10-29 98 return raw;
b2197755b2633e Daniel Borkmann 2015-10-29 99 }
b2197755b2633e Daniel Borkmann 2015-10-29 100
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 101 return ERR_PTR(-EINVAL);
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 102 }
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 103
b2197755b2633e Daniel Borkmann 2015-10-29 104 static const struct inode_operations bpf_dir_iops;
b2197755b2633e Daniel Borkmann 2015-10-29 105
b2197755b2633e Daniel Borkmann 2015-10-29 106 static const struct inode_operations bpf_prog_iops = { };
b2197755b2633e Daniel Borkmann 2015-10-29 107 static const struct inode_operations bpf_map_iops = { };
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 108 static const struct inode_operations bpf_link_iops = { };
b2197755b2633e Daniel Borkmann 2015-10-29 109
f6c6ca7ed74437 Hao Luo 2022-02-01 110 static int bpf_mkprog(struct dentry *dentry, umode_t mode, void *arg);
f6c6ca7ed74437 Hao Luo 2022-02-01 111 static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg);
f6c6ca7ed74437 Hao Luo 2022-02-01 112 static int bpf_mklink(struct dentry *dentry, umode_t mode, void *arg);
f6c6ca7ed74437 Hao Luo 2022-02-01 113
b2197755b2633e Daniel Borkmann 2015-10-29 114 static struct inode *bpf_get_inode(struct super_block *sb,
b2197755b2633e Daniel Borkmann 2015-10-29 115 const struct inode *dir,
b2197755b2633e Daniel Borkmann 2015-10-29 116 umode_t mode)
b2197755b2633e Daniel Borkmann 2015-10-29 117 {
b2197755b2633e Daniel Borkmann 2015-10-29 118 struct inode *inode;
b2197755b2633e Daniel Borkmann 2015-10-29 119
b2197755b2633e Daniel Borkmann 2015-10-29 120 switch (mode & S_IFMT) {
b2197755b2633e Daniel Borkmann 2015-10-29 121 case S_IFDIR:
b2197755b2633e Daniel Borkmann 2015-10-29 122 case S_IFREG:
0f98621bef5d2b Daniel Borkmann 2016-10-29 123 case S_IFLNK:
b2197755b2633e Daniel Borkmann 2015-10-29 124 break;
b2197755b2633e Daniel Borkmann 2015-10-29 125 default:
b2197755b2633e Daniel Borkmann 2015-10-29 126 return ERR_PTR(-EINVAL);
b2197755b2633e Daniel Borkmann 2015-10-29 127 }
b2197755b2633e Daniel Borkmann 2015-10-29 128
b2197755b2633e Daniel Borkmann 2015-10-29 129 inode = new_inode(sb);
b2197755b2633e Daniel Borkmann 2015-10-29 130 if (!inode)
b2197755b2633e Daniel Borkmann 2015-10-29 131 return ERR_PTR(-ENOSPC);
b2197755b2633e Daniel Borkmann 2015-10-29 132
b2197755b2633e Daniel Borkmann 2015-10-29 133 inode->i_ino = get_next_ino();
078cd8279e6599 Deepa Dinamani 2016-09-14 134 inode->i_atime = current_time(inode);
b2197755b2633e Daniel Borkmann 2015-10-29 135 inode->i_mtime = inode->i_atime;
b2197755b2633e Daniel Borkmann 2015-10-29 136 inode->i_ctime = inode->i_atime;
b2197755b2633e Daniel Borkmann 2015-10-29 137
21cb47be6fb9ec Christian Brauner 2021-01-21 138 inode_init_owner(&init_user_ns, inode, dir, mode);
b2197755b2633e Daniel Borkmann 2015-10-29 139
b2197755b2633e Daniel Borkmann 2015-10-29 140 return inode;
b2197755b2633e Daniel Borkmann 2015-10-29 141 }
b2197755b2633e Daniel Borkmann 2015-10-29 142
b2197755b2633e Daniel Borkmann 2015-10-29 143 static int bpf_inode_type(const struct inode *inode, enum bpf_type *type)
b2197755b2633e Daniel Borkmann 2015-10-29 144 {
b2197755b2633e Daniel Borkmann 2015-10-29 145 *type = BPF_TYPE_UNSPEC;
b2197755b2633e Daniel Borkmann 2015-10-29 146 if (inode->i_op == &bpf_prog_iops)
b2197755b2633e Daniel Borkmann 2015-10-29 147 *type = BPF_TYPE_PROG;
b2197755b2633e Daniel Borkmann 2015-10-29 148 else if (inode->i_op == &bpf_map_iops)
b2197755b2633e Daniel Borkmann 2015-10-29 149 *type = BPF_TYPE_MAP;
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 150 else if (inode->i_op == &bpf_link_iops)
70ed506c3bbcfa Andrii Nakryiko 2020-03-02 151 *type = BPF_TYPE_LINK;
b2197755b2633e Daniel Borkmann 2015-10-29 152 else
b2197755b2633e Daniel Borkmann 2015-10-29 153 return -EACCES;
b2197755b2633e Daniel Borkmann 2015-10-29 154
b2197755b2633e Daniel Borkmann 2015-10-29 155 return 0;
b2197755b2633e Daniel Borkmann 2015-10-29 156 }
b2197755b2633e Daniel Borkmann 2015-10-29 157
3a2ad553a70d36 Hao Luo 2022-02-01 158 static struct bpf_dir_tag *inode_tag(const struct inode *inode)
3a2ad553a70d36 Hao Luo 2022-02-01 159 {
3a2ad553a70d36 Hao Luo 2022-02-01 160 if (unlikely(!S_ISDIR(inode->i_mode)))
3a2ad553a70d36 Hao Luo 2022-02-01 161 return NULL;
3a2ad553a70d36 Hao Luo 2022-02-01 162
3a2ad553a70d36 Hao Luo 2022-02-01 163 return inode->i_private;
3a2ad553a70d36 Hao Luo 2022-02-01 164 }
3a2ad553a70d36 Hao Luo 2022-02-01 165
3a2ad553a70d36 Hao Luo 2022-02-01 166 /* tag_dir_inode - tag a newly created directory.
3a2ad553a70d36 Hao Luo 2022-02-01 167 * @tag: tag of parent directory
3a2ad553a70d36 Hao Luo 2022-02-01 168 * @dentry: dentry of the new directory
3a2ad553a70d36 Hao Luo 2022-02-01 169 * @inode: inode of the new directory
3a2ad553a70d36 Hao Luo 2022-02-01 170 *
3a2ad553a70d36 Hao Luo 2022-02-01 171 * Called from bpf_mkdir.
3a2ad553a70d36 Hao Luo 2022-02-01 172 */
3a2ad553a70d36 Hao Luo 2022-02-01 173 static int tag_dir_inode(const struct bpf_dir_tag *tag,
3a2ad553a70d36 Hao Luo 2022-02-01 174 const struct dentry *dentry, struct inode *inode)
3a2ad553a70d36 Hao Luo 2022-02-01 175 {
3a2ad553a70d36 Hao Luo 2022-02-01 176 struct bpf_dir_tag *t;
3a2ad553a70d36 Hao Luo 2022-02-01 177 struct kernfs_node *kn;
3a2ad553a70d36 Hao Luo 2022-02-01 178
3a2ad553a70d36 Hao Luo 2022-02-01 179 WARN_ON(tag->type != BPF_DIR_KERNFS_REP);
3a2ad553a70d36 Hao Luo 2022-02-01 180
3a2ad553a70d36 Hao Luo 2022-02-01 181 /* kn is put at tag deallocation. */
3a2ad553a70d36 Hao Luo 2022-02-01 182 kn = kernfs_find_and_get_ns(tag->private, dentry->d_name.name, NULL);
3a2ad553a70d36 Hao Luo 2022-02-01 183 if (unlikely(!kn))
3a2ad553a70d36 Hao Luo 2022-02-01 184 return -ENOENT;
3a2ad553a70d36 Hao Luo 2022-02-01 185
3a2ad553a70d36 Hao Luo 2022-02-01 186 if (unlikely(kernfs_type(kn) != KERNFS_DIR)) {
3a2ad553a70d36 Hao Luo 2022-02-01 187 kernfs_put(kn);
3a2ad553a70d36 Hao Luo 2022-02-01 188 return -EPERM;
3a2ad553a70d36 Hao Luo 2022-02-01 189 }
3a2ad553a70d36 Hao Luo 2022-02-01 190
3a2ad553a70d36 Hao Luo 2022-02-01 191 t = kzalloc(sizeof(struct bpf_dir_tag), GFP_KERNEL | __GFP_NOWARN);
3a2ad553a70d36 Hao Luo 2022-02-01 192 if (unlikely(!t)) {
3a2ad553a70d36 Hao Luo 2022-02-01 193 kernfs_put(kn);
3a2ad553a70d36 Hao Luo 2022-02-01 194 return -ENOMEM;
3a2ad553a70d36 Hao Luo 2022-02-01 195 }
3a2ad553a70d36 Hao Luo 2022-02-01 196
3a2ad553a70d36 Hao Luo 2022-02-01 197 t->type = tag->type;
f6c6ca7ed74437 Hao Luo 2022-02-01 198 t->inherit_objects = tag->inherit_objects;
f6c6ca7ed74437 Hao Luo 2022-02-01 199 kref_get(&t->inherit_objects->refcnt);
3a2ad553a70d36 Hao Luo 2022-02-01 200 t->private = kn;
3a2ad553a70d36 Hao Luo 2022-02-01 201
3a2ad553a70d36 Hao Luo 2022-02-01 202 inode->i_private = t;
3a2ad553a70d36 Hao Luo 2022-02-01 203 return 0;
3a2ad553a70d36 Hao Luo 2022-02-01 204 }
3a2ad553a70d36 Hao Luo 2022-02-01 205
f6c6ca7ed74437 Hao Luo 2022-02-01 206 /* populate_dir - populate directory with bpf objects in a tag's
f6c6ca7ed74437 Hao Luo 2022-02-01 207 * inherit_objects.
f6c6ca7ed74437 Hao Luo 2022-02-01 208 * @dir: dentry of the directory.
f6c6ca7ed74437 Hao Luo 2022-02-01 209 * @inode: inode of the direcotry.
f6c6ca7ed74437 Hao Luo 2022-02-01 210 *
f6c6ca7ed74437 Hao Luo 2022-02-01 211 * Called from mkdir. Must be called after dentry has been finalized.
f6c6ca7ed74437 Hao Luo 2022-02-01 212 */
f6c6ca7ed74437 Hao Luo 2022-02-01 213 static int populate_dir(struct dentry *dir, struct inode *inode)
f6c6ca7ed74437 Hao Luo 2022-02-01 214 {
f6c6ca7ed74437 Hao Luo 2022-02-01 215 struct bpf_dir_tag *tag = inode_tag(inode);
f6c6ca7ed74437 Hao Luo 2022-02-01 216 struct bpf_inherit_entry *e;
f6c6ca7ed74437 Hao Luo 2022-02-01 217 struct dentry *child;
f6c6ca7ed74437 Hao Luo 2022-02-01 218 int ret;
f6c6ca7ed74437 Hao Luo 2022-02-01 219
f6c6ca7ed74437 Hao Luo 2022-02-01 220 rcu_read_lock();
f6c6ca7ed74437 Hao Luo 2022-02-01 221 list_for_each_entry_rcu(e, &tag->inherit_objects->list, list) {
f6c6ca7ed74437 Hao Luo 2022-02-01 222 child = lookup_one_len_unlocked(e->name.name, dir,
f6c6ca7ed74437 Hao Luo 2022-02-01 223 strlen(e->name.name));
f6c6ca7ed74437 Hao Luo 2022-02-01 224 if (unlikely(IS_ERR(child))) {
f6c6ca7ed74437 Hao Luo 2022-02-01 225 ret = PTR_ERR(child);
f6c6ca7ed74437 Hao Luo 2022-02-01 226 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 227 }
f6c6ca7ed74437 Hao Luo 2022-02-01 228
f6c6ca7ed74437 Hao Luo 2022-02-01 229 switch (e->type) {
f6c6ca7ed74437 Hao Luo 2022-02-01 230 case BPF_TYPE_PROG:
f6c6ca7ed74437 Hao Luo 2022-02-01 231 ret = bpf_mkprog(child, e->mode, e->obj);
f6c6ca7ed74437 Hao Luo 2022-02-01 232 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 233 case BPF_TYPE_MAP:
f6c6ca7ed74437 Hao Luo 2022-02-01 234 ret = bpf_mkmap(child, e->mode, e->obj);
f6c6ca7ed74437 Hao Luo 2022-02-01 235 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 236 case BPF_TYPE_LINK:
f6c6ca7ed74437 Hao Luo 2022-02-01 237 ret = bpf_mklink(child, e->mode, e->obj);
f6c6ca7ed74437 Hao Luo 2022-02-01 238 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 239 default:
f6c6ca7ed74437 Hao Luo 2022-02-01 240 ret = -EPERM;
f6c6ca7ed74437 Hao Luo 2022-02-01 241 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 242 }
f6c6ca7ed74437 Hao Luo 2022-02-01 243 dput(child);
f6c6ca7ed74437 Hao Luo 2022-02-01 244 if (ret)
f6c6ca7ed74437 Hao Luo 2022-02-01 245 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 246
f6c6ca7ed74437 Hao Luo 2022-02-01 247 /* To match bpf_any_put in bpf_free_inode. */
f6c6ca7ed74437 Hao Luo 2022-02-01 248 bpf_any_get(e->obj, e->type);
f6c6ca7ed74437 Hao Luo 2022-02-01 249 }
f6c6ca7ed74437 Hao Luo 2022-02-01 250 rcu_read_unlock();
f6c6ca7ed74437 Hao Luo 2022-02-01 @251 return ret;
f6c6ca7ed74437 Hao Luo 2022-02-01 252 }
f6c6ca7ed74437 Hao Luo 2022-02-01 253
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag.
@ 2022-02-02 9:32 ` Dan Carpenter
0 siblings, 0 replies; 4+ messages in thread
From: Dan Carpenter @ 2022-02-02 9:32 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 4885 bytes --]
Hi Hao,
url: https://github.com/0day-ci/linux/commits/Hao-Luo/Extend-cgroup-interface-with-bpf/20220202-045743
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: i386-randconfig-m021-20220131 (https://download.01.org/0day-ci/archive/20220202/202202021722.Gftmgh6J-lkp(a)intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
kernel/bpf/inode.c:71 free_obj_list() error: dereferencing freed memory 'e'
kernel/bpf/inode.c:251 populate_dir() error: uninitialized symbol 'ret'.
vim +/e +71 kernel/bpf/inode.c
f6c6ca7ed74437 Hao Luo 2022-02-01 65 static void free_obj_list(struct kref *kref)
f6c6ca7ed74437 Hao Luo 2022-02-01 66 {
f6c6ca7ed74437 Hao Luo 2022-02-01 67 struct obj_list *list;
f6c6ca7ed74437 Hao Luo 2022-02-01 68 struct bpf_inherit_entry *e;
f6c6ca7ed74437 Hao Luo 2022-02-01 69
f6c6ca7ed74437 Hao Luo 2022-02-01 70 list = container_of(kref, struct obj_list, refcnt);
f6c6ca7ed74437 Hao Luo 2022-02-01 @71 list_for_each_entry(e, &list->list, list) {
Need to use list_for_each_entry_safe() because this frees the list
iterator.
f6c6ca7ed74437 Hao Luo 2022-02-01 72 list_del_rcu(&e->list);
f6c6ca7ed74437 Hao Luo 2022-02-01 73 bpf_any_put(e->obj, e->type);
f6c6ca7ed74437 Hao Luo 2022-02-01 74 kfree(e);
f6c6ca7ed74437 Hao Luo 2022-02-01 75 }
f6c6ca7ed74437 Hao Luo 2022-02-01 76 kfree(list);
f6c6ca7ed74437 Hao Luo 2022-02-01 77 }
[ snip ]
f6c6ca7ed74437 Hao Luo 2022-02-01 213 static int populate_dir(struct dentry *dir, struct inode *inode)
f6c6ca7ed74437 Hao Luo 2022-02-01 214 {
f6c6ca7ed74437 Hao Luo 2022-02-01 215 struct bpf_dir_tag *tag = inode_tag(inode);
f6c6ca7ed74437 Hao Luo 2022-02-01 216 struct bpf_inherit_entry *e;
f6c6ca7ed74437 Hao Luo 2022-02-01 217 struct dentry *child;
f6c6ca7ed74437 Hao Luo 2022-02-01 218 int ret;
f6c6ca7ed74437 Hao Luo 2022-02-01 219
f6c6ca7ed74437 Hao Luo 2022-02-01 220 rcu_read_lock();
f6c6ca7ed74437 Hao Luo 2022-02-01 221 list_for_each_entry_rcu(e, &tag->inherit_objects->list, list) {
f6c6ca7ed74437 Hao Luo 2022-02-01 222 child = lookup_one_len_unlocked(e->name.name, dir,
f6c6ca7ed74437 Hao Luo 2022-02-01 223 strlen(e->name.name));
f6c6ca7ed74437 Hao Luo 2022-02-01 224 if (unlikely(IS_ERR(child))) {
f6c6ca7ed74437 Hao Luo 2022-02-01 225 ret = PTR_ERR(child);
f6c6ca7ed74437 Hao Luo 2022-02-01 226 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 227 }
f6c6ca7ed74437 Hao Luo 2022-02-01 228
f6c6ca7ed74437 Hao Luo 2022-02-01 229 switch (e->type) {
f6c6ca7ed74437 Hao Luo 2022-02-01 230 case BPF_TYPE_PROG:
f6c6ca7ed74437 Hao Luo 2022-02-01 231 ret = bpf_mkprog(child, e->mode, e->obj);
f6c6ca7ed74437 Hao Luo 2022-02-01 232 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 233 case BPF_TYPE_MAP:
f6c6ca7ed74437 Hao Luo 2022-02-01 234 ret = bpf_mkmap(child, e->mode, e->obj);
f6c6ca7ed74437 Hao Luo 2022-02-01 235 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 236 case BPF_TYPE_LINK:
f6c6ca7ed74437 Hao Luo 2022-02-01 237 ret = bpf_mklink(child, e->mode, e->obj);
f6c6ca7ed74437 Hao Luo 2022-02-01 238 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 239 default:
f6c6ca7ed74437 Hao Luo 2022-02-01 240 ret = -EPERM;
f6c6ca7ed74437 Hao Luo 2022-02-01 241 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 242 }
f6c6ca7ed74437 Hao Luo 2022-02-01 243 dput(child);
f6c6ca7ed74437 Hao Luo 2022-02-01 244 if (ret)
f6c6ca7ed74437 Hao Luo 2022-02-01 245 break;
f6c6ca7ed74437 Hao Luo 2022-02-01 246
f6c6ca7ed74437 Hao Luo 2022-02-01 247 /* To match bpf_any_put in bpf_free_inode. */
f6c6ca7ed74437 Hao Luo 2022-02-01 248 bpf_any_get(e->obj, e->type);
f6c6ca7ed74437 Hao Luo 2022-02-01 249 }
f6c6ca7ed74437 Hao Luo 2022-02-01 250 rcu_read_unlock();
f6c6ca7ed74437 Hao Luo 2022-02-01 @251 return ret;
This warning is just about empty loops. Likely impossible.
f6c6ca7ed74437 Hao Luo 2022-02-01 252 }
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH RFC bpf-next v2 0/5] Extend cgroup interface with bpf
@ 2022-02-01 20:55 Hao Luo
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag Hao Luo
0 siblings, 1 reply; 4+ messages in thread
From: Hao Luo @ 2022-02-01 20:55 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann
Cc: Martin KaFai Lau, Song Liu, Yonghong Song, KP Singh, Shakeel Butt,
Joe Burton, Stanislav Fomichev, bpf, linux-kernel, Hao Luo
This patchset introduces a new program type to extend the cgroup interfaces.
It extends the bpf filesystem (bpffs) to allow creating a directory
hierarchy that tracks any kernfs hierarchy, in particular cgroupfs. Each
subdirectory in this hierarchy will keep a reference to a corresponding
kernfs node when created. This is done by associating a new data
structure (called "tag" in this patchset) to the bpffs directory inodes.
File inode in bpffs holds a reference to bpf object and directory inode
may point to a tag, which holds a kernfs node.
A bpf object can be pinned in these directories and objects can choose to
enable inheritance in tagged directories. In this patchset, a new
program type "cgroup_view" is introduced, which supports inheritance.
More specifically, when a link to cgroup_view prog is pinned in a bpffs
directory, it tags the directory and connects the directory to the root
cgroup. Subdirectories created underneath has to match a subcgroup, and
when created, they will inherit the pinned cgroup_view link from the
parent directory.
The pinned cgroup_view objects can be read as files. When the object is
read, it tries to get the cgroup its parent directory is matched to.
Failure to get the cgroup's reference will not run the cgroup_view prog.
Users can implement cgroup_view program to define what to print out to
the file, given the cgroup object.
See patch 5/5 for an example of how this works.
Userspace has to manually create/remove directories in bpffs to mirror
the cgroup hierarchy. It was suggested using overlayfs to create a
hierarchy that contains both cgroupfs and bpffs. But after some
experiments, I found overlayfs is not intended to be used this way:
overlayfs assumes the underlying filesystem will not change [1], but our
underlaying fs (i.e. cgroupfs) will change and cause weird behavior. So
I didn't pursue in that direction.
This patchset v2 is only for demonstrating the high level design. There
are a lot of places in its implementation that can be improved. Cgroup_view
is a type of bpf_iter, because seqfile printing has been supported well
in bpf_iter, although cgroup_view is not iterating kernel objects.
Changes v1->v2:
- Complete redesign. v1 implements pinning bpf objects in cgroupfs[2].
v2 implements object inheritance in bpffs. Due to its simplicity,
bpffs is better for implementing inheritance compared to cgroupfs.
- Extend selftest to include a more realistic use case. The selftests
in v2 developed a cgroup-level sched performance metric and exported
through the new prog type.
[1] https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#changes-to-underlying-filesystems
[2] https://lore.kernel.org/bpf/Ydd1IIUG7%2F3kQRcR@google.com/
Hao Luo (5):
bpf: Bpffs directory tag
bpf: Introduce inherit list for dir tag.
bpf: cgroup_view iter
bpf: Pin cgroup_view
selftests/bpf: test for pinning for cgroup_view link
include/linux/bpf.h | 2 +
kernel/bpf/Makefile | 2 +-
kernel/bpf/bpf_iter.c | 11 +
kernel/bpf/cgroup_view_iter.c | 114 ++++++++
kernel/bpf/inode.c | 272 +++++++++++++++++-
kernel/bpf/inode.h | 55 ++++
.../selftests/bpf/prog_tests/pinning_cgroup.c | 143 +++++++++
tools/testing/selftests/bpf/progs/bpf_iter.h | 7 +
.../bpf/progs/bpf_iter_cgroup_view.c | 232 +++++++++++++++
9 files changed, 829 insertions(+), 9 deletions(-)
create mode 100644 kernel/bpf/cgroup_view_iter.c
create mode 100644 kernel/bpf/inode.h
create mode 100644 tools/testing/selftests/bpf/prog_tests/pinning_cgroup.c
create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_cgroup_view.c
--
2.35.0.rc2.247.g8bbb082509-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag.
2022-02-01 20:55 [PATCH RFC bpf-next v2 0/5] Extend cgroup interface with bpf Hao Luo
@ 2022-02-01 20:55 ` Hao Luo
0 siblings, 0 replies; 4+ messages in thread
From: Hao Luo @ 2022-02-01 20:55 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann
Cc: Martin KaFai Lau, Song Liu, Yonghong Song, KP Singh, Shakeel Butt,
Joe Burton, Stanislav Fomichev, bpf, linux-kernel, Hao Luo
Embed a list of bpf objects in a directory's tag. This list is
shared by all the directories in the tagged hierarchy.
When a new tagged directory is created, it will be prepopulated
with the objects in the inherit list. When the directory is
removed, the inherited objects will be removed automatically.
Because the whole tagged hierarchy share the same list, all the
directories in the hierarchy have the same set of objects to be
prepopulated.
Signed-off-by: Hao Luo <haoluo@google.com>
---
kernel/bpf/inode.c | 110 +++++++++++++++++++++++++++++++++++++++++----
kernel/bpf/inode.h | 33 ++++++++++++++
2 files changed, 135 insertions(+), 8 deletions(-)
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index ecc357009df5..9ae17a2bf779 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -24,13 +24,6 @@
#include "preload/bpf_preload.h"
#include "inode.h"
-enum bpf_type {
- BPF_TYPE_UNSPEC = 0,
- BPF_TYPE_PROG,
- BPF_TYPE_MAP,
- BPF_TYPE_LINK,
-};
-
static void *bpf_any_get(void *raw, enum bpf_type type)
{
switch (type) {
@@ -69,6 +62,20 @@ static void bpf_any_put(void *raw, enum bpf_type type)
}
}
+static void free_obj_list(struct kref *kref)
+{
+ struct obj_list *list;
+ struct bpf_inherit_entry *e;
+
+ list = container_of(kref, struct obj_list, refcnt);
+ list_for_each_entry(e, &list->list, list) {
+ list_del_rcu(&e->list);
+ bpf_any_put(e->obj, e->type);
+ kfree(e);
+ }
+ kfree(list);
+}
+
static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type)
{
void *raw;
@@ -100,6 +107,10 @@ static const struct inode_operations bpf_prog_iops = { };
static const struct inode_operations bpf_map_iops = { };
static const struct inode_operations bpf_link_iops = { };
+static int bpf_mkprog(struct dentry *dentry, umode_t mode, void *arg);
+static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg);
+static int bpf_mklink(struct dentry *dentry, umode_t mode, void *arg);
+
static struct inode *bpf_get_inode(struct super_block *sb,
const struct inode *dir,
umode_t mode)
@@ -184,12 +195,62 @@ static int tag_dir_inode(const struct bpf_dir_tag *tag,
}
t->type = tag->type;
+ t->inherit_objects = tag->inherit_objects;
+ kref_get(&t->inherit_objects->refcnt);
t->private = kn;
inode->i_private = t;
return 0;
}
+/* populate_dir - populate directory with bpf objects in a tag's
+ * inherit_objects.
+ * @dir: dentry of the directory.
+ * @inode: inode of the direcotry.
+ *
+ * Called from mkdir. Must be called after dentry has been finalized.
+ */
+static int populate_dir(struct dentry *dir, struct inode *inode)
+{
+ struct bpf_dir_tag *tag = inode_tag(inode);
+ struct bpf_inherit_entry *e;
+ struct dentry *child;
+ int ret;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(e, &tag->inherit_objects->list, list) {
+ child = lookup_one_len_unlocked(e->name.name, dir,
+ strlen(e->name.name));
+ if (unlikely(IS_ERR(child))) {
+ ret = PTR_ERR(child);
+ break;
+ }
+
+ switch (e->type) {
+ case BPF_TYPE_PROG:
+ ret = bpf_mkprog(child, e->mode, e->obj);
+ break;
+ case BPF_TYPE_MAP:
+ ret = bpf_mkmap(child, e->mode, e->obj);
+ break;
+ case BPF_TYPE_LINK:
+ ret = bpf_mklink(child, e->mode, e->obj);
+ break;
+ default:
+ ret = -EPERM;
+ break;
+ }
+ dput(child);
+ if (ret)
+ break;
+
+ /* To match bpf_any_put in bpf_free_inode. */
+ bpf_any_get(e->obj, e->type);
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
static void bpf_dentry_finalize(struct dentry *dentry, struct inode *inode,
struct inode *dir)
{
@@ -227,6 +288,12 @@ static int bpf_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
inc_nlink(dir);
bpf_dentry_finalize(dentry, inode, dir);
+
+ if (tag) {
+ err = populate_dir(dentry, inode);
+ if (err)
+ return err;
+ }
return 0;
}
@@ -463,6 +530,30 @@ static int bpf_symlink(struct user_namespace *mnt_userns, struct inode *dir,
return 0;
}
+/* unpopulate_dir - remove pre-populated entries from directory.
+ * @dentry: dentry of directory
+ * @inode: inode of directory
+ *
+ * Called from rmdir.
+ */
+static void unpopulate_dir(struct dentry *dentry, struct inode *inode)
+{
+ struct bpf_dir_tag *tag = inode_tag(inode);
+ struct bpf_inherit_entry *e;
+ struct dentry *child;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(e, &tag->inherit_objects->list, list) {
+ child = d_hash_and_lookup(dentry, &e->name);
+ if (unlikely(IS_ERR(child)))
+ continue;
+
+ simple_unlink(inode, child);
+ dput(child);
+ }
+ rcu_read_unlock();
+}
+
static void untag_dir_inode(struct inode *dir)
{
struct bpf_dir_tag *tag = inode_tag(dir);
@@ -471,13 +562,16 @@ static void untag_dir_inode(struct inode *dir)
dir->i_private = NULL;
kernfs_put(tag->private);
+ kref_put(&tag->inherit_objects->refcnt, free_obj_list);
kfree(tag);
}
static int bpf_rmdir(struct inode *dir, struct dentry *dentry)
{
- if (inode_tag(dir))
+ if (inode_tag(dir)) {
+ unpopulate_dir(dentry, dir);
untag_dir_inode(dir);
+ }
return simple_rmdir(dir, dentry);
}
diff --git a/kernel/bpf/inode.h b/kernel/bpf/inode.h
index 2cfeef39e861..a8207122643d 100644
--- a/kernel/bpf/inode.h
+++ b/kernel/bpf/inode.h
@@ -4,11 +4,42 @@
#ifndef __BPF_INODE_H_
#define __BPF_INODE_H_
+#include <linux/bpf.h>
+#include <linux/fs.h>
+
+enum bpf_type {
+ BPF_TYPE_UNSPEC = 0,
+ BPF_TYPE_PROG,
+ BPF_TYPE_MAP,
+ BPF_TYPE_LINK,
+};
+
enum tag_type {
/* The directory is a replicate of a kernfs directory hierarchy. */
BPF_DIR_KERNFS_REP = 0,
};
+/* Entry for bpf_dir_tag->inherit_objects.
+ *
+ * When a new directory is created from a tagged directory, the new directory
+ * will be populated with bpf objects in the tag's inherit_objects list. Each
+ * entry holds a reference of a bpf object and the information needed to
+ * recreate the object's entry in the new directory.
+ */
+struct bpf_inherit_entry {
+ struct list_head list;
+ void *obj; /* bpf object to inherit. */
+ enum bpf_type type; /* type of the object (prog, map or link). */
+ struct qstr name; /* name of the entry. */
+ umode_t mode; /* access mode of the entry. */
+};
+
+struct obj_list {
+ struct list_head list;
+ struct kref refcnt;
+ struct inode *root;
+};
+
/* A tag for bpffs directories. It carries special information about a
* directory. For example, BPF_DIR_KERNFS_REP denotes that the directory is
* a replicate of a kernfs hierarchy. Pinning a certain type of objects tags
@@ -16,6 +47,8 @@ enum tag_type {
*/
struct bpf_dir_tag {
enum tag_type type;
+ /* list of bpf objects that a directory inherits from its parent. */
+ struct obj_list *inherit_objects;
void *private; /* tag private data */
};
--
2.35.0.rc2.247.g8bbb082509-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-02-02 14:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-02 14:00 [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2022-02-02 9:15 kernel test robot
2022-02-02 9:32 ` Dan Carpenter
2022-02-01 20:55 [PATCH RFC bpf-next v2 0/5] Extend cgroup interface with bpf Hao Luo
2022-02-01 20:55 ` [PATCH RFC bpf-next v2 2/5] bpf: Introduce inherit list for dir tag Hao Luo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.