Commit 4f19cab7 authored by Florent Revest's avatar Florent Revest Committed by Daniel Borkmann

bpf: Add a bpf_sock_from_file helper

While eBPF programs can check whether a file is a socket by file->f_op
== &socket_file_ops, they cannot convert the void private_data pointer
to a struct socket BTF pointer. In order to do this a new helper
wrapping sock_from_file is added.

This is useful to tracing programs but also other program types
inheriting this set of helpers such as iterators or LSM programs.
Signed-off-by: default avatarFlorent Revest <revest@google.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarKP Singh <kpsingh@google.com>
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20201204113609.1850150-2-revest@google.com
parent dba4a925
...@@ -3822,6 +3822,14 @@ union bpf_attr { ...@@ -3822,6 +3822,14 @@ union bpf_attr {
* The **hash_algo** is returned on success, * The **hash_algo** is returned on success,
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if * **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
* invalid arguments are passed. * invalid arguments are passed.
*
* struct socket *bpf_sock_from_file(struct file *file)
* Description
* If the given file represents a socket, returns the associated
* socket.
* Return
* A pointer to a struct socket on success or NULL if the file is
* not a socket.
*/ */
#define __BPF_FUNC_MAPPER(FN) \ #define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \ FN(unspec), \
...@@ -3986,6 +3994,7 @@ union bpf_attr { ...@@ -3986,6 +3994,7 @@ union bpf_attr {
FN(bprm_opts_set), \ FN(bprm_opts_set), \
FN(ktime_get_coarse_ns), \ FN(ktime_get_coarse_ns), \
FN(ima_inode_hash), \ FN(ima_inode_hash), \
FN(sock_from_file), \
/* */ /* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper /* integer value in 'imm' field of BPF_CALL instruction selects which helper
......
...@@ -1270,6 +1270,24 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = { ...@@ -1270,6 +1270,24 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = {
.arg5_type = ARG_ANYTHING, .arg5_type = ARG_ANYTHING,
}; };
BPF_CALL_1(bpf_sock_from_file, struct file *, file)
{
return (unsigned long) sock_from_file(file);
}
BTF_ID_LIST(bpf_sock_from_file_btf_ids)
BTF_ID(struct, socket)
BTF_ID(struct, file)
static const struct bpf_func_proto bpf_sock_from_file_proto = {
.func = bpf_sock_from_file,
.gpl_only = false,
.ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
.ret_btf_id = &bpf_sock_from_file_btf_ids[0],
.arg1_type = ARG_PTR_TO_BTF_ID,
.arg1_btf_id = &bpf_sock_from_file_btf_ids[1],
};
const struct bpf_func_proto * const struct bpf_func_proto *
bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{ {
...@@ -1366,6 +1384,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) ...@@ -1366,6 +1384,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_per_cpu_ptr_proto; return &bpf_per_cpu_ptr_proto;
case BPF_FUNC_bpf_this_cpu_ptr: case BPF_FUNC_bpf_this_cpu_ptr:
return &bpf_this_cpu_ptr_proto; return &bpf_this_cpu_ptr_proto;
case BPF_FUNC_sock_from_file:
return &bpf_sock_from_file_proto;
default: default:
return NULL; return NULL;
} }
......
...@@ -437,6 +437,8 @@ class PrinterHelpers(Printer): ...@@ -437,6 +437,8 @@ class PrinterHelpers(Printer):
'struct path', 'struct path',
'struct btf_ptr', 'struct btf_ptr',
'struct inode', 'struct inode',
'struct socket',
'struct file',
] ]
known_types = { known_types = {
'...', '...',
...@@ -482,6 +484,8 @@ class PrinterHelpers(Printer): ...@@ -482,6 +484,8 @@ class PrinterHelpers(Printer):
'struct path', 'struct path',
'struct btf_ptr', 'struct btf_ptr',
'struct inode', 'struct inode',
'struct socket',
'struct file',
} }
mapped_types = { mapped_types = {
'u8': '__u8', 'u8': '__u8',
......
...@@ -3822,6 +3822,14 @@ union bpf_attr { ...@@ -3822,6 +3822,14 @@ union bpf_attr {
* The **hash_algo** is returned on success, * The **hash_algo** is returned on success,
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if * **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
* invalid arguments are passed. * invalid arguments are passed.
*
* struct socket *bpf_sock_from_file(struct file *file)
* Description
* If the given file represents a socket, returns the associated
* socket.
* Return
* A pointer to a struct socket on success or NULL if the file is
* not a socket.
*/ */
#define __BPF_FUNC_MAPPER(FN) \ #define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \ FN(unspec), \
...@@ -3986,6 +3994,7 @@ union bpf_attr { ...@@ -3986,6 +3994,7 @@ union bpf_attr {
FN(bprm_opts_set), \ FN(bprm_opts_set), \
FN(ktime_get_coarse_ns), \ FN(ktime_get_coarse_ns), \
FN(ima_inode_hash), \ FN(ima_inode_hash), \
FN(sock_from_file), \
/* */ /* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper /* integer value in 'imm' field of BPF_CALL instruction selects which helper
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment