Re: [Non-DoD Source] Re: [PATCH net-next v2 5/5] selinux: bpf: Add addtional check for bpf object file receive

2017-10-10 Thread Chenbo Feng
On Tue, Oct 10, 2017 at 12:23 PM, Stephen Smalley  wrote:
> On Tue, 2017-10-10 at 10:48 -0700, Chenbo Feng wrote:
>> On Tue, Oct 10, 2017 at 7:24 AM, Stephen Smalley 
>> wrote:
>> > On Mon, 2017-10-09 at 15:20 -0700, Chenbo Feng wrote:
>> > > From: Chenbo Feng 
>> > >
>> > > Introduce a bpf object related check when sending and receiving
>> > > files
>> > > through unix domain socket as well as binder. It checks if the
>> > > receiving
>> > > process have privilege to read/write the bpf map or use the bpf
>> > > program.
>> > > This check is necessary because the bpf maps and programs are
>> > > using a
>> > > anonymous inode as their shared inode so the normal way of
>> > > checking
>> > > the
>> > > files and sockets when passing between processes cannot work
>> > > properly
>> > > on
>> > > eBPF object. This check only works when the BPF_SYSCALL is
>> > > configured.
>> > > The information stored inside the file security struct is the
>> > > same as
>> > > the information in bpf object security struct.
>> > >
>> > > Signed-off-by: Chenbo Feng 
>> > > ---
>> > >  include/linux/bpf.h   |  3 +++
>> > >  include/linux/lsm_hooks.h | 17 +
>> > >  include/linux/security.h  |  9 +++
>> > >  kernel/bpf/syscall.c  |  4 ++--
>> > >  security/security.c   |  8 +++
>> > >  security/selinux/hooks.c  | 61
>> > > +++
>> > >  6 files changed, 100 insertions(+), 2 deletions(-)
>> > >
>> > > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> > > index 225740688ab7..81d6c01b8825 100644
>> > > --- a/include/linux/bpf.h
>> > > +++ b/include/linux/bpf.h
>> > > @@ -285,6 +285,9 @@ int bpf_prog_array_copy_to_user(struct
>> > > bpf_prog_array __rcu *progs,
>> > >  #ifdef CONFIG_BPF_SYSCALL
>> > >  DECLARE_PER_CPU(int, bpf_prog_active);
>> > >
>> > > +extern const struct file_operations bpf_map_fops;
>> > > +extern const struct file_operations bpf_prog_fops;
>> > > +
>> > >  #define BPF_PROG_TYPE(_id, _ops) \
>> > >   extern const struct bpf_verifier_ops _ops;
>> > >  #define BPF_MAP_TYPE(_id, _ops) \
>> > > diff --git a/include/linux/lsm_hooks.h
>> > > b/include/linux/lsm_hooks.h
>> > > index 7161d8e7ee79..517dea60b87b 100644
>> > > --- a/include/linux/lsm_hooks.h
>> > > +++ b/include/linux/lsm_hooks.h
>> > > @@ -1385,6 +1385,19 @@
>> > >   * @bpf_prog_free_security:
>> > >   *   Clean up the security information stored inside bpf prog.
>> > >   *
>> > > + * @bpf_map_file:
>> > > + *   When creating a bpf map fd, set up the file security
>> > > information with
>> > > + *   the bpf security information stored in the map struct. So
>> > > when the map
>> > > + *   fd is passed between processes, the security module can
>> > > directly read
>> > > + *   the security information from file security struct rather
>> > > than the bpf
>> > > + *   security struct.
>> > > + *
>> > > + * @bpf_prog_file:
>> > > + *   When creating a bpf prog fd, set up the file security
>> > > information with
>> > > + *   the bpf security information stored in the prog struct. So
>> > > when the prog
>> > > + *   fd is passed between processes, the security module can
>> > > directly read
>> > > + *   the security information from file security struct rather
>> > > than the bpf
>> > > + *   security struct.
>> > >   */
>> > >  union security_list_options {
>> > >   int (*binder_set_context_mgr)(struct task_struct *mgr);
>> > > @@ -1726,6 +1739,8 @@ union security_list_options {
>> > >   void (*bpf_map_free_security)(struct bpf_map *map);
>> > >   int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux);
>> > >   void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
>> > > + void (*bpf_map_file)(struct bpf_map *map, struct file
>> > > *file);
>> > > + void (*bpf_prog_file)(struct bpf_prog_aux *aux, struct file
>> > > *file);
>> > >  #endif /* CONFIG_BPF_SYSCALL */
>> > >  };
>> > >
>> > > @@ -1954,6 +1969,8 @@ struct security_hook_heads {
>> > >   struct list_head bpf_map_free_security;
>> > >   struct list_head bpf_prog_alloc_security;
>> > >   struct list_head bpf_prog_free_security;
>> > > + struct list_head bpf_map_file;
>> > > + struct list_head bpf_prog_file;
>> > >  #endif /* CONFIG_BPF_SYSCALL */
>> > >  } __randomize_layout;
>> > >
>> > > diff --git a/include/linux/security.h b/include/linux/security.h
>> > > index 18800b0911e5..57573b794e2d 100644
>> > > --- a/include/linux/security.h
>> > > +++ b/include/linux/security.h
>> > > @@ -1740,6 +1740,8 @@ extern int security_bpf_map_alloc(struct
>> > > bpf_map *map);
>> > >  extern void security_bpf_map_free(struct bpf_map *map);
>> > >  extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
>> > >  extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
>> > > +extern void security_bpf_map_file(struct bpf_map *map, struct
>> > > file
>> > > *file);
>> > > +extern void 

Re: [Non-DoD Source] Re: [PATCH net-next v2 5/5] selinux: bpf: Add addtional check for bpf object file receive

2017-10-10 Thread Stephen Smalley
On Tue, 2017-10-10 at 10:48 -0700, Chenbo Feng wrote:
> On Tue, Oct 10, 2017 at 7:24 AM, Stephen Smalley 
> wrote:
> > On Mon, 2017-10-09 at 15:20 -0700, Chenbo Feng wrote:
> > > From: Chenbo Feng 
> > > 
> > > Introduce a bpf object related check when sending and receiving
> > > files
> > > through unix domain socket as well as binder. It checks if the
> > > receiving
> > > process have privilege to read/write the bpf map or use the bpf
> > > program.
> > > This check is necessary because the bpf maps and programs are
> > > using a
> > > anonymous inode as their shared inode so the normal way of
> > > checking
> > > the
> > > files and sockets when passing between processes cannot work
> > > properly
> > > on
> > > eBPF object. This check only works when the BPF_SYSCALL is
> > > configured.
> > > The information stored inside the file security struct is the
> > > same as
> > > the information in bpf object security struct.
> > > 
> > > Signed-off-by: Chenbo Feng 
> > > ---
> > >  include/linux/bpf.h   |  3 +++
> > >  include/linux/lsm_hooks.h | 17 +
> > >  include/linux/security.h  |  9 +++
> > >  kernel/bpf/syscall.c  |  4 ++--
> > >  security/security.c   |  8 +++
> > >  security/selinux/hooks.c  | 61
> > > +++
> > >  6 files changed, 100 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> > > index 225740688ab7..81d6c01b8825 100644
> > > --- a/include/linux/bpf.h
> > > +++ b/include/linux/bpf.h
> > > @@ -285,6 +285,9 @@ int bpf_prog_array_copy_to_user(struct
> > > bpf_prog_array __rcu *progs,
> > >  #ifdef CONFIG_BPF_SYSCALL
> > >  DECLARE_PER_CPU(int, bpf_prog_active);
> > > 
> > > +extern const struct file_operations bpf_map_fops;
> > > +extern const struct file_operations bpf_prog_fops;
> > > +
> > >  #define BPF_PROG_TYPE(_id, _ops) \
> > >   extern const struct bpf_verifier_ops _ops;
> > >  #define BPF_MAP_TYPE(_id, _ops) \
> > > diff --git a/include/linux/lsm_hooks.h
> > > b/include/linux/lsm_hooks.h
> > > index 7161d8e7ee79..517dea60b87b 100644
> > > --- a/include/linux/lsm_hooks.h
> > > +++ b/include/linux/lsm_hooks.h
> > > @@ -1385,6 +1385,19 @@
> > >   * @bpf_prog_free_security:
> > >   *   Clean up the security information stored inside bpf prog.
> > >   *
> > > + * @bpf_map_file:
> > > + *   When creating a bpf map fd, set up the file security
> > > information with
> > > + *   the bpf security information stored in the map struct. So
> > > when the map
> > > + *   fd is passed between processes, the security module can
> > > directly read
> > > + *   the security information from file security struct rather
> > > than the bpf
> > > + *   security struct.
> > > + *
> > > + * @bpf_prog_file:
> > > + *   When creating a bpf prog fd, set up the file security
> > > information with
> > > + *   the bpf security information stored in the prog struct. So
> > > when the prog
> > > + *   fd is passed between processes, the security module can
> > > directly read
> > > + *   the security information from file security struct rather
> > > than the bpf
> > > + *   security struct.
> > >   */
> > >  union security_list_options {
> > >   int (*binder_set_context_mgr)(struct task_struct *mgr);
> > > @@ -1726,6 +1739,8 @@ union security_list_options {
> > >   void (*bpf_map_free_security)(struct bpf_map *map);
> > >   int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux);
> > >   void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
> > > + void (*bpf_map_file)(struct bpf_map *map, struct file
> > > *file);
> > > + void (*bpf_prog_file)(struct bpf_prog_aux *aux, struct file
> > > *file);
> > >  #endif /* CONFIG_BPF_SYSCALL */
> > >  };
> > > 
> > > @@ -1954,6 +1969,8 @@ struct security_hook_heads {
> > >   struct list_head bpf_map_free_security;
> > >   struct list_head bpf_prog_alloc_security;
> > >   struct list_head bpf_prog_free_security;
> > > + struct list_head bpf_map_file;
> > > + struct list_head bpf_prog_file;
> > >  #endif /* CONFIG_BPF_SYSCALL */
> > >  } __randomize_layout;
> > > 
> > > diff --git a/include/linux/security.h b/include/linux/security.h
> > > index 18800b0911e5..57573b794e2d 100644
> > > --- a/include/linux/security.h
> > > +++ b/include/linux/security.h
> > > @@ -1740,6 +1740,8 @@ extern int security_bpf_map_alloc(struct
> > > bpf_map *map);
> > >  extern void security_bpf_map_free(struct bpf_map *map);
> > >  extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
> > >  extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
> > > +extern void security_bpf_map_file(struct bpf_map *map, struct
> > > file
> > > *file);
> > > +extern void security_bpf_prog_file(struct bpf_prog_aux *aux,
> > > struct
> > > file *file);
> > >  #else
> > >  static inline int security_bpf(int cmd, union bpf_attr *attr,
> > >  

Re: [PATCH net-next v2 5/5] selinux: bpf: Add addtional check for bpf object file receive

2017-10-10 Thread Chenbo Feng
On Tue, Oct 10, 2017 at 7:24 AM, Stephen Smalley  wrote:
> On Mon, 2017-10-09 at 15:20 -0700, Chenbo Feng wrote:
>> From: Chenbo Feng 
>>
>> Introduce a bpf object related check when sending and receiving files
>> through unix domain socket as well as binder. It checks if the
>> receiving
>> process have privilege to read/write the bpf map or use the bpf
>> program.
>> This check is necessary because the bpf maps and programs are using a
>> anonymous inode as their shared inode so the normal way of checking
>> the
>> files and sockets when passing between processes cannot work properly
>> on
>> eBPF object. This check only works when the BPF_SYSCALL is
>> configured.
>> The information stored inside the file security struct is the same as
>> the information in bpf object security struct.
>>
>> Signed-off-by: Chenbo Feng 
>> ---
>>  include/linux/bpf.h   |  3 +++
>>  include/linux/lsm_hooks.h | 17 +
>>  include/linux/security.h  |  9 +++
>>  kernel/bpf/syscall.c  |  4 ++--
>>  security/security.c   |  8 +++
>>  security/selinux/hooks.c  | 61
>> +++
>>  6 files changed, 100 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index 225740688ab7..81d6c01b8825 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -285,6 +285,9 @@ int bpf_prog_array_copy_to_user(struct
>> bpf_prog_array __rcu *progs,
>>  #ifdef CONFIG_BPF_SYSCALL
>>  DECLARE_PER_CPU(int, bpf_prog_active);
>>
>> +extern const struct file_operations bpf_map_fops;
>> +extern const struct file_operations bpf_prog_fops;
>> +
>>  #define BPF_PROG_TYPE(_id, _ops) \
>>   extern const struct bpf_verifier_ops _ops;
>>  #define BPF_MAP_TYPE(_id, _ops) \
>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>> index 7161d8e7ee79..517dea60b87b 100644
>> --- a/include/linux/lsm_hooks.h
>> +++ b/include/linux/lsm_hooks.h
>> @@ -1385,6 +1385,19 @@
>>   * @bpf_prog_free_security:
>>   *   Clean up the security information stored inside bpf prog.
>>   *
>> + * @bpf_map_file:
>> + *   When creating a bpf map fd, set up the file security
>> information with
>> + *   the bpf security information stored in the map struct. So
>> when the map
>> + *   fd is passed between processes, the security module can
>> directly read
>> + *   the security information from file security struct rather
>> than the bpf
>> + *   security struct.
>> + *
>> + * @bpf_prog_file:
>> + *   When creating a bpf prog fd, set up the file security
>> information with
>> + *   the bpf security information stored in the prog struct. So
>> when the prog
>> + *   fd is passed between processes, the security module can
>> directly read
>> + *   the security information from file security struct rather
>> than the bpf
>> + *   security struct.
>>   */
>>  union security_list_options {
>>   int (*binder_set_context_mgr)(struct task_struct *mgr);
>> @@ -1726,6 +1739,8 @@ union security_list_options {
>>   void (*bpf_map_free_security)(struct bpf_map *map);
>>   int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux);
>>   void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
>> + void (*bpf_map_file)(struct bpf_map *map, struct file
>> *file);
>> + void (*bpf_prog_file)(struct bpf_prog_aux *aux, struct file
>> *file);
>>  #endif /* CONFIG_BPF_SYSCALL */
>>  };
>>
>> @@ -1954,6 +1969,8 @@ struct security_hook_heads {
>>   struct list_head bpf_map_free_security;
>>   struct list_head bpf_prog_alloc_security;
>>   struct list_head bpf_prog_free_security;
>> + struct list_head bpf_map_file;
>> + struct list_head bpf_prog_file;
>>  #endif /* CONFIG_BPF_SYSCALL */
>>  } __randomize_layout;
>>
>> diff --git a/include/linux/security.h b/include/linux/security.h
>> index 18800b0911e5..57573b794e2d 100644
>> --- a/include/linux/security.h
>> +++ b/include/linux/security.h
>> @@ -1740,6 +1740,8 @@ extern int security_bpf_map_alloc(struct
>> bpf_map *map);
>>  extern void security_bpf_map_free(struct bpf_map *map);
>>  extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
>>  extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
>> +extern void security_bpf_map_file(struct bpf_map *map, struct file
>> *file);
>> +extern void security_bpf_prog_file(struct bpf_prog_aux *aux, struct
>> file *file);
>>  #else
>>  static inline int security_bpf(int cmd, union bpf_attr *attr,
>>unsigned int size)
>> @@ -1772,6 +1774,13 @@ static inline int
>> security_bpf_prog_alloc(struct bpf_prog_aux *aux)
>>
>>  static inline void security_bpf_prog_free(struct bpf_prog_aux *aux)
>>  { }
>> +
>> +static inline void security_bpf_map_file(struct bpf_map *map, struct
>> file *file)
>> +{ }
>> +
>> +static inline void security_bpf_prog_file(struct bpf_prog_aux *aux,
>> +   struct file 

Re: [PATCH net-next v2 5/5] selinux: bpf: Add addtional check for bpf object file receive

2017-10-10 Thread Stephen Smalley
On Mon, 2017-10-09 at 15:20 -0700, Chenbo Feng wrote:
> From: Chenbo Feng 
> 
> Introduce a bpf object related check when sending and receiving files
> through unix domain socket as well as binder. It checks if the
> receiving
> process have privilege to read/write the bpf map or use the bpf
> program.
> This check is necessary because the bpf maps and programs are using a
> anonymous inode as their shared inode so the normal way of checking
> the
> files and sockets when passing between processes cannot work properly
> on
> eBPF object. This check only works when the BPF_SYSCALL is
> configured.
> The information stored inside the file security struct is the same as
> the information in bpf object security struct.
> 
> Signed-off-by: Chenbo Feng 
> ---
>  include/linux/bpf.h   |  3 +++
>  include/linux/lsm_hooks.h | 17 +
>  include/linux/security.h  |  9 +++
>  kernel/bpf/syscall.c  |  4 ++--
>  security/security.c   |  8 +++
>  security/selinux/hooks.c  | 61
> +++
>  6 files changed, 100 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 225740688ab7..81d6c01b8825 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -285,6 +285,9 @@ int bpf_prog_array_copy_to_user(struct
> bpf_prog_array __rcu *progs,
>  #ifdef CONFIG_BPF_SYSCALL
>  DECLARE_PER_CPU(int, bpf_prog_active);
>  
> +extern const struct file_operations bpf_map_fops;
> +extern const struct file_operations bpf_prog_fops;
> +
>  #define BPF_PROG_TYPE(_id, _ops) \
>   extern const struct bpf_verifier_ops _ops;
>  #define BPF_MAP_TYPE(_id, _ops) \
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7161d8e7ee79..517dea60b87b 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1385,6 +1385,19 @@
>   * @bpf_prog_free_security:
>   *   Clean up the security information stored inside bpf prog.
>   *
> + * @bpf_map_file:
> + *   When creating a bpf map fd, set up the file security
> information with
> + *   the bpf security information stored in the map struct. So
> when the map
> + *   fd is passed between processes, the security module can
> directly read
> + *   the security information from file security struct rather
> than the bpf
> + *   security struct.
> + *
> + * @bpf_prog_file:
> + *   When creating a bpf prog fd, set up the file security
> information with
> + *   the bpf security information stored in the prog struct. So
> when the prog
> + *   fd is passed between processes, the security module can
> directly read
> + *   the security information from file security struct rather
> than the bpf
> + *   security struct.
>   */
>  union security_list_options {
>   int (*binder_set_context_mgr)(struct task_struct *mgr);
> @@ -1726,6 +1739,8 @@ union security_list_options {
>   void (*bpf_map_free_security)(struct bpf_map *map);
>   int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux);
>   void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
> + void (*bpf_map_file)(struct bpf_map *map, struct file
> *file);
> + void (*bpf_prog_file)(struct bpf_prog_aux *aux, struct file
> *file);
>  #endif /* CONFIG_BPF_SYSCALL */
>  };
>  
> @@ -1954,6 +1969,8 @@ struct security_hook_heads {
>   struct list_head bpf_map_free_security;
>   struct list_head bpf_prog_alloc_security;
>   struct list_head bpf_prog_free_security;
> + struct list_head bpf_map_file;
> + struct list_head bpf_prog_file;
>  #endif /* CONFIG_BPF_SYSCALL */
>  } __randomize_layout;
>  
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 18800b0911e5..57573b794e2d 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1740,6 +1740,8 @@ extern int security_bpf_map_alloc(struct
> bpf_map *map);
>  extern void security_bpf_map_free(struct bpf_map *map);
>  extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
>  extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
> +extern void security_bpf_map_file(struct bpf_map *map, struct file
> *file);
> +extern void security_bpf_prog_file(struct bpf_prog_aux *aux, struct
> file *file);
>  #else
>  static inline int security_bpf(int cmd, union bpf_attr *attr,
>    unsigned int size)
> @@ -1772,6 +1774,13 @@ static inline int
> security_bpf_prog_alloc(struct bpf_prog_aux *aux)
>  
>  static inline void security_bpf_prog_free(struct bpf_prog_aux *aux)
>  { }
> +
> +static inline void security_bpf_map_file(struct bpf_map *map, struct
> file *file)
> +{ }
> +
> +static inline void security_bpf_prog_file(struct bpf_prog_aux *aux,
> +   struct file *file)
> +{ }
>  #endif /* CONFIG_SECURITY */
>  #endif /* CONFIG_BPF_SYSCALL */
>  
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 1cf31ddd7616..b144181d3f3a 100644
> --- 

[PATCH net-next v2 5/5] selinux: bpf: Add addtional check for bpf object file receive

2017-10-09 Thread Chenbo Feng
From: Chenbo Feng 

Introduce a bpf object related check when sending and receiving files
through unix domain socket as well as binder. It checks if the receiving
process have privilege to read/write the bpf map or use the bpf program.
This check is necessary because the bpf maps and programs are using a
anonymous inode as their shared inode so the normal way of checking the
files and sockets when passing between processes cannot work properly on
eBPF object. This check only works when the BPF_SYSCALL is configured.
The information stored inside the file security struct is the same as
the information in bpf object security struct.

Signed-off-by: Chenbo Feng 
---
 include/linux/bpf.h   |  3 +++
 include/linux/lsm_hooks.h | 17 +
 include/linux/security.h  |  9 +++
 kernel/bpf/syscall.c  |  4 ++--
 security/security.c   |  8 +++
 security/selinux/hooks.c  | 61 +++
 6 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 225740688ab7..81d6c01b8825 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -285,6 +285,9 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu 
*progs,
 #ifdef CONFIG_BPF_SYSCALL
 DECLARE_PER_CPU(int, bpf_prog_active);
 
+extern const struct file_operations bpf_map_fops;
+extern const struct file_operations bpf_prog_fops;
+
 #define BPF_PROG_TYPE(_id, _ops) \
extern const struct bpf_verifier_ops _ops;
 #define BPF_MAP_TYPE(_id, _ops) \
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7161d8e7ee79..517dea60b87b 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1385,6 +1385,19 @@
  * @bpf_prog_free_security:
  * Clean up the security information stored inside bpf prog.
  *
+ * @bpf_map_file:
+ * When creating a bpf map fd, set up the file security information with
+ * the bpf security information stored in the map struct. So when the map
+ * fd is passed between processes, the security module can directly read
+ * the security information from file security struct rather than the bpf
+ * security struct.
+ *
+ * @bpf_prog_file:
+ * When creating a bpf prog fd, set up the file security information with
+ * the bpf security information stored in the prog struct. So when the prog
+ * fd is passed between processes, the security module can directly read
+ * the security information from file security struct rather than the bpf
+ * security struct.
  */
 union security_list_options {
int (*binder_set_context_mgr)(struct task_struct *mgr);
@@ -1726,6 +1739,8 @@ union security_list_options {
void (*bpf_map_free_security)(struct bpf_map *map);
int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux);
void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
+   void (*bpf_map_file)(struct bpf_map *map, struct file *file);
+   void (*bpf_prog_file)(struct bpf_prog_aux *aux, struct file *file);
 #endif /* CONFIG_BPF_SYSCALL */
 };
 
@@ -1954,6 +1969,8 @@ struct security_hook_heads {
struct list_head bpf_map_free_security;
struct list_head bpf_prog_alloc_security;
struct list_head bpf_prog_free_security;
+   struct list_head bpf_map_file;
+   struct list_head bpf_prog_file;
 #endif /* CONFIG_BPF_SYSCALL */
 } __randomize_layout;
 
diff --git a/include/linux/security.h b/include/linux/security.h
index 18800b0911e5..57573b794e2d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1740,6 +1740,8 @@ extern int security_bpf_map_alloc(struct bpf_map *map);
 extern void security_bpf_map_free(struct bpf_map *map);
 extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
 extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
+extern void security_bpf_map_file(struct bpf_map *map, struct file *file);
+extern void security_bpf_prog_file(struct bpf_prog_aux *aux, struct file 
*file);
 #else
 static inline int security_bpf(int cmd, union bpf_attr *attr,
 unsigned int size)
@@ -1772,6 +1774,13 @@ static inline int security_bpf_prog_alloc(struct 
bpf_prog_aux *aux)
 
 static inline void security_bpf_prog_free(struct bpf_prog_aux *aux)
 { }
+
+static inline void security_bpf_map_file(struct bpf_map *map, struct file 
*file)
+{ }
+
+static inline void security_bpf_prog_file(struct bpf_prog_aux *aux,
+ struct file *file)
+{ }
 #endif /* CONFIG_SECURITY */
 #endif /* CONFIG_BPF_SYSCALL */
 
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 1cf31ddd7616..b144181d3f3a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -313,7 +313,7 @@ static ssize_t bpf_dummy_write(struct file *filp, const 
char __user *buf,
return -EINVAL;
 }
 
-static const struct file_operations bpf_map_fops = {
+const struct file_operations