diff mbox series

[35/58] LSM: Limit calls to certain module hooks

Message ID 20190602165101.25079-36-casey@schaufler-ca.com (mailing list archive)
State Superseded
Headers show
Series LSM: Module stacking for AppArmor | expand

Commit Message

Casey Schaufler June 2, 2019, 4:50 p.m. UTC
LSM hooks dealing with security context strings should
only be called for one security module. Add call macros
that invoke a single module hook and us in for those cases.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 security/security.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

Comments

Ondrej Mosnacek June 10, 2019, 10:20 a.m. UTC | #1
Hi Casey,

On Sun, Jun 2, 2019 at 6:53 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
> LSM hooks dealing with security context strings should
> only be called for one security module. Add call macros
> that invoke a single module hook and us in for those cases.
>
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  security/security.c | 32 ++++++++++++++++++++++++++++----
>  1 file changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/security/security.c b/security/security.c
> index 69983ad68233..365970f2501d 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -698,6 +698,16 @@ int lsm_superblock_alloc(struct super_block *sb)
>                         P->hook.FUNC(__VA_ARGS__);              \
>         } while (0)
>
> +#define call_one_void_hook(FUNC, ...)                          \
> +       do {                                                    \
> +               struct security_hook_list *P;                   \
> +                                                               \
> +               hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
> +                       P->hook.FUNC(__VA_ARGS__);              \
> +                       break;                                  \
> +               }                                               \
> +       } while (0)
> +
>  #define call_int_hook(FUNC, IRC, ...) ({                       \
>         int RC = IRC;                                           \
>         do {                                                    \
> @@ -712,6 +722,19 @@ int lsm_superblock_alloc(struct super_block *sb)
>         RC;                                                     \
>  })
>
> +#define call_one_int_hook(FUNC, IRC, ...) ({                   \
> +       int RC = IRC;                                           \
> +       do {                                                    \
> +               struct security_hook_list *P;                   \
> +                                                               \
> +               hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
> +                       RC = P->hook.FUNC(__VA_ARGS__);         \
> +                       break;                                  \
> +               }                                               \
> +       } while (0);                                            \
> +       RC;                                                     \
> +})
> +
>  /* Security operations */
>
>  int security_binder_set_context_mgr(struct task_struct *mgr)
> @@ -1951,7 +1974,8 @@ EXPORT_SYMBOL(security_ismaclabel);
>
>  int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
>  {
> -       return call_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata, seclen);
> +       return call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata,
> +                                seclen);
>  }
>  EXPORT_SYMBOL(security_secid_to_secctx);
>
> @@ -1959,13 +1983,13 @@ int security_secctx_to_secid(const char *secdata, u32 seclen,
>                              struct lsm_export *l)
>  {
>         lsm_export_init(l);
> -       return call_int_hook(secctx_to_secid, 0, secdata, seclen, l);
> +       return call_one_int_hook(secctx_to_secid, 0, secdata, seclen, l);
>  }
>  EXPORT_SYMBOL(security_secctx_to_secid);
>
>  void security_release_secctx(char *secdata, u32 seclen)
>  {
> -       call_void_hook(release_secctx, secdata, seclen);
> +       call_one_void_hook(release_secctx, secdata, seclen);
>  }
>  EXPORT_SYMBOL(security_release_secctx);
>
> @@ -2090,7 +2114,7 @@ EXPORT_SYMBOL(security_sock_rcv_skb);
>  int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
>                                       int __user *optlen, unsigned len)
>  {
> -       return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
> +       return call_one_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
>                                 optval, optlen, len);
>  }
>
> --
> 2.19.1
>

Shouldn't dentry_init_security() use call_one_int_hook() as well? It
also returns a context string.

Thanks,
diff mbox series

Patch

diff --git a/security/security.c b/security/security.c
index 69983ad68233..365970f2501d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -698,6 +698,16 @@  int lsm_superblock_alloc(struct super_block *sb)
 			P->hook.FUNC(__VA_ARGS__);		\
 	} while (0)
 
+#define call_one_void_hook(FUNC, ...)				\
+	do {							\
+		struct security_hook_list *P;			\
+								\
+		hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
+			P->hook.FUNC(__VA_ARGS__);		\
+			break;					\
+		}						\
+	} while (0)
+
 #define call_int_hook(FUNC, IRC, ...) ({			\
 	int RC = IRC;						\
 	do {							\
@@ -712,6 +722,19 @@  int lsm_superblock_alloc(struct super_block *sb)
 	RC;							\
 })
 
+#define call_one_int_hook(FUNC, IRC, ...) ({			\
+	int RC = IRC;						\
+	do {							\
+		struct security_hook_list *P;			\
+								\
+		hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
+			RC = P->hook.FUNC(__VA_ARGS__);		\
+			break;					\
+		}						\
+	} while (0);						\
+	RC;							\
+})
+
 /* Security operations */
 
 int security_binder_set_context_mgr(struct task_struct *mgr)
@@ -1951,7 +1974,8 @@  EXPORT_SYMBOL(security_ismaclabel);
 
 int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
 {
-	return call_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata, seclen);
+	return call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata,
+				 seclen);
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
@@ -1959,13 +1983,13 @@  int security_secctx_to_secid(const char *secdata, u32 seclen,
 			     struct lsm_export *l)
 {
 	lsm_export_init(l);
-	return call_int_hook(secctx_to_secid, 0, secdata, seclen, l);
+	return call_one_int_hook(secctx_to_secid, 0, secdata, seclen, l);
 }
 EXPORT_SYMBOL(security_secctx_to_secid);
 
 void security_release_secctx(char *secdata, u32 seclen)
 {
-	call_void_hook(release_secctx, secdata, seclen);
+	call_one_void_hook(release_secctx, secdata, seclen);
 }
 EXPORT_SYMBOL(security_release_secctx);
 
@@ -2090,7 +2114,7 @@  EXPORT_SYMBOL(security_sock_rcv_skb);
 int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
 				      int __user *optlen, unsigned len)
 {
-	return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
+	return call_one_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
 				optval, optlen, len);
 }