netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname
@ 2019-10-18 10:47 Wenbo Zhang
  2019-10-18 18:20 ` Yonghong Song
  0 siblings, 1 reply; 5+ messages in thread
From: Wenbo Zhang @ 2019-10-18 10:47 UTC (permalink / raw)
  To: netdev; +Cc: yhs, daniel, Wenbo Zhang

When people want to identify which file system files are being opened,
read, and written to, they can use this helper with file descriptor as
input to achieve this goal. Other pseudo filesystems are also supported.

Signed-off-by: Wenbo Zhang <ethercflow@gmail.com>
---
 include/linux/bpf.h            |  1 +
 include/uapi/linux/bpf.h       | 12 ++++++++++-
 kernel/bpf/core.c              |  1 +
 kernel/bpf/helpers.c           | 39 ++++++++++++++++++++++++++++++++++
 kernel/trace/bpf_trace.c       |  2 ++
 tools/include/uapi/linux/bpf.h | 12 ++++++++++-
 6 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 2c2c29b49845..d73314a7e674 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1082,6 +1082,7 @@ extern const struct bpf_func_proto bpf_get_local_storage_proto;
 extern const struct bpf_func_proto bpf_strtol_proto;
 extern const struct bpf_func_proto bpf_strtoul_proto;
 extern const struct bpf_func_proto bpf_tcp_sock_proto;
+extern const struct bpf_func_proto bpf_fd2path_proto;
 
 /* Shared helpers among cBPF and eBPF. */
 void bpf_user_rnd_init_once(void);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 4af8b0819a32..fdb37740951f 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2773,6 +2773,15 @@ union bpf_attr {
  *
  * 		This helper is similar to **bpf_perf_event_output**\ () but
  * 		restricted to raw_tracepoint bpf programs.
+ *
+ * int bpf_fd2path(char *path, u32 size, int fd)
+ *	Description
+ *		Get **file** atrribute from the current task by *fd*, then call
+ *		**d_path** to get it's absolute path and copy it as string into
+ *		*path* of *size*. The **path** also support pseudo filesystems
+ *		(whether or not it can be mounted). The *size* must be strictly
+ *		positive. On success, the helper makes sure that the *path* is
+ *		NUL-terminated. On failure, it is filled with zeroes.
  * 	Return
  * 		0 on success, or a negative error in case of failure.
  */
@@ -2888,7 +2897,8 @@ union bpf_attr {
 	FN(sk_storage_delete),		\
 	FN(send_signal),		\
 	FN(tcp_gen_syncookie),		\
-	FN(skb_output),
+	FN(skb_output),			\
+	FN(fd2path),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 673f5d40a93e..6b44ed804280 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2079,6 +2079,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
 const struct bpf_func_proto bpf_get_current_comm_proto __weak;
 const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
 const struct bpf_func_proto bpf_get_local_storage_proto __weak;
+const struct bpf_func_proto bpf_fd2path_proto __weak;
 
 const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 {
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 5e28718928ca..0832536c7ddb 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -487,3 +487,42 @@ const struct bpf_func_proto bpf_strtoul_proto = {
 	.arg4_type	= ARG_PTR_TO_LONG,
 };
 #endif
+
+BPF_CALL_3(bpf_fd2path, char *, dst, u32, size, int, fd)
+{
+	struct fd f;
+	int ret;
+	char *p;
+
+	ret = security_locked_down(LOCKDOWN_BPF_READ);
+	if (ret < 0)
+		goto out;
+
+	f = fdget_raw(fd);
+	if (!f.file)
+		goto out;
+
+	p = d_path(&f.file->f_path, dst, size);
+	if (IS_ERR_OR_NULL(p))
+		ret = PTR_ERR(p);
+	else {
+		ret = strlen(p);
+		memmove(dst, p, ret);
+		dst[ret] = 0;
+	}
+
+	if (unlikely(ret < 0))
+out:
+		memset(dst, '0', size);
+
+	return ret;
+}
+
+const struct bpf_func_proto bpf_fd2path_proto = {
+	.func       = bpf_fd2path,
+	.gpl_only   = true,
+	.ret_type   = RET_INTEGER,
+	.arg1_type  = ARG_PTR_TO_UNINIT_MEM,
+	.arg2_type  = ARG_CONST_SIZE,
+	.arg3_type  = ARG_ANYTHING,
+};
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 52f7e9d8c29b..23cc3a955e59 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -735,6 +735,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 #endif
 	case BPF_FUNC_send_signal:
 		return &bpf_send_signal_proto;
+	case BPF_FUNC_fd2path:
+		return &bpf_fd2path_proto;
 	default:
 		return NULL;
 	}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 4af8b0819a32..fdb37740951f 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2773,6 +2773,15 @@ union bpf_attr {
  *
  * 		This helper is similar to **bpf_perf_event_output**\ () but
  * 		restricted to raw_tracepoint bpf programs.
+ *
+ * int bpf_fd2path(char *path, u32 size, int fd)
+ *	Description
+ *		Get **file** atrribute from the current task by *fd*, then call
+ *		**d_path** to get it's absolute path and copy it as string into
+ *		*path* of *size*. The **path** also support pseudo filesystems
+ *		(whether or not it can be mounted). The *size* must be strictly
+ *		positive. On success, the helper makes sure that the *path* is
+ *		NUL-terminated. On failure, it is filled with zeroes.
  * 	Return
  * 		0 on success, or a negative error in case of failure.
  */
@@ -2888,7 +2897,8 @@ union bpf_attr {
 	FN(sk_storage_delete),		\
 	FN(send_signal),		\
 	FN(tcp_gen_syncookie),		\
-	FN(skb_output),
+	FN(skb_output),			\
+	FN(fd2path),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname
  2019-10-18 10:47 [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname Wenbo Zhang
@ 2019-10-18 18:20 ` Yonghong Song
  0 siblings, 0 replies; 5+ messages in thread
From: Yonghong Song @ 2019-10-18 18:20 UTC (permalink / raw)
  To: Wenbo Zhang, netdev; +Cc: daniel



On 10/18/19 3:47 AM, Wenbo Zhang wrote:
> When people want to identify which file system files are being opened,
> read, and written to, they can use this helper with file descriptor as
> input to achieve this goal. Other pseudo filesystems are also supported.

I commented on previous version of the patch.
Could you add version number (this is v2) to the patch set
when you submit next time (which will be v3).

> 
> Signed-off-by: Wenbo Zhang <ethercflow@gmail.com>
> ---
>   include/linux/bpf.h            |  1 +
>   include/uapi/linux/bpf.h       | 12 ++++++++++-
>   kernel/bpf/core.c              |  1 +
>   kernel/bpf/helpers.c           | 39 ++++++++++++++++++++++++++++++++++
>   kernel/trace/bpf_trace.c       |  2 ++
>   tools/include/uapi/linux/bpf.h | 12 ++++++++++-
>   6 files changed, 65 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 2c2c29b49845..d73314a7e674 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1082,6 +1082,7 @@ extern const struct bpf_func_proto bpf_get_local_storage_proto;
>   extern const struct bpf_func_proto bpf_strtol_proto;
>   extern const struct bpf_func_proto bpf_strtoul_proto;
>   extern const struct bpf_func_proto bpf_tcp_sock_proto;
> +extern const struct bpf_func_proto bpf_fd2path_proto;
>   
>   /* Shared helpers among cBPF and eBPF. */
>   void bpf_user_rnd_init_once(void);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 4af8b0819a32..fdb37740951f 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -2773,6 +2773,15 @@ union bpf_attr {
>    *
>    * 		This helper is similar to **bpf_perf_event_output**\ () but
>    * 		restricted to raw_tracepoint bpf programs.
> + *
> + * int bpf_fd2path(char *path, u32 size, int fd)
> + *	Description
> + *		Get **file** atrribute from the current task by *fd*, then call
> + *		**d_path** to get it's absolute path and copy it as string into
> + *		*path* of *size*. The **path** also support pseudo filesystems
> + *		(whether or not it can be mounted). The *size* must be strictly
> + *		positive. On success, the helper makes sure that the *path* is
> + *		NUL-terminated. On failure, it is filled with zeroes.
>    * 	Return
>    * 		0 on success, or a negative error in case of failure.
>    */
> @@ -2888,7 +2897,8 @@ union bpf_attr {
>   	FN(sk_storage_delete),		\
>   	FN(send_signal),		\
>   	FN(tcp_gen_syncookie),		\
> -	FN(skb_output),
> +	FN(skb_output),			\
> +	FN(fd2path),
>   
>   /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>    * function eBPF program intends to call
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 673f5d40a93e..6b44ed804280 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2079,6 +2079,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
>   const struct bpf_func_proto bpf_get_current_comm_proto __weak;
>   const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
>   const struct bpf_func_proto bpf_get_local_storage_proto __weak;
> +const struct bpf_func_proto bpf_fd2path_proto __weak;
>   
>   const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
>   {
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 5e28718928ca..0832536c7ddb 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -487,3 +487,42 @@ const struct bpf_func_proto bpf_strtoul_proto = {
>   	.arg4_type	= ARG_PTR_TO_LONG,
>   };
>   #endif
> +
> +BPF_CALL_3(bpf_fd2path, char *, dst, u32, size, int, fd)
> +{
> +	struct fd f;
> +	int ret;
> +	char *p;
> +
> +	ret = security_locked_down(LOCKDOWN_BPF_READ);
> +	if (ret < 0)
> +		goto out;
> +
> +	f = fdget_raw(fd);
> +	if (!f.file)
> +		goto out;
> +
> +	p = d_path(&f.file->f_path, dst, size);
> +	if (IS_ERR_OR_NULL(p))
> +		ret = PTR_ERR(p);
> +	else {
> +		ret = strlen(p);
> +		memmove(dst, p, ret);
> +		dst[ret] = 0;
> +	}
> +
> +	if (unlikely(ret < 0))
> +out:
> +		memset(dst, '0', size);
> +
> +	return ret;
> +}
> +
> +const struct bpf_func_proto bpf_fd2path_proto = {
> +	.func       = bpf_fd2path,
> +	.gpl_only   = true,
> +	.ret_type   = RET_INTEGER,
> +	.arg1_type  = ARG_PTR_TO_UNINIT_MEM,
> +	.arg2_type  = ARG_CONST_SIZE,
> +	.arg3_type  = ARG_ANYTHING,
> +};
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 52f7e9d8c29b..23cc3a955e59 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -735,6 +735,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
>   #endif
>   	case BPF_FUNC_send_signal:
>   		return &bpf_send_signal_proto;
> +	case BPF_FUNC_fd2path:
> +		return &bpf_fd2path_proto;
>   	default:
>   		return NULL;
>   	}
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index 4af8b0819a32..fdb37740951f 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
> @@ -2773,6 +2773,15 @@ union bpf_attr {
>    *
>    * 		This helper is similar to **bpf_perf_event_output**\ () but
>    * 		restricted to raw_tracepoint bpf programs.
> + *
> + * int bpf_fd2path(char *path, u32 size, int fd)
> + *	Description
> + *		Get **file** atrribute from the current task by *fd*, then call
> + *		**d_path** to get it's absolute path and copy it as string into
> + *		*path* of *size*. The **path** also support pseudo filesystems
> + *		(whether or not it can be mounted). The *size* must be strictly
> + *		positive. On success, the helper makes sure that the *path* is
> + *		NUL-terminated. On failure, it is filled with zeroes.
>    * 	Return
>    * 		0 on success, or a negative error in case of failure.
>    */
> @@ -2888,7 +2897,8 @@ union bpf_attr {
>   	FN(sk_storage_delete),		\
>   	FN(send_signal),		\
>   	FN(tcp_gen_syncookie),		\
> -	FN(skb_output),
> +	FN(skb_output),			\
> +	FN(fd2path),
>   
>   /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>    * function eBPF program intends to call
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname
  2019-10-17  9:26 Zwb
  2019-10-17 14:49 ` Daniel Borkmann
@ 2019-10-18 16:07 ` Yonghong Song
  1 sibling, 0 replies; 5+ messages in thread
From: Yonghong Song @ 2019-10-18 16:07 UTC (permalink / raw)
  To: Zwb, netdev



On 10/17/19 2:26 AM, Zwb wrote:
> When people want to identify which file system files are being opened,
> read, and written to, they can use this helper with file descriptor as
> input to achieve this goal. Other pseudo filesystems are also supported.

For the description, a link to related bcc issue may provide more 
background why this is needed.

Please send to bpf mailing list bpf@vger.kernel.org. This way, more 
people can catch and look at this patch.

Please provide a test case in tools/testing/selftests/bpf directory.

> 
> Signed-off-by: Zwb <ethercflow@gmail.com>
> ---
>   include/linux/bpf.h            |  1 +
>   include/uapi/linux/bpf.h       |  1 +
>   kernel/bpf/core.c              |  1 +
>   kernel/bpf/helpers.c           | 39 ++++++++++++++++++++++++++++++++++
>   kernel/trace/bpf_trace.c       |  2 ++
>   tools/include/uapi/linux/bpf.h |  1 +
>   6 files changed, 45 insertions(+)
> 
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 282e28bf41ec..c0a710cf2c88 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1055,6 +1055,7 @@ extern const struct bpf_func_proto bpf_get_local_storage_proto;
>   extern const struct bpf_func_proto bpf_strtol_proto;
>   extern const struct bpf_func_proto bpf_strtoul_proto;
>   extern const struct bpf_func_proto bpf_tcp_sock_proto;
> +extern const struct bpf_func_proto bpf_fd2path_proto;
>   
>   /* Shared helpers among cBPF and eBPF. */
>   void bpf_user_rnd_init_once(void);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index a65c3b0c6935..a4a5d432e572 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -2769,6 +2769,7 @@ union bpf_attr {
>   	FN(get_current_pid_tgid),	\
>   	FN(get_current_uid_gid),	\
>   	FN(get_current_comm),		\
> +	FN(fd2path),			\

As Daniel mentioned, please put this at the end of enum to
avoid breaking backward compatibility. Also this needs proper
documentation.

>   	FN(get_cgroup_classid),		\
>   	FN(skb_vlan_push),		\
>   	FN(skb_vlan_pop),		\
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 66088a9e9b9e..349a8b1be232 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2042,6 +2042,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
>   const struct bpf_func_proto bpf_get_current_comm_proto __weak;
>   const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
>   const struct bpf_func_proto bpf_get_local_storage_proto __weak;
> +const struct bpf_func_proto bpf_fd2path_proto __weak;
>   
>   const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
>   {
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 5e28718928ca..0832536c7ddb 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -487,3 +487,42 @@ const struct bpf_func_proto bpf_strtoul_proto = {
>   	.arg4_type	= ARG_PTR_TO_LONG,
>   };
>   #endif
> +
> +BPF_CALL_3(bpf_fd2path, char *, dst, u32, size, int, fd)
> +{
> +	struct fd f;
> +	int ret;
> +	char *p;
> +
> +	ret = security_locked_down(LOCKDOWN_BPF_READ);
> +	if (ret < 0)
> +		goto out;

The LOCKDOWN_BPF_READ is used when kernel internal data is exposed.
That is why currently only bpf_probe_read() and bpf_probe_read_str()
are checked.
Not 100% sure whether this helper needs check of LOCKDOWN_BPF_READ
or not.

> +
> +	f = fdget_raw(fd);
> +	if (!f.file)
> +		goto out;
> +
> +	p = d_path(&f.file->f_path, dst, size);

inside d_path, spin_lock() could be called. I guess it is okay.

> +	if (IS_ERR_OR_NULL(p))
> +		ret = PTR_ERR(p);
> +	else {
> +		ret = strlen(p);
> +		memmove(dst, p, ret);
> +		dst[ret] = 0;
> +	}
> +
> +	if (unlikely(ret < 0))
> +out:
> +		memset(dst, '0', size);

The coding style here is not great. Maybe you can do
	if (IS_ERR_OR_NULL(p)) {
		ret = PTRERR(p);
		goto error;
	}

	ret = strlen(p);
	memmove(dst, p, ret);
	dst[ret] = '\0';
	return ret;

    error:
	memset(dst, '0', size);
	return ret;

> +
> +	return ret;
> +}
> +
> +const struct bpf_func_proto bpf_fd2path_proto = {
> +	.func       = bpf_fd2path,
> +	.gpl_only   = true,
> +	.ret_type   = RET_INTEGER,
> +	.arg1_type  = ARG_PTR_TO_UNINIT_MEM,
> +	.arg2_type  = ARG_CONST_SIZE,
> +	.arg3_type  = ARG_ANYTHING,
> +};
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 44bd08f2443b..0ca7fdefb8e5 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -735,6 +735,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
>   #endif
>   	case BPF_FUNC_send_signal:
>   		return &bpf_send_signal_proto;
> +	case BPF_FUNC_fd2path:
> +		return &bpf_fd2path_proto;
>   	default:
>   		return NULL;
>   	}
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index a65c3b0c6935..a4a5d432e572 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
> @@ -2769,6 +2769,7 @@ union bpf_attr {
>   	FN(get_current_pid_tgid),	\
>   	FN(get_current_uid_gid),	\
>   	FN(get_current_comm),		\
> +	FN(fd2path),			\
>   	FN(get_cgroup_classid),		\
>   	FN(skb_vlan_push),		\
>   	FN(skb_vlan_pop),		\
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname
  2019-10-17  9:26 Zwb
@ 2019-10-17 14:49 ` Daniel Borkmann
  2019-10-18 16:07 ` Yonghong Song
  1 sibling, 0 replies; 5+ messages in thread
From: Daniel Borkmann @ 2019-10-17 14:49 UTC (permalink / raw)
  To: Zwb, netdev; +Cc: yhs

On 10/17/19 11:26 AM, Zwb wrote:
> When people want to identify which file system files are being opened,
> read, and written to, they can use this helper with file descriptor as
> input to achieve this goal. Other pseudo filesystems are also supported.
> 
> Signed-off-by: Zwb <ethercflow@gmail.com>

SOB requires that there is a proper name, see Documentation/process/submitting-patches.rst +431.

[...]
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index a65c3b0c6935..a4a5d432e572 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -2769,6 +2769,7 @@ union bpf_attr {
>   	FN(get_current_pid_tgid),	\
>   	FN(get_current_uid_gid),	\
>   	FN(get_current_comm),		\
> +	FN(fd2path),			\

Adding into the middle will break existing BPF programs. Helper description is also missing.

>   	FN(get_cgroup_classid),		\
>   	FN(skb_vlan_push),		\
>   	FN(skb_vlan_pop),		\

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname
@ 2019-10-17  9:26 Zwb
  2019-10-17 14:49 ` Daniel Borkmann
  2019-10-18 16:07 ` Yonghong Song
  0 siblings, 2 replies; 5+ messages in thread
From: Zwb @ 2019-10-17  9:26 UTC (permalink / raw)
  To: netdev; +Cc: yhs, Zwb

When people want to identify which file system files are being opened,
read, and written to, they can use this helper with file descriptor as
input to achieve this goal. Other pseudo filesystems are also supported.

Signed-off-by: Zwb <ethercflow@gmail.com>
---
 include/linux/bpf.h            |  1 +
 include/uapi/linux/bpf.h       |  1 +
 kernel/bpf/core.c              |  1 +
 kernel/bpf/helpers.c           | 39 ++++++++++++++++++++++++++++++++++
 kernel/trace/bpf_trace.c       |  2 ++
 tools/include/uapi/linux/bpf.h |  1 +
 6 files changed, 45 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 282e28bf41ec..c0a710cf2c88 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1055,6 +1055,7 @@ extern const struct bpf_func_proto bpf_get_local_storage_proto;
 extern const struct bpf_func_proto bpf_strtol_proto;
 extern const struct bpf_func_proto bpf_strtoul_proto;
 extern const struct bpf_func_proto bpf_tcp_sock_proto;
+extern const struct bpf_func_proto bpf_fd2path_proto;
 
 /* Shared helpers among cBPF and eBPF. */
 void bpf_user_rnd_init_once(void);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index a65c3b0c6935..a4a5d432e572 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2769,6 +2769,7 @@ union bpf_attr {
 	FN(get_current_pid_tgid),	\
 	FN(get_current_uid_gid),	\
 	FN(get_current_comm),		\
+	FN(fd2path),			\
 	FN(get_cgroup_classid),		\
 	FN(skb_vlan_push),		\
 	FN(skb_vlan_pop),		\
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 66088a9e9b9e..349a8b1be232 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2042,6 +2042,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
 const struct bpf_func_proto bpf_get_current_comm_proto __weak;
 const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
 const struct bpf_func_proto bpf_get_local_storage_proto __weak;
+const struct bpf_func_proto bpf_fd2path_proto __weak;
 
 const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 {
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 5e28718928ca..0832536c7ddb 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -487,3 +487,42 @@ const struct bpf_func_proto bpf_strtoul_proto = {
 	.arg4_type	= ARG_PTR_TO_LONG,
 };
 #endif
+
+BPF_CALL_3(bpf_fd2path, char *, dst, u32, size, int, fd)
+{
+	struct fd f;
+	int ret;
+	char *p;
+
+	ret = security_locked_down(LOCKDOWN_BPF_READ);
+	if (ret < 0)
+		goto out;
+
+	f = fdget_raw(fd);
+	if (!f.file)
+		goto out;
+
+	p = d_path(&f.file->f_path, dst, size);
+	if (IS_ERR_OR_NULL(p))
+		ret = PTR_ERR(p);
+	else {
+		ret = strlen(p);
+		memmove(dst, p, ret);
+		dst[ret] = 0;
+	}
+
+	if (unlikely(ret < 0))
+out:
+		memset(dst, '0', size);
+
+	return ret;
+}
+
+const struct bpf_func_proto bpf_fd2path_proto = {
+	.func       = bpf_fd2path,
+	.gpl_only   = true,
+	.ret_type   = RET_INTEGER,
+	.arg1_type  = ARG_PTR_TO_UNINIT_MEM,
+	.arg2_type  = ARG_CONST_SIZE,
+	.arg3_type  = ARG_ANYTHING,
+};
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 44bd08f2443b..0ca7fdefb8e5 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -735,6 +735,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 #endif
 	case BPF_FUNC_send_signal:
 		return &bpf_send_signal_proto;
+	case BPF_FUNC_fd2path:
+		return &bpf_fd2path_proto;
 	default:
 		return NULL;
 	}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index a65c3b0c6935..a4a5d432e572 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2769,6 +2769,7 @@ union bpf_attr {
 	FN(get_current_pid_tgid),	\
 	FN(get_current_uid_gid),	\
 	FN(get_current_comm),		\
+	FN(fd2path),			\
 	FN(get_cgroup_classid),		\
 	FN(skb_vlan_push),		\
 	FN(skb_vlan_pop),		\
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-10-18 18:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-18 10:47 [PATCH bpf-next] bpf: add new helper fd2path for mapping a file descriptor to a pathname Wenbo Zhang
2019-10-18 18:20 ` Yonghong Song
  -- strict thread matches above, loose matches on Subject: below --
2019-10-17  9:26 Zwb
2019-10-17 14:49 ` Daniel Borkmann
2019-10-18 16:07 ` Yonghong Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).