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

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
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -3822,6 +3822,14 @@ union bpf_attr {
 *		The **hash_algo** is returned on success,
 *		**-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
 *		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)		\
	FN(unspec),			\
@@ -3986,6 +3994,7 @@ union bpf_attr {
	FN(bprm_opts_set),		\
	FN(ktime_get_coarse_ns),	\
	FN(ima_inode_hash),		\
	FN(sock_from_file),		\
	/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
+20 −0
Original line number Diff line number Diff line
@@ -1270,6 +1270,24 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = {
	.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 *
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;
	case BPF_FUNC_bpf_this_cpu_ptr:
		return &bpf_this_cpu_ptr_proto;
	case BPF_FUNC_sock_from_file:
		return &bpf_sock_from_file_proto;
	default:
		return NULL;
	}
+4 −0
Original line number Diff line number Diff line
@@ -437,6 +437,8 @@ class PrinterHelpers(Printer):
            'struct path',
            'struct btf_ptr',
            'struct inode',
            'struct socket',
            'struct file',
    ]
    known_types = {
            '...',
@@ -482,6 +484,8 @@ class PrinterHelpers(Printer):
            'struct path',
            'struct btf_ptr',
            'struct inode',
            'struct socket',
            'struct file',
    }
    mapped_types = {
            'u8': '__u8',
+9 −0
Original line number Diff line number Diff line
@@ -3822,6 +3822,14 @@ union bpf_attr {
 *		The **hash_algo** is returned on success,
 *		**-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
 *		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)		\
	FN(unspec),			\
@@ -3986,6 +3994,7 @@ union bpf_attr {
	FN(bprm_opts_set),		\
	FN(ktime_get_coarse_ns),	\
	FN(ima_inode_hash),		\
	FN(sock_from_file),		\
	/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper