mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	bpf: Add bpf_snprintf_btf helper
A helper is added to support tracing kernel type information in BPF
using the BPF Type Format (BTF).  Its signature is
long bpf_snprintf_btf(char *str, u32 str_size, struct btf_ptr *ptr,
		      u32 btf_ptr_size, u64 flags);
struct btf_ptr * specifies
- a pointer to the data to be traced
- the BTF id of the type of data pointed to
- a flags field is provided for future use; these flags
  are not to be confused with the BTF_F_* flags
  below that control how the btf_ptr is displayed; the
  flags member of the struct btf_ptr may be used to
  disambiguate types in kernel versus module BTF, etc;
  the main distinction is the flags relate to the type
  and information needed in identifying it; not how it
  is displayed.
For example a BPF program with a struct sk_buff *skb
could do the following:
	static struct btf_ptr b = { };
	b.ptr = skb;
	b.type_id = __builtin_btf_type_id(struct sk_buff, 1);
	bpf_snprintf_btf(str, sizeof(str), &b, sizeof(b), 0, 0);
Default output looks like this:
(struct sk_buff){
 .transport_header = (__u16)65535,
 .mac_header = (__u16)65535,
 .end = (sk_buff_data_t)192,
 .head = (unsigned char *)0x000000007524fd8b,
 .data = (unsigned char *)0x000000007524fd8b,
 .truesize = (unsigned int)768,
 .users = (refcount_t){
  .refs = (atomic_t){
   .counter = (int)1,
  },
 },
}
Flags modifying display are as follows:
- BTF_F_COMPACT:	no formatting around type information
- BTF_F_NONAME:		no struct/union member names/types
- BTF_F_PTR_RAW:	show raw (unobfuscated) pointer values;
			equivalent to %px.
- BTF_F_ZERO:		show zero-valued struct/union members;
			they are not displayed by default
Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/1601292670-1616-4-git-send-email-alan.maguire@oracle.com
			
			
This commit is contained in:
		
							parent
							
								
									31d0bc8163
								
							
						
					
					
						commit
						c4d0bfb450
					
				
					 8 changed files with 212 additions and 4 deletions
				
			
		| 
						 | 
					@ -1822,6 +1822,7 @@ extern const struct bpf_func_proto bpf_skc_to_tcp_timewait_sock_proto;
 | 
				
			||||||
extern const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto;
 | 
					extern const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto;
 | 
				
			||||||
extern const struct bpf_func_proto bpf_skc_to_udp6_sock_proto;
 | 
					extern const struct bpf_func_proto bpf_skc_to_udp6_sock_proto;
 | 
				
			||||||
extern const struct bpf_func_proto bpf_copy_from_user_proto;
 | 
					extern const struct bpf_func_proto bpf_copy_from_user_proto;
 | 
				
			||||||
 | 
					extern const struct bpf_func_proto bpf_snprintf_btf_proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct bpf_func_proto *bpf_tracing_func_proto(
 | 
					const struct bpf_func_proto *bpf_tracing_func_proto(
 | 
				
			||||||
	enum bpf_func_id func_id, const struct bpf_prog *prog);
 | 
						enum bpf_func_id func_id, const struct bpf_prog *prog);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
#include <uapi/linux/btf.h>
 | 
					#include <uapi/linux/btf.h>
 | 
				
			||||||
 | 
					#include <uapi/linux/bpf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BTF_TYPE_EMIT(type) ((void)(type *)0)
 | 
					#define BTF_TYPE_EMIT(type) ((void)(type *)0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,10 +60,10 @@ const struct btf_type *btf_type_id_size(const struct btf *btf,
 | 
				
			||||||
 *	- BTF_SHOW_UNSAFE: skip use of bpf_probe_read() to safely read
 | 
					 *	- BTF_SHOW_UNSAFE: skip use of bpf_probe_read() to safely read
 | 
				
			||||||
 *	  data before displaying it.
 | 
					 *	  data before displaying it.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define BTF_SHOW_COMPACT	(1ULL << 0)
 | 
					#define BTF_SHOW_COMPACT	BTF_F_COMPACT
 | 
				
			||||||
#define BTF_SHOW_NONAME		(1ULL << 1)
 | 
					#define BTF_SHOW_NONAME		BTF_F_NONAME
 | 
				
			||||||
#define BTF_SHOW_PTR_RAW	(1ULL << 2)
 | 
					#define BTF_SHOW_PTR_RAW	BTF_F_PTR_RAW
 | 
				
			||||||
#define BTF_SHOW_ZERO		(1ULL << 3)
 | 
					#define BTF_SHOW_ZERO		BTF_F_ZERO
 | 
				
			||||||
#define BTF_SHOW_UNSAFE		(1ULL << 4)
 | 
					#define BTF_SHOW_UNSAFE		(1ULL << 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj,
 | 
					void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3594,6 +3594,42 @@ union bpf_attr {
 | 
				
			||||||
 * 		the data in *dst*. This is a wrapper of **copy_from_user**\ ().
 | 
					 * 		the data in *dst*. This is a wrapper of **copy_from_user**\ ().
 | 
				
			||||||
 * 	Return
 | 
					 * 	Return
 | 
				
			||||||
 * 		0 on success, or a negative error in case of failure.
 | 
					 * 		0 on success, or a negative error in case of failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * long bpf_snprintf_btf(char *str, u32 str_size, struct btf_ptr *ptr, u32 btf_ptr_size, u64 flags)
 | 
				
			||||||
 | 
					 *	Description
 | 
				
			||||||
 | 
					 *		Use BTF to store a string representation of *ptr*->ptr in *str*,
 | 
				
			||||||
 | 
					 *		using *ptr*->type_id.  This value should specify the type
 | 
				
			||||||
 | 
					 *		that *ptr*->ptr points to. LLVM __builtin_btf_type_id(type, 1)
 | 
				
			||||||
 | 
					 *		can be used to look up vmlinux BTF type ids. Traversing the
 | 
				
			||||||
 | 
					 *		data structure using BTF, the type information and values are
 | 
				
			||||||
 | 
					 *		stored in the first *str_size* - 1 bytes of *str*.  Safe copy of
 | 
				
			||||||
 | 
					 *		the pointer data is carried out to avoid kernel crashes during
 | 
				
			||||||
 | 
					 *		operation.  Smaller types can use string space on the stack;
 | 
				
			||||||
 | 
					 *		larger programs can use map data to store the string
 | 
				
			||||||
 | 
					 *		representation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		The string can be subsequently shared with userspace via
 | 
				
			||||||
 | 
					 *		bpf_perf_event_output() or ring buffer interfaces.
 | 
				
			||||||
 | 
					 *		bpf_trace_printk() is to be avoided as it places too small
 | 
				
			||||||
 | 
					 *		a limit on string size to be useful.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		*flags* is a combination of
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		**BTF_F_COMPACT**
 | 
				
			||||||
 | 
					 *			no formatting around type information
 | 
				
			||||||
 | 
					 *		**BTF_F_NONAME**
 | 
				
			||||||
 | 
					 *			no struct/union member names/types
 | 
				
			||||||
 | 
					 *		**BTF_F_PTR_RAW**
 | 
				
			||||||
 | 
					 *			show raw (unobfuscated) pointer values;
 | 
				
			||||||
 | 
					 *			equivalent to printk specifier %px.
 | 
				
			||||||
 | 
					 *		**BTF_F_ZERO**
 | 
				
			||||||
 | 
					 *			show zero-valued struct/union members; they
 | 
				
			||||||
 | 
					 *			are not displayed by default
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *	Return
 | 
				
			||||||
 | 
					 *		The number of bytes that were written (or would have been
 | 
				
			||||||
 | 
					 *		written if output had to be truncated due to string size),
 | 
				
			||||||
 | 
					 *		or a negative error in cases of failure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define __BPF_FUNC_MAPPER(FN)		\
 | 
					#define __BPF_FUNC_MAPPER(FN)		\
 | 
				
			||||||
	FN(unspec),			\
 | 
						FN(unspec),			\
 | 
				
			||||||
| 
						 | 
					@ -3745,6 +3781,7 @@ union bpf_attr {
 | 
				
			||||||
	FN(inode_storage_delete),	\
 | 
						FN(inode_storage_delete),	\
 | 
				
			||||||
	FN(d_path),			\
 | 
						FN(d_path),			\
 | 
				
			||||||
	FN(copy_from_user),		\
 | 
						FN(copy_from_user),		\
 | 
				
			||||||
 | 
						FN(snprintf_btf),		\
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
 | 
					/* integer value in 'imm' field of BPF_CALL instruction selects which helper
 | 
				
			||||||
| 
						 | 
					@ -4853,4 +4890,34 @@ struct bpf_sk_lookup {
 | 
				
			||||||
	__u32 local_port;	/* Host byte order */
 | 
						__u32 local_port;	/* Host byte order */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * struct btf_ptr is used for typed pointer representation; the
 | 
				
			||||||
 | 
					 * type id is used to render the pointer data as the appropriate type
 | 
				
			||||||
 | 
					 * via the bpf_snprintf_btf() helper described above.  A flags field -
 | 
				
			||||||
 | 
					 * potentially to specify additional details about the BTF pointer
 | 
				
			||||||
 | 
					 * (rather than its mode of display) - is included for future use.
 | 
				
			||||||
 | 
					 * Display flags - BTF_F_* - are passed to bpf_snprintf_btf separately.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct btf_ptr {
 | 
				
			||||||
 | 
						void *ptr;
 | 
				
			||||||
 | 
						__u32 type_id;
 | 
				
			||||||
 | 
						__u32 flags;		/* BTF ptr flags; unused at present. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Flags to control bpf_snprintf_btf() behaviour.
 | 
				
			||||||
 | 
					 *     - BTF_F_COMPACT: no formatting around type information
 | 
				
			||||||
 | 
					 *     - BTF_F_NONAME: no struct/union member names/types
 | 
				
			||||||
 | 
					 *     - BTF_F_PTR_RAW: show raw (unobfuscated) pointer values;
 | 
				
			||||||
 | 
					 *       equivalent to %px.
 | 
				
			||||||
 | 
					 *     - BTF_F_ZERO: show zero-valued struct/union members; they
 | 
				
			||||||
 | 
					 *       are not displayed by default
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						BTF_F_COMPACT	=	(1ULL << 0),
 | 
				
			||||||
 | 
						BTF_F_NONAME	=	(1ULL << 1),
 | 
				
			||||||
 | 
						BTF_F_PTR_RAW	=	(1ULL << 2),
 | 
				
			||||||
 | 
						BTF_F_ZERO	=	(1ULL << 3),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _UAPI__LINUX_BPF_H__ */
 | 
					#endif /* _UAPI__LINUX_BPF_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2216,6 +2216,7 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
 | 
				
			||||||
const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto __weak;
 | 
					const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto __weak;
 | 
				
			||||||
const struct bpf_func_proto bpf_get_local_storage_proto __weak;
 | 
					const struct bpf_func_proto bpf_get_local_storage_proto __weak;
 | 
				
			||||||
const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak;
 | 
					const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak;
 | 
				
			||||||
 | 
					const struct bpf_func_proto bpf_snprintf_btf_proto __weak;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 | 
					const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -683,6 +683,10 @@ bpf_base_func_proto(enum bpf_func_id func_id)
 | 
				
			||||||
		if (!perfmon_capable())
 | 
							if (!perfmon_capable())
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		return bpf_get_trace_printk_proto();
 | 
							return bpf_get_trace_printk_proto();
 | 
				
			||||||
 | 
						case BPF_FUNC_snprintf_btf:
 | 
				
			||||||
 | 
							if (!perfmon_capable())
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							return &bpf_snprintf_btf_proto;
 | 
				
			||||||
	case BPF_FUNC_jiffies64:
 | 
						case BPF_FUNC_jiffies64:
 | 
				
			||||||
		return &bpf_jiffies64_proto;
 | 
							return &bpf_jiffies64_proto;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/bpf.h>
 | 
					#include <linux/bpf.h>
 | 
				
			||||||
#include <linux/bpf_perf_event.h>
 | 
					#include <linux/bpf_perf_event.h>
 | 
				
			||||||
 | 
					#include <linux/btf.h>
 | 
				
			||||||
#include <linux/filter.h>
 | 
					#include <linux/filter.h>
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
#include <linux/ctype.h>
 | 
					#include <linux/ctype.h>
 | 
				
			||||||
| 
						 | 
					@ -16,6 +17,9 @@
 | 
				
			||||||
#include <linux/error-injection.h>
 | 
					#include <linux/error-injection.h>
 | 
				
			||||||
#include <linux/btf_ids.h>
 | 
					#include <linux/btf_ids.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <uapi/linux/bpf.h>
 | 
				
			||||||
 | 
					#include <uapi/linux/btf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/tlb.h>
 | 
					#include <asm/tlb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "trace_probe.h"
 | 
					#include "trace_probe.h"
 | 
				
			||||||
| 
						 | 
					@ -1147,6 +1151,65 @@ static const struct bpf_func_proto bpf_d_path_proto = {
 | 
				
			||||||
	.allowed	= bpf_d_path_allowed,
 | 
						.allowed	= bpf_d_path_allowed,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BTF_F_ALL	(BTF_F_COMPACT  | BTF_F_NONAME | \
 | 
				
			||||||
 | 
								 BTF_F_PTR_RAW | BTF_F_ZERO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int bpf_btf_printf_prepare(struct btf_ptr *ptr, u32 btf_ptr_size,
 | 
				
			||||||
 | 
									  u64 flags, const struct btf **btf,
 | 
				
			||||||
 | 
									  s32 *btf_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct btf_type *t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (unlikely(flags & ~(BTF_F_ALL)))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (btf_ptr_size != sizeof(struct btf_ptr))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*btf = bpf_get_btf_vmlinux();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_ERR_OR_NULL(*btf))
 | 
				
			||||||
 | 
							return PTR_ERR(*btf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ptr->type_id > 0)
 | 
				
			||||||
 | 
							*btf_id = ptr->type_id;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*btf_id > 0)
 | 
				
			||||||
 | 
							t = btf_type_by_id(*btf, *btf_id);
 | 
				
			||||||
 | 
						if (*btf_id <= 0 || !t)
 | 
				
			||||||
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BPF_CALL_5(bpf_snprintf_btf, char *, str, u32, str_size, struct btf_ptr *, ptr,
 | 
				
			||||||
 | 
						   u32, btf_ptr_size, u64, flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct btf *btf;
 | 
				
			||||||
 | 
						s32 btf_id;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_btf_printf_prepare(ptr, btf_ptr_size, flags, &btf, &btf_id);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return btf_type_snprintf_show(btf, btf_id, ptr->ptr, str, str_size,
 | 
				
			||||||
 | 
									      flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct bpf_func_proto bpf_snprintf_btf_proto = {
 | 
				
			||||||
 | 
						.func		= bpf_snprintf_btf,
 | 
				
			||||||
 | 
						.gpl_only	= false,
 | 
				
			||||||
 | 
						.ret_type	= RET_INTEGER,
 | 
				
			||||||
 | 
						.arg1_type	= ARG_PTR_TO_MEM,
 | 
				
			||||||
 | 
						.arg2_type	= ARG_CONST_SIZE,
 | 
				
			||||||
 | 
						.arg3_type	= ARG_PTR_TO_MEM,
 | 
				
			||||||
 | 
						.arg4_type	= ARG_CONST_SIZE,
 | 
				
			||||||
 | 
						.arg5_type	= ARG_ANYTHING,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1233,6 +1296,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 | 
				
			||||||
		return &bpf_get_task_stack_proto;
 | 
							return &bpf_get_task_stack_proto;
 | 
				
			||||||
	case BPF_FUNC_copy_from_user:
 | 
						case BPF_FUNC_copy_from_user:
 | 
				
			||||||
		return prog->aux->sleepable ? &bpf_copy_from_user_proto : NULL;
 | 
							return prog->aux->sleepable ? &bpf_copy_from_user_proto : NULL;
 | 
				
			||||||
 | 
						case BPF_FUNC_snprintf_btf:
 | 
				
			||||||
 | 
							return &bpf_snprintf_btf_proto;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -433,6 +433,7 @@ class PrinterHelpers(Printer):
 | 
				
			||||||
            'struct sk_msg_md',
 | 
					            'struct sk_msg_md',
 | 
				
			||||||
            'struct xdp_md',
 | 
					            'struct xdp_md',
 | 
				
			||||||
            'struct path',
 | 
					            'struct path',
 | 
				
			||||||
 | 
					            'struct btf_ptr',
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    known_types = {
 | 
					    known_types = {
 | 
				
			||||||
            '...',
 | 
					            '...',
 | 
				
			||||||
| 
						 | 
					@ -474,6 +475,7 @@ class PrinterHelpers(Printer):
 | 
				
			||||||
            'struct udp6_sock',
 | 
					            'struct udp6_sock',
 | 
				
			||||||
            'struct task_struct',
 | 
					            'struct task_struct',
 | 
				
			||||||
            'struct path',
 | 
					            'struct path',
 | 
				
			||||||
 | 
					            'struct btf_ptr',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mapped_types = {
 | 
					    mapped_types = {
 | 
				
			||||||
            'u8': '__u8',
 | 
					            'u8': '__u8',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3594,6 +3594,42 @@ union bpf_attr {
 | 
				
			||||||
 * 		the data in *dst*. This is a wrapper of **copy_from_user**\ ().
 | 
					 * 		the data in *dst*. This is a wrapper of **copy_from_user**\ ().
 | 
				
			||||||
 * 	Return
 | 
					 * 	Return
 | 
				
			||||||
 * 		0 on success, or a negative error in case of failure.
 | 
					 * 		0 on success, or a negative error in case of failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * long bpf_snprintf_btf(char *str, u32 str_size, struct btf_ptr *ptr, u32 btf_ptr_size, u64 flags)
 | 
				
			||||||
 | 
					 *	Description
 | 
				
			||||||
 | 
					 *		Use BTF to store a string representation of *ptr*->ptr in *str*,
 | 
				
			||||||
 | 
					 *		using *ptr*->type_id.  This value should specify the type
 | 
				
			||||||
 | 
					 *		that *ptr*->ptr points to. LLVM __builtin_btf_type_id(type, 1)
 | 
				
			||||||
 | 
					 *		can be used to look up vmlinux BTF type ids. Traversing the
 | 
				
			||||||
 | 
					 *		data structure using BTF, the type information and values are
 | 
				
			||||||
 | 
					 *		stored in the first *str_size* - 1 bytes of *str*.  Safe copy of
 | 
				
			||||||
 | 
					 *		the pointer data is carried out to avoid kernel crashes during
 | 
				
			||||||
 | 
					 *		operation.  Smaller types can use string space on the stack;
 | 
				
			||||||
 | 
					 *		larger programs can use map data to store the string
 | 
				
			||||||
 | 
					 *		representation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		The string can be subsequently shared with userspace via
 | 
				
			||||||
 | 
					 *		bpf_perf_event_output() or ring buffer interfaces.
 | 
				
			||||||
 | 
					 *		bpf_trace_printk() is to be avoided as it places too small
 | 
				
			||||||
 | 
					 *		a limit on string size to be useful.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		*flags* is a combination of
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		**BTF_F_COMPACT**
 | 
				
			||||||
 | 
					 *			no formatting around type information
 | 
				
			||||||
 | 
					 *		**BTF_F_NONAME**
 | 
				
			||||||
 | 
					 *			no struct/union member names/types
 | 
				
			||||||
 | 
					 *		**BTF_F_PTR_RAW**
 | 
				
			||||||
 | 
					 *			show raw (unobfuscated) pointer values;
 | 
				
			||||||
 | 
					 *			equivalent to printk specifier %px.
 | 
				
			||||||
 | 
					 *		**BTF_F_ZERO**
 | 
				
			||||||
 | 
					 *			show zero-valued struct/union members; they
 | 
				
			||||||
 | 
					 *			are not displayed by default
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *	Return
 | 
				
			||||||
 | 
					 *		The number of bytes that were written (or would have been
 | 
				
			||||||
 | 
					 *		written if output had to be truncated due to string size),
 | 
				
			||||||
 | 
					 *		or a negative error in cases of failure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define __BPF_FUNC_MAPPER(FN)		\
 | 
					#define __BPF_FUNC_MAPPER(FN)		\
 | 
				
			||||||
	FN(unspec),			\
 | 
						FN(unspec),			\
 | 
				
			||||||
| 
						 | 
					@ -3745,6 +3781,7 @@ union bpf_attr {
 | 
				
			||||||
	FN(inode_storage_delete),	\
 | 
						FN(inode_storage_delete),	\
 | 
				
			||||||
	FN(d_path),			\
 | 
						FN(d_path),			\
 | 
				
			||||||
	FN(copy_from_user),		\
 | 
						FN(copy_from_user),		\
 | 
				
			||||||
 | 
						FN(snprintf_btf),		\
 | 
				
			||||||
	/* */
 | 
						/* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
 | 
					/* integer value in 'imm' field of BPF_CALL instruction selects which helper
 | 
				
			||||||
| 
						 | 
					@ -4853,4 +4890,34 @@ struct bpf_sk_lookup {
 | 
				
			||||||
	__u32 local_port;	/* Host byte order */
 | 
						__u32 local_port;	/* Host byte order */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * struct btf_ptr is used for typed pointer representation; the
 | 
				
			||||||
 | 
					 * type id is used to render the pointer data as the appropriate type
 | 
				
			||||||
 | 
					 * via the bpf_snprintf_btf() helper described above.  A flags field -
 | 
				
			||||||
 | 
					 * potentially to specify additional details about the BTF pointer
 | 
				
			||||||
 | 
					 * (rather than its mode of display) - is included for future use.
 | 
				
			||||||
 | 
					 * Display flags - BTF_F_* - are passed to bpf_snprintf_btf separately.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct btf_ptr {
 | 
				
			||||||
 | 
						void *ptr;
 | 
				
			||||||
 | 
						__u32 type_id;
 | 
				
			||||||
 | 
						__u32 flags;		/* BTF ptr flags; unused at present. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Flags to control bpf_snprintf_btf() behaviour.
 | 
				
			||||||
 | 
					 *     - BTF_F_COMPACT: no formatting around type information
 | 
				
			||||||
 | 
					 *     - BTF_F_NONAME: no struct/union member names/types
 | 
				
			||||||
 | 
					 *     - BTF_F_PTR_RAW: show raw (unobfuscated) pointer values;
 | 
				
			||||||
 | 
					 *       equivalent to %px.
 | 
				
			||||||
 | 
					 *     - BTF_F_ZERO: show zero-valued struct/union members; they
 | 
				
			||||||
 | 
					 *       are not displayed by default
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						BTF_F_COMPACT	=	(1ULL << 0),
 | 
				
			||||||
 | 
						BTF_F_NONAME	=	(1ULL << 1),
 | 
				
			||||||
 | 
						BTF_F_PTR_RAW	=	(1ULL << 2),
 | 
				
			||||||
 | 
						BTF_F_ZERO	=	(1ULL << 3),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _UAPI__LINUX_BPF_H__ */
 | 
					#endif /* _UAPI__LINUX_BPF_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue