Linux Security Modules development
 help / color / mirror / Atom feed
* [PATCH 02/11] quota: reorder capability check last
@ 2024-11-25 10:39 Christian Göttsche
  2024-11-25 10:39 ` [PATCH 03/11] ext4: " Christian Göttsche
                   ` (9 more replies)
  0 siblings, 10 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:39 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Jan Kara, Serge Hallyn, Julia Lawall,
	Nicolas Palix, linux-kernel, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 fs/quota/dquot.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 3dd8d6f27725..a2dddffeaac5 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1281,9 +1281,9 @@ static int ignore_hardlimit(struct dquot *dquot)
 {
 	struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
 
-	return capable(CAP_SYS_RESOURCE) &&
-	       (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
-		!(info->dqi_flags & DQF_ROOT_SQUASH));
+	return (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
+		!(info->dqi_flags & DQF_ROOT_SQUASH)) &&
+		capable(CAP_SYS_RESOURCE);
 }
 
 static int dquot_add_inodes(struct dquot *dquot, qsize_t inodes,
-- 
2.45.2


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

* [PATCH 03/11] ext4: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
@ 2024-11-25 10:39 ` Christian Göttsche
  2024-11-25 10:39 ` [PATCH 04/11] hugetlbfs: " Christian Göttsche
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:39 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Theodore Ts'o, Andreas Dilger,
	Serge Hallyn, Julia Lawall, Nicolas Palix, linux-kernel,
	linux-ext4, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 fs/ext4/balloc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 8042ad873808..c48fd36b2d74 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -649,8 +649,8 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi,
 	/* Hm, nope.  Are (enough) root reserved clusters available? */
 	if (uid_eq(sbi->s_resuid, current_fsuid()) ||
 	    (!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) && in_group_p(sbi->s_resgid)) ||
-	    capable(CAP_SYS_RESOURCE) ||
-	    (flags & EXT4_MB_USE_ROOT_BLOCKS)) {
+	    (flags & EXT4_MB_USE_ROOT_BLOCKS) ||
+	    capable(CAP_SYS_RESOURCE)) {
 
 		if (free_clusters >= (nclusters + dirty_clusters +
 				      resv_clusters))
-- 
2.45.2


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

* [PATCH 04/11] hugetlbfs: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
  2024-11-25 10:39 ` [PATCH 03/11] ext4: " Christian Göttsche
@ 2024-11-25 10:39 ` Christian Göttsche
  2024-11-25 10:39 ` [PATCH 05/11] genwqe: " Christian Göttsche
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:39 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Muchun Song, Serge Hallyn, Julia Lawall,
	Nicolas Palix, linux-kernel, linux-mm, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 fs/hugetlbfs/inode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index a4441fb77f7c..e4f6790c1638 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1508,7 +1508,7 @@ static int can_do_hugetlb_shm(void)
 {
 	kgid_t shm_group;
 	shm_group = make_kgid(&init_user_ns, sysctl_hugetlb_shm_group);
-	return capable(CAP_IPC_LOCK) || in_group_p(shm_group);
+	return in_group_p(shm_group) || capable(CAP_IPC_LOCK);
 }
 
 static int get_hstate_idx(int page_size_log)
-- 
2.45.2


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

* [PATCH 05/11] genwqe: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
  2024-11-25 10:39 ` [PATCH 03/11] ext4: " Christian Göttsche
  2024-11-25 10:39 ` [PATCH 04/11] hugetlbfs: " Christian Göttsche
@ 2024-11-25 10:39 ` Christian Göttsche
  2024-11-25 10:39 ` [PATCH 06/11] ubifs: " Christian Göttsche
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:39 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Frank Haverkamp, Arnd Bergmann,
	Greg Kroah-Hartman, Serge Hallyn, Julia Lawall, Nicolas Palix,
	linux-kernel, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 drivers/misc/genwqe/card_dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c
index 4441aca2280a..77b2d191d21c 100644
--- a/drivers/misc/genwqe/card_dev.c
+++ b/drivers/misc/genwqe/card_dev.c
@@ -461,7 +461,7 @@ static int genwqe_mmap(struct file *filp, struct vm_area_struct *vma)
 		goto free_dma_map;
 	}
 
-	if (capable(CAP_SYS_ADMIN) && (vsize > sizeof(dma_addr_t)))
+	if ((vsize > sizeof(dma_addr_t)) && capable(CAP_SYS_ADMIN))
 		*(dma_addr_t *)dma_map->k_vaddr = dma_map->dma_addr;
 
 	pfn = virt_to_phys(dma_map->k_vaddr) >> PAGE_SHIFT;
-- 
2.45.2


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

* [PATCH 06/11] ubifs: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (2 preceding siblings ...)
  2024-11-25 10:39 ` [PATCH 05/11] genwqe: " Christian Göttsche
@ 2024-11-25 10:39 ` Christian Göttsche
  2024-11-25 11:10   ` Liviu Dudau
  2024-11-25 11:30   ` Richard Weinberger
  2024-11-25 10:39 ` [PATCH 07/11] ipv4: " Christian Göttsche
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:39 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Boris Brezillon, Steven Price,
	Liviu Dudau, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Richard Weinberger, Zhihao Cheng,
	Serge Hallyn, Julia Lawall, Nicolas Palix, linux-kernel,
	dri-devel, linux-mtd, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 drivers/gpu/drm/panthor/panthor_drv.c | 2 +-
 fs/ubifs/budget.c                     | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index ac7e53f6e3f0..2de0c3627fbf 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -791,7 +791,7 @@ static int group_priority_permit(struct drm_file *file,
 		return 0;
 
 	/* Higher priorities require CAP_SYS_NICE or DRM_MASTER */
-	if (capable(CAP_SYS_NICE) || drm_is_current_master(file))
+	if (drm_is_current_master(file) || capable(CAP_SYS_NICE))
 		return 0;
 
 	return -EACCES;
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index d76eb7b39f56..6137aeadec3f 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -256,8 +256,9 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs)
  */
 static int can_use_rp(struct ubifs_info *c)
 {
-	if (uid_eq(current_fsuid(), c->rp_uid) || capable(CAP_SYS_RESOURCE) ||
-	    (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)))
+	if (uid_eq(current_fsuid(), c->rp_uid) ||
+	    (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)) ||
+	    capable(CAP_SYS_RESOURCE))
 		return 1;
 	return 0;
 }
-- 
2.45.2


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

* [PATCH 07/11] ipv4: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (3 preceding siblings ...)
  2024-11-25 10:39 ` [PATCH 06/11] ubifs: " Christian Göttsche
@ 2024-11-25 10:39 ` Christian Göttsche
  2024-11-26  8:01   ` Paolo Abeni
  2024-11-25 10:40 ` [PATCH 08/11] gfs2: " Christian Göttsche
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:39 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Eric Dumazet, David S. Miller,
	David Ahern, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Serge Hallyn, Julia Lawall, Nicolas Palix, linux-kernel, netdev,
	cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 net/ipv4/tcp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0d704bda6c41..bd3d7a3d6655 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3406,8 +3406,8 @@ EXPORT_SYMBOL(tcp_disconnect);
 
 static inline bool tcp_can_repair_sock(const struct sock *sk)
 {
-	return sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) &&
-		(sk->sk_state != TCP_LISTEN);
+	return (sk->sk_state != TCP_LISTEN) &&
+	       sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN);
 }
 
 static int tcp_repair_set_window(struct tcp_sock *tp, sockptr_t optbuf, int len)
-- 
2.45.2


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

* [PATCH 08/11] gfs2: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (4 preceding siblings ...)
  2024-11-25 10:39 ` [PATCH 07/11] ipv4: " Christian Göttsche
@ 2024-11-25 10:40 ` Christian Göttsche
  2024-11-25 11:34   ` Andreas Gruenbacher
  2024-11-25 10:40 ` [PATCH 09/11] fs: " Christian Göttsche
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:40 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Andreas Gruenbacher, Serge Hallyn,
	Julia Lawall, Nicolas Palix, linux-kernel, gfs2, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 fs/gfs2/quota.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index f462d9cb3087..988f38dc5b2c 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -44,8 +44,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip,
 	int ret;
 
 	ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */
-	if (capable(CAP_SYS_RESOURCE) ||
-	    sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF ||
+	    capable(CAP_SYS_RESOURCE))
 		return 0;
 	ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (ret)
-- 
2.45.2


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

* [PATCH 09/11] fs: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (5 preceding siblings ...)
  2024-11-25 10:40 ` [PATCH 08/11] gfs2: " Christian Göttsche
@ 2024-11-25 10:40 ` Christian Göttsche
  2024-11-25 12:17   ` Christian Brauner
  2024-11-25 10:40 ` [PATCH 10/11] skbuff: " Christian Göttsche
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:40 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Chuck Lever, Jeff Layton, Amir Goldstein,
	Alexander Viro, Christian Brauner, Jan Kara, Serge Hallyn,
	Julia Lawall, Nicolas Palix, linux-kernel, linux-fsdevel,
	linux-nfs, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 fs/fhandle.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/fhandle.c b/fs/fhandle.c
index 5f801139358e..01b3e14e07de 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -265,9 +265,9 @@ static inline bool may_decode_fh(struct handle_to_path_ctx *ctx,
 	if (ns_capable(root->mnt->mnt_sb->s_user_ns, CAP_SYS_ADMIN))
 		ctx->flags = HANDLE_CHECK_PERMS;
 	else if (is_mounted(root->mnt) &&
+		 !has_locked_children(real_mount(root->mnt), root->dentry) &&
 		 ns_capable(real_mount(root->mnt)->mnt_ns->user_ns,
-			    CAP_SYS_ADMIN) &&
-		 !has_locked_children(real_mount(root->mnt), root->dentry))
+			    CAP_SYS_ADMIN))
 		ctx->flags = HANDLE_CHECK_PERMS | HANDLE_CHECK_SUBTREE;
 	else
 		return false;
-- 
2.45.2


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

* [PATCH 10/11] skbuff: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (6 preceding siblings ...)
  2024-11-25 10:40 ` [PATCH 09/11] fs: " Christian Göttsche
@ 2024-11-25 10:40 ` Christian Göttsche
  2024-11-25 10:40 ` [PATCH 11/11] infiniband: " Christian Göttsche
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
  9 siblings, 0 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:40 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Serge Hallyn,
	Julia Lawall, Nicolas Palix, Mina Almasry, Willem de Bruijn,
	Pavel Begunkov, Lorenzo Bianconi, Sebastian Andrzej Siewior,
	Liang Chen, Alexander Lobakin, linux-kernel, netdev, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 net/core/skbuff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6841e61a6bd0..8bf622744862 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1656,7 +1656,7 @@ int mm_account_pinned_pages(struct mmpin *mmp, size_t size)
 	unsigned long max_pg, num_pg, new_pg, old_pg, rlim;
 	struct user_struct *user;
 
-	if (capable(CAP_IPC_LOCK) || !size)
+	if (!size || capable(CAP_IPC_LOCK))
 		return 0;
 
 	rlim = rlimit(RLIMIT_MEMLOCK);
-- 
2.45.2


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

* [PATCH 11/11] infiniband: reorder capability check last
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (7 preceding siblings ...)
  2024-11-25 10:40 ` [PATCH 10/11] skbuff: " Christian Göttsche
@ 2024-11-25 10:40 ` Christian Göttsche
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
  9 siblings, 0 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:40 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Leon Romanovsky, Jason Gunthorpe,
	Serge Hallyn, Julia Lawall, Nicolas Palix, linux-kernel,
	linux-rdma, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 drivers/infiniband/hw/mlx5/devx.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c
index 4186884c66e1..39304cae5b10 100644
--- a/drivers/infiniband/hw/mlx5/devx.c
+++ b/drivers/infiniband/hw/mlx5/devx.c
@@ -136,12 +136,14 @@ int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
 		return -EINVAL;
 
 	uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx);
-	if (is_user && capable(CAP_NET_RAW) &&
-	    (MLX5_CAP_GEN(dev->mdev, uctx_cap) & MLX5_UCTX_CAP_RAW_TX))
+	if (is_user &&
+	    (MLX5_CAP_GEN(dev->mdev, uctx_cap) & MLX5_UCTX_CAP_RAW_TX) &&
+	    capable(CAP_NET_RAW))
 		cap |= MLX5_UCTX_CAP_RAW_TX;
-	if (is_user && capable(CAP_SYS_RAWIO) &&
+	if (is_user &&
 	    (MLX5_CAP_GEN(dev->mdev, uctx_cap) &
-	     MLX5_UCTX_CAP_INTERNAL_DEV_RES))
+	     MLX5_UCTX_CAP_INTERNAL_DEV_RES) &&
+	    capable(CAP_SYS_RAWIO))
 		cap |= MLX5_UCTX_CAP_INTERNAL_DEV_RES;
 
 	MLX5_SET(create_uctx_in, in, opcode, MLX5_CMD_OP_CREATE_UCTX);
-- 
2.45.2


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

* [PATCH 01/11] coccinelle: Add script to reorder capable() calls
  2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
                   ` (8 preceding siblings ...)
  2024-11-25 10:40 ` [PATCH 11/11] infiniband: " Christian Göttsche
@ 2024-11-25 10:40 ` Christian Göttsche
  2024-11-25 17:48   ` [cocci] " Markus Elfring
                     ` (4 more replies)
  9 siblings, 5 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 10:40 UTC (permalink / raw)
  To: linux-security-module
  Cc: Christian Göttsche, Serge Hallyn, Julia Lawall,
	Nicolas Palix, linux-kernel, cocci

From: Christian Göttsche <cgzones@googlemail.com>

capable() calls refer to enabled LSMs whether to permit or deny the
request.  This is relevant in connection with SELinux, where a
capability check results in a policy decision and by default a denial
message on insufficient permission is issued.
It can lead to three undesired cases:
  1. A denial message is generated, even in case the operation was an
     unprivileged one and thus the syscall succeeded, creating noise.
  2. To avoid the noise from 1. the policy writer adds a rule to ignore
     those denial messages, hiding future syscalls, where the task
     performs an actual privileged operation, leading to hidden limited
     functionality of that task.
  3. To avoid the noise from 1. the policy writer adds a rule to permit
     the task the requested capability, while it does not need it,
     violating the principle of least privilege.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 MAINTAINERS                                |  1 +
 scripts/coccinelle/api/capable_order.cocci | 98 ++++++++++++++++++++++
 2 files changed, 99 insertions(+)
 create mode 100644 scripts/coccinelle/api/capable_order.cocci

diff --git a/MAINTAINERS b/MAINTAINERS
index e7f017097701..ab5ea47b61e2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5106,6 +5106,7 @@ S:	Supported
 F:	include/linux/capability.h
 F:	include/uapi/linux/capability.h
 F:	kernel/capability.c
+F:	scripts/coccinelle/api/capable_order.cocci
 F:	security/commoncap.c
 
 CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
diff --git a/scripts/coccinelle/api/capable_order.cocci b/scripts/coccinelle/api/capable_order.cocci
new file mode 100644
index 000000000000..4150d91b0f33
--- /dev/null
+++ b/scripts/coccinelle/api/capable_order.cocci
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Checks for capable() calls of the left side of a binary expression.
+/// Reordering might avoid needless checks, LSM log messages, and more
+/// restrictive LSM security policies (e.g. SELinux).
+/// Can report false positives if the righthand side contains a nested
+/// capability check or has side effects.
+///
+// Confidence: Moderate
+// Copyright: (C) 2024 Christian Göttsche.
+// Options: --no-includes --include-headers
+// Keywords: capable, ns_capable, sockopt_ns_capable
+//
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  Pattern to ignore
+//----------------------------------------------------------
+
+@ignore@
+identifier F1 = { capable, ns_capable, sockopt_ns_capable };
+identifier F2 = { capable, ns_capable, sockopt_ns_capable };
+binary operator op,op1,op2;
+expression E;
+position p;
+@@
+
+(
+F1@p(...) op F2(...)
+|
+E op1 F1@p(...) op2 F2(...)
+)
+
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+@ depends on patch@
+identifier F = { capable, ns_capable, sockopt_ns_capable };
+binary operator op,op1,op2;
+expression E,E1,E2;
+expression list EL;
+position p != ignore.p;
+@@
+
+(
+-  F@p(EL) op E
++  E op F(EL)
+|
+-  E1 op1 F@p(EL) op2 E2
++  E1 op1 E2 op2 F(EL)
+)
+
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+@r1 depends on !patch exists@
+identifier F = { capable, ns_capable, sockopt_ns_capable };
+binary operator op,op1,op2;
+expression E, E1, E2;
+position p != ignore.p;
+@@
+
+(
+*  F@p(...) op E
+|
+*  E1 op1 F@p(...) op2 E2
+)
+
+
+//----------------------------------------------------------
+//  For org mode
+//----------------------------------------------------------
+
+@script:python depends on org@
+p << r1.p;
+@@
+
+cocci.print_main("WARNING opportunity for capable reordering",p)
+
+
+//----------------------------------------------------------
+//  For report mode
+//----------------------------------------------------------
+
+@script:python depends on report@
+p << r1.p;
+@@
+
+msg = "WARNING opportunity for capable reordering"
+coccilib.report.print_report(p[0], msg)
-- 
2.45.2


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

* Re: [PATCH 06/11] ubifs: reorder capability check last
  2024-11-25 10:39 ` [PATCH 06/11] ubifs: " Christian Göttsche
@ 2024-11-25 11:10   ` Liviu Dudau
  2024-11-25 11:30   ` Richard Weinberger
  1 sibling, 0 replies; 22+ messages in thread
From: Liviu Dudau @ 2024-11-25 11:10 UTC (permalink / raw)
  To: cgzones
  Cc: linux-security-module, Boris Brezillon, Steven Price,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Richard Weinberger, Zhihao Cheng, Serge Hallyn,
	Julia Lawall, Nicolas Palix, linux-kernel, dri-devel, linux-mtd,
	cocci

Hi Christian,

On Mon, Nov 25, 2024 at 11:39:58AM +0100, Christian Göttsche wrote:
> From: Christian Göttsche <cgzones@googlemail.com>
> 
> capable() calls refer to enabled LSMs whether to permit or deny the
> request.  This is relevant in connection with SELinux, where a
> capability check results in a policy decision and by default a denial
> message on insufficient permission is issued.
> It can lead to three undesired cases:
>   1. A denial message is generated, even in case the operation was an
>      unprivileged one and thus the syscall succeeded, creating noise.
>   2. To avoid the noise from 1. the policy writer adds a rule to ignore
>      those denial messages, hiding future syscalls, where the task
>      performs an actual privileged operation, leading to hidden limited
>      functionality of that task.
>   3. To avoid the noise from 1. the policy writer adds a rule to permit
>      the task the requested capability, while it does not need it,
>      violating the principle of least privilege.
> 
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  drivers/gpu/drm/panthor/panthor_drv.c | 2 +-
>  fs/ubifs/budget.c                     | 5 +++--
>  2 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
> index ac7e53f6e3f0..2de0c3627fbf 100644
> --- a/drivers/gpu/drm/panthor/panthor_drv.c
> +++ b/drivers/gpu/drm/panthor/panthor_drv.c
> @@ -791,7 +791,7 @@ static int group_priority_permit(struct drm_file *file,
>  		return 0;
>  
>  	/* Higher priorities require CAP_SYS_NICE or DRM_MASTER */
> -	if (capable(CAP_SYS_NICE) || drm_is_current_master(file))
> +	if (drm_is_current_master(file) || capable(CAP_SYS_NICE))
>  		return 0;
>  
>  	return -EACCES;

Can the patch above be split into a separate one? It's for a different subsystem than ubifs.

Otherwise, it looks good to me, so you can add my Reviewed-by to the new patch.

Best regards,
Liviu

> diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
> index d76eb7b39f56..6137aeadec3f 100644
> --- a/fs/ubifs/budget.c
> +++ b/fs/ubifs/budget.c
> @@ -256,8 +256,9 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs)
>   */
>  static int can_use_rp(struct ubifs_info *c)
>  {
> -	if (uid_eq(current_fsuid(), c->rp_uid) || capable(CAP_SYS_RESOURCE) ||
> -	    (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)))
> +	if (uid_eq(current_fsuid(), c->rp_uid) ||
> +	    (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)) ||
> +	    capable(CAP_SYS_RESOURCE))
>  		return 1;
>  	return 0;
>  }
> -- 
> 2.45.2
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯

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

* Re: [PATCH 06/11] ubifs: reorder capability check last
  2024-11-25 10:39 ` [PATCH 06/11] ubifs: " Christian Göttsche
  2024-11-25 11:10   ` Liviu Dudau
@ 2024-11-25 11:30   ` Richard Weinberger
  2024-11-25 11:48     ` Christian Göttsche
  1 sibling, 1 reply; 22+ messages in thread
From: Richard Weinberger @ 2024-11-25 11:30 UTC (permalink / raw)
  To: cgzones
  Cc: LSM, Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, chengzhihao1, Serge E. Hallyn, Julia Lawall,
	Nicolas Palix, linux-kernel, DRI mailing list, linux-mtd, cocci

----- Ursprüngliche Mail -----
> Von: "Christian Göttsche" <cgoettsche@seltendoof.de>
> capable() calls refer to enabled LSMs whether to permit or deny the
> request.  This is relevant in connection with SELinux, where a
> capability check results in a policy decision and by default a denial
> message on insufficient permission is issued.
> It can lead to three undesired cases:
>  1. A denial message is generated, even in case the operation was an
>     unprivileged one and thus the syscall succeeded, creating noise.
>  2. To avoid the noise from 1. the policy writer adds a rule to ignore
>     those denial messages, hiding future syscalls, where the task
>     performs an actual privileged operation, leading to hidden limited
>     functionality of that task.
>  3. To avoid the noise from 1. the policy writer adds a rule to permit
>     the task the requested capability, while it does not need it,
>     violating the principle of least privilege.
> 
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
> drivers/gpu/drm/panthor/panthor_drv.c | 2 +-

This change is unrelated, please remove it.

> fs/ubifs/budget.c                     | 5 +++--
> 2 files changed, 4 insertions(+), 3 deletions(-)

[...]

> diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
> index d76eb7b39f56..6137aeadec3f 100644
> --- a/fs/ubifs/budget.c
> +++ b/fs/ubifs/budget.c
> @@ -256,8 +256,9 @@ long long ubifs_calc_available(const struct ubifs_info *c,
> int min_idx_lebs)
>  */
> static int can_use_rp(struct ubifs_info *c)
> {
> -	if (uid_eq(current_fsuid(), c->rp_uid) || capable(CAP_SYS_RESOURCE) ||
> -	    (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)))
> +	if (uid_eq(current_fsuid(), c->rp_uid) ||
> +	    (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)) ||
> +	    capable(CAP_SYS_RESOURCE))
> 		return 1;
> 	return 0;
> }

The UBIFS part looks ok:

Acked-by: Richard Weinberger <richard@nod.at>

Since I was not CC'ed to the whole series, I miss a lot of context.
Will this series merged as a whole? By whom?

Thanks,
//richard

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

* Re: [PATCH 08/11] gfs2: reorder capability check last
  2024-11-25 10:40 ` [PATCH 08/11] gfs2: " Christian Göttsche
@ 2024-11-25 11:34   ` Andreas Gruenbacher
  0 siblings, 0 replies; 22+ messages in thread
From: Andreas Gruenbacher @ 2024-11-25 11:34 UTC (permalink / raw)
  To: cgzones
  Cc: linux-security-module, Serge Hallyn, Julia Lawall, Nicolas Palix,
	linux-kernel, gfs2, cocci

On Mon, Nov 25, 2024 at 11:46 AM Christian Göttsche
<cgoettsche@seltendoof.de> wrote:
> From: Christian Göttsche <cgzones@googlemail.com>
>
> capable() calls refer to enabled LSMs whether to permit or deny the
> request.  This is relevant in connection with SELinux, where a
> capability check results in a policy decision and by default a denial
> message on insufficient permission is issued.
> It can lead to three undesired cases:
>   1. A denial message is generated, even in case the operation was an
>      unprivileged one and thus the syscall succeeded, creating noise.
>   2. To avoid the noise from 1. the policy writer adds a rule to ignore
>      those denial messages, hiding future syscalls, where the task
>      performs an actual privileged operation, leading to hidden limited
>      functionality of that task.
>   3. To avoid the noise from 1. the policy writer adds a rule to permit
>      the task the requested capability, while it does not need it,
>      violating the principle of least privilege.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  fs/gfs2/quota.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
> index f462d9cb3087..988f38dc5b2c 100644
> --- a/fs/gfs2/quota.h
> +++ b/fs/gfs2/quota.h
> @@ -44,8 +44,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip,
>         int ret;
>
>         ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */
> -       if (capable(CAP_SYS_RESOURCE) ||
> -           sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
> +       if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF ||
> +           capable(CAP_SYS_RESOURCE))
>                 return 0;
>         ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
>         if (ret)
> --
> 2.45.2

Applied, thanks.

Andreas


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

* Re: [PATCH 06/11] ubifs: reorder capability check last
  2024-11-25 11:30   ` Richard Weinberger
@ 2024-11-25 11:48     ` Christian Göttsche
  0 siblings, 0 replies; 22+ messages in thread
From: Christian Göttsche @ 2024-11-25 11:48 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: LSM, Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, chengzhihao1, Serge E. Hallyn, Julia Lawall,
	Nicolas Palix, linux-kernel, DRI mailing list, linux-mtd, cocci

On Mon, 25 Nov 2024 at 12:31, Richard Weinberger <richard@nod.at> wrote:
>
> ----- Ursprüngliche Mail -----
> > Von: "Christian Göttsche" <cgoettsche@seltendoof.de>
> > capable() calls refer to enabled LSMs whether to permit or deny the
> > request.  This is relevant in connection with SELinux, where a
> > capability check results in a policy decision and by default a denial
> > message on insufficient permission is issued.
> > It can lead to three undesired cases:
> >  1. A denial message is generated, even in case the operation was an
> >     unprivileged one and thus the syscall succeeded, creating noise.
> >  2. To avoid the noise from 1. the policy writer adds a rule to ignore
> >     those denial messages, hiding future syscalls, where the task
> >     performs an actual privileged operation, leading to hidden limited
> >     functionality of that task.
> >  3. To avoid the noise from 1. the policy writer adds a rule to permit
> >     the task the requested capability, while it does not need it,
> >     violating the principle of least privilege.
> >
> > Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> > ---
> > drivers/gpu/drm/panthor/panthor_drv.c | 2 +-
>
> This change is unrelated, please remove it.

Sorry, somehow these two changes got erroneously combined in a single patch.
I'll send a v2 with them split into separate ones.

>
> > fs/ubifs/budget.c                     | 5 +++--
> > 2 files changed, 4 insertions(+), 3 deletions(-)
>
> [...]
>
> > diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
> > index d76eb7b39f56..6137aeadec3f 100644
> > --- a/fs/ubifs/budget.c
> > +++ b/fs/ubifs/budget.c
> > @@ -256,8 +256,9 @@ long long ubifs_calc_available(const struct ubifs_info *c,
> > int min_idx_lebs)
> >  */
> > static int can_use_rp(struct ubifs_info *c)
> > {
> > -     if (uid_eq(current_fsuid(), c->rp_uid) || capable(CAP_SYS_RESOURCE) ||
> > -         (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)))
> > +     if (uid_eq(current_fsuid(), c->rp_uid) ||
> > +         (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid)) ||
> > +         capable(CAP_SYS_RESOURCE))
> >               return 1;
> >       return 0;
> > }
>
> The UBIFS part looks ok:
>
> Acked-by: Richard Weinberger <richard@nod.at>
>
> Since I was not CC'ed to the whole series, I miss a lot of context.

The series consists of similar patches to other subsystems and a
coccinelle script addition.
See https://lore.kernel.org/linux-security-module/20241125104011.36552-11-cgoettsche@seltendoof.de/#t

> Will this series merged as a whole? By whom?
>
> Thanks,
> //richard

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

* Re: [PATCH 09/11] fs: reorder capability check last
  2024-11-25 10:40 ` [PATCH 09/11] fs: " Christian Göttsche
@ 2024-11-25 12:17   ` Christian Brauner
  0 siblings, 0 replies; 22+ messages in thread
From: Christian Brauner @ 2024-11-25 12:17 UTC (permalink / raw)
  To: cgzones
  Cc: linux-security-module, Chuck Lever, Jeff Layton, Amir Goldstein,
	Alexander Viro, Jan Kara, Serge Hallyn, Julia Lawall,
	Nicolas Palix, linux-kernel, linux-fsdevel, linux-nfs, cocci

On Mon, Nov 25, 2024 at 11:40:01AM +0100, Christian Göttsche wrote:
> From: Christian Göttsche <cgzones@googlemail.com>
> 
> capable() calls refer to enabled LSMs whether to permit or deny the
> request.  This is relevant in connection with SELinux, where a
> capability check results in a policy decision and by default a denial
> message on insufficient permission is issued.
> It can lead to three undesired cases:
>   1. A denial message is generated, even in case the operation was an
>      unprivileged one and thus the syscall succeeded, creating noise.
>   2. To avoid the noise from 1. the policy writer adds a rule to ignore
>      those denial messages, hiding future syscalls, where the task
>      performs an actual privileged operation, leading to hidden limited
>      functionality of that task.
>   3. To avoid the noise from 1. the policy writer adds a rule to permit
>      the task the requested capability, while it does not need it,
>      violating the principle of least privilege.
> 
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---

Reviewed-by: Christian Brauner <brauner@kernel.org>

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

* Re: [cocci] [PATCH 01/11] coccinelle: Add script to reorder capable() calls
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
@ 2024-11-25 17:48   ` Markus Elfring
  2024-11-26 12:55   ` Markus Elfring
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 22+ messages in thread
From: Markus Elfring @ 2024-11-25 17:48 UTC (permalink / raw)
  To: Christian Göttsche, linux-security-module, cocci,
	Julia Lawall, Nicolas Palix, Serge Hallyn
  Cc: Christian Göttsche, LKML> +++ b/scripts/coccinelle/api/capable_order.cocci
> @@ -0,0 +1,98 @@
> +@ignore@
> +identifier F1 = { capable, ns_capable, sockopt_ns_capable };
> +identifier F2 = { capable, ns_capable, sockopt_ns_capable };

May a key word repetition avoided here?

+identifier F1 = { capable, ns_capable, sockopt_ns_capable },
+           F2 = { capable, ns_capable, sockopt_ns_capable };


…
> +//----------------------------------------------------------
> +//  For patch mode
> +//----------------------------------------------------------

I suggest to omit such a comment.


> +@ depends on patch@
> +(
> +-  F@p(EL) op E
> ++  E op F(EL)
> +|
> +-  E1 op1 F@p(EL) op2 E2
> ++  E1 op1 E2 op2 F(EL)
> +)

How do you think about to omit extra space characters at the beginning
of any SmPL lines?


> +//----------------------------------------------------------
> +//  For context mode
> +//----------------------------------------------------------
> +
> +@r1 depends on !patch exists@

How good do the provided data fit to the operation modes “org” and “report”?


> +//----------------------------------------------------------
> +//  For org mode
> +//----------------------------------------------------------

I suggest to omit such a comment.

> +
> +@script:python depends on org@
> +p << r1.p;
> +@@
> +
> +cocci.print_main("WARNING opportunity for capable reordering",p)

How do you think about to use a statement like the following?

coccilib.org.print_todo(p[0], "WARNING: opportunity for reordering of capable() calls")


> +//----------------------------------------------------------
> +//  For report mode
> +//----------------------------------------------------------

I suggest to omit such a comment.


> +@script:python depends on report@
> +p << r1.p;
> +@@
> +
> +msg = "WARNING opportunity for capable reordering"
> +coccilib.report.print_report(p[0], msg)

Can the following code variant be a bit nicer?

coccilib.report.print_report(p[0], "WARNING: opportunity for reordering of capable() calls")


Regards,
Markus

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

* Re: [PATCH 07/11] ipv4: reorder capability check last
  2024-11-25 10:39 ` [PATCH 07/11] ipv4: " Christian Göttsche
@ 2024-11-26  8:01   ` Paolo Abeni
  0 siblings, 0 replies; 22+ messages in thread
From: Paolo Abeni @ 2024-11-26  8:01 UTC (permalink / raw)
  To: cgzones, linux-security-module
  Cc: Eric Dumazet, David S. Miller, David Ahern, Jakub Kicinski,
	Simon Horman, Serge Hallyn, Julia Lawall, Nicolas Palix,
	linux-kernel, netdev, cocci

On 11/25/24 11:39, Christian Göttsche wrote:
> capable() calls refer to enabled LSMs whether to permit or deny the
> request.  This is relevant in connection with SELinux, where a
> capability check results in a policy decision and by default a denial
> message on insufficient permission is issued.
> It can lead to three undesired cases:
>   1. A denial message is generated, even in case the operation was an
>      unprivileged one and thus the syscall succeeded, creating noise.
>   2. To avoid the noise from 1. the policy writer adds a rule to ignore
>      those denial messages, hiding future syscalls, where the task
>      performs an actual privileged operation, leading to hidden limited
>      functionality of that task.
>   3. To avoid the noise from 1. the policy writer adds a rule to permit
>      the task the requested capability, while it does not need it,
>      violating the principle of least privilege.
> 
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  net/ipv4/tcp.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 0d704bda6c41..bd3d7a3d6655 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -3406,8 +3406,8 @@ EXPORT_SYMBOL(tcp_disconnect);
>  
>  static inline bool tcp_can_repair_sock(const struct sock *sk)
>  {
> -	return sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) &&
> -		(sk->sk_state != TCP_LISTEN);
> +	return (sk->sk_state != TCP_LISTEN) &&
> +	       sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN);
>  }
>  
>  static int tcp_repair_set_window(struct tcp_sock *tp, sockptr_t optbuf, int len)

The code change IMHO makes sense, but the commit message looks quite
unrelated to this specific change, please re-word it describing this
change helps capability validation.

Additionally it looks the net patches don't depend on other patches in
this series, so it would simplify the merging if you would resubmit them
separately targeting the net-next tree explicitly (add 'net-next' in the
subj prefix).

Note that the net-next tree is currently closed for the merge window, it
will reopen around ~2 Dec.

Please have a look at:

https://elixir.bootlin.com/linux/v6.12/source/Documentation/process/maintainer-netdev.rst

for more details.

Thanks,

Paolo


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

* Re: [cocci] [PATCH 01/11] coccinelle: Add script to reorder capable() calls
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
  2024-11-25 17:48   ` [cocci] " Markus Elfring
@ 2024-11-26 12:55   ` Markus Elfring
  2024-11-27 11:45   ` Markus Elfring
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 22+ messages in thread
From: Markus Elfring @ 2024-11-26 12:55 UTC (permalink / raw)
  To: Christian Göttsche, linux-security-module, cocci,
	Julia Lawall, Nicolas Palix, Serge Hallyn
  Cc: Christian Göttsche, LKML> +(
> +-  F@p(EL) op E
> ++  E op F(EL)
> +|
> +-  E1 op1 F@p(EL) op2 E2
> ++  E1 op1 E2 op2 F(EL)
> +)

How do you think about to use an SmPL code variant like the following?

(
 E1 op1
-F@p(EL)
+E2
 op2
-E2
+F(EL)
|
-F@p(EL) op
 E
+op F(EL)
)


> +//----------------------------------------------------------
> +//  For context mode
> +//----------------------------------------------------------
> +
> +@r1 depends on !patch exists@
…

I would prefer the dependency specification “context” for this SmPL rule.
The SmPL asterisk functionality should be better distinguished here.


…
> +@script:python depends on org@
> +p << r1.p;
> +@@
…

I got the impression that source code search approaches can be safely
shared only between the operation modes “org” and “report” so far.

Regards,
Markus

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

* Re: [cocci] [PATCH 01/11] coccinelle: Add script to reorder capable() calls
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
  2024-11-25 17:48   ` [cocci] " Markus Elfring
  2024-11-26 12:55   ` Markus Elfring
@ 2024-11-27 11:45   ` Markus Elfring
  2024-11-29 12:38   ` Markus Elfring
  2024-11-30  4:08   ` Serge E. Hallyn
  4 siblings, 0 replies; 22+ messages in thread
From: Markus Elfring @ 2024-11-27 11:45 UTC (permalink / raw)
  To: Christian Göttsche, linux-security-module, cocci,
	Julia Lawall, Nicolas Palix, Serge Hallyn
  Cc: Christian Göttsche, LKML> +++ b/scripts/coccinelle/api/capable_order.cocci
> +@ depends on patch@
> +identifier F = { capable, ns_capable, sockopt_ns_capable };
> +binary operator op,op1,op2;
> +-  F@p(EL) op E
> ++  E op F(EL)
…


You would like to reorder expression parts.
How do you think about to increase the precision for such
an SmPL change specification?

* May only operators be taken into account for which
  the commutative property holds?

* Would you like to support a varying length for the affected
  operator chain (≥ 2 operands)?


Regards,
Markus

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

* Re: [cocci] [PATCH 01/11] coccinelle: Add script to reorder capable() calls
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
                     ` (2 preceding siblings ...)
  2024-11-27 11:45   ` Markus Elfring
@ 2024-11-29 12:38   ` Markus Elfring
  2024-11-30  4:08   ` Serge E. Hallyn
  4 siblings, 0 replies; 22+ messages in thread
From: Markus Elfring @ 2024-11-29 12:38 UTC (permalink / raw)
  To: Christian Göttsche, linux-security-module, cocci,
	Julia Lawall, Nicolas Palix, Serge Hallyn
  Cc: Christian Göttsche, LKML> +++ b/scripts/coccinelle/api/capable_order.cocci
> +@ depends on patch@
> +identifier F = { capable, ns_capable, sockopt_ns_capable };
> +binary operator op,op1,op2;
> +-  F@p(EL) op E
> ++  E op F(EL)
…

It can be amazing how many source code places can be handled by such
a transformation approach already.
I hope that corresponding data processing requirement analyses will trigger
further collateral evolution.
You propose to use the metavariable types “expression” and “binary operator”.
These filters have got the potential to match more source code than it would be
intended here.
The length of computations behind a selected operator is not really restricted.
Such expressions can probably contain varying operator chains.
There is a desire to split the affected code into subexpressions.
Special development challenges are involved accordingly.
I find it safer and more promising to use scripting interfaces for this use case.
https://gitlab.inria.fr/coccinelle/coccinelle/-/blob/620463b4bfb8bdc5c99dabfdfa337b34cbaa9ef1/docs/manual/cocci_syntax.tex#L655

Unfortunately, required programming interfaces (for OCaml and Python) probably
need significant improvements.

Regards,
Markus

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

* Re: [PATCH 01/11] coccinelle: Add script to reorder capable() calls
  2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
                     ` (3 preceding siblings ...)
  2024-11-29 12:38   ` Markus Elfring
@ 2024-11-30  4:08   ` Serge E. Hallyn
  4 siblings, 0 replies; 22+ messages in thread
From: Serge E. Hallyn @ 2024-11-30  4:08 UTC (permalink / raw)
  To: cgzones
  Cc: linux-security-module, Serge Hallyn, Julia Lawall, Nicolas Palix,
	linux-kernel, cocci

On Mon, Nov 25, 2024 at 11:40:04AM +0100, Christian Göttsche wrote:
> From: Christian Göttsche <cgzones@googlemail.com>
> 
> capable() calls refer to enabled LSMs whether to permit or deny the
> request.  This is relevant in connection with SELinux, where a
> capability check results in a policy decision and by default a denial
> message on insufficient permission is issued.
> It can lead to three undesired cases:
>   1. A denial message is generated, even in case the operation was an
>      unprivileged one and thus the syscall succeeded, creating noise.
>   2. To avoid the noise from 1. the policy writer adds a rule to ignore
>      those denial messages, hiding future syscalls, where the task
>      performs an actual privileged operation, leading to hidden limited
>      functionality of that task.
>   3. To avoid the noise from 1. the policy writer adds a rule to permit
>      the task the requested capability, while it does not need it,
>      violating the principle of least privilege.
> 
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Hi,

these all look good to me.

Reviewed-by: Serge Hallyn <serge@hallyn.com>

Except for, in fact, this patch, as I'm not versed in .cocci and
can't tell whether it's doing the right thing.  Looks like it is,
based on the patches you sent...

> ---
>  MAINTAINERS                                |  1 +
>  scripts/coccinelle/api/capable_order.cocci | 98 ++++++++++++++++++++++
>  2 files changed, 99 insertions(+)
>  create mode 100644 scripts/coccinelle/api/capable_order.cocci
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e7f017097701..ab5ea47b61e2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5106,6 +5106,7 @@ S:	Supported
>  F:	include/linux/capability.h
>  F:	include/uapi/linux/capability.h
>  F:	kernel/capability.c
> +F:	scripts/coccinelle/api/capable_order.cocci
>  F:	security/commoncap.c
>  
>  CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
> diff --git a/scripts/coccinelle/api/capable_order.cocci b/scripts/coccinelle/api/capable_order.cocci
> new file mode 100644
> index 000000000000..4150d91b0f33
> --- /dev/null
> +++ b/scripts/coccinelle/api/capable_order.cocci
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +///
> +/// Checks for capable() calls of the left side of a binary expression.
> +/// Reordering might avoid needless checks, LSM log messages, and more
> +/// restrictive LSM security policies (e.g. SELinux).
> +/// Can report false positives if the righthand side contains a nested
> +/// capability check or has side effects.
> +///
> +// Confidence: Moderate
> +// Copyright: (C) 2024 Christian Göttsche.
> +// Options: --no-includes --include-headers
> +// Keywords: capable, ns_capable, sockopt_ns_capable
> +//
> +
> +virtual patch
> +virtual context
> +virtual org
> +virtual report
> +
> +//----------------------------------------------------------
> +//  Pattern to ignore
> +//----------------------------------------------------------
> +
> +@ignore@
> +identifier F1 = { capable, ns_capable, sockopt_ns_capable };
> +identifier F2 = { capable, ns_capable, sockopt_ns_capable };
> +binary operator op,op1,op2;
> +expression E;
> +position p;
> +@@
> +
> +(
> +F1@p(...) op F2(...)
> +|
> +E op1 F1@p(...) op2 F2(...)
> +)
> +
> +
> +//----------------------------------------------------------
> +//  For patch mode
> +//----------------------------------------------------------
> +
> +@ depends on patch@
> +identifier F = { capable, ns_capable, sockopt_ns_capable };
> +binary operator op,op1,op2;
> +expression E,E1,E2;
> +expression list EL;
> +position p != ignore.p;
> +@@
> +
> +(
> +-  F@p(EL) op E
> ++  E op F(EL)
> +|
> +-  E1 op1 F@p(EL) op2 E2
> ++  E1 op1 E2 op2 F(EL)
> +)
> +
> +
> +//----------------------------------------------------------
> +//  For context mode
> +//----------------------------------------------------------
> +
> +@r1 depends on !patch exists@
> +identifier F = { capable, ns_capable, sockopt_ns_capable };
> +binary operator op,op1,op2;
> +expression E, E1, E2;
> +position p != ignore.p;
> +@@
> +
> +(
> +*  F@p(...) op E
> +|
> +*  E1 op1 F@p(...) op2 E2
> +)
> +
> +
> +//----------------------------------------------------------
> +//  For org mode
> +//----------------------------------------------------------
> +
> +@script:python depends on org@
> +p << r1.p;
> +@@
> +
> +cocci.print_main("WARNING opportunity for capable reordering",p)
> +
> +
> +//----------------------------------------------------------
> +//  For report mode
> +//----------------------------------------------------------
> +
> +@script:python depends on report@
> +p << r1.p;
> +@@
> +
> +msg = "WARNING opportunity for capable reordering"
> +coccilib.report.print_report(p[0], msg)
> -- 
> 2.45.2

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

end of thread, other threads:[~2024-11-30  4:08 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-25 10:39 [PATCH 02/11] quota: reorder capability check last Christian Göttsche
2024-11-25 10:39 ` [PATCH 03/11] ext4: " Christian Göttsche
2024-11-25 10:39 ` [PATCH 04/11] hugetlbfs: " Christian Göttsche
2024-11-25 10:39 ` [PATCH 05/11] genwqe: " Christian Göttsche
2024-11-25 10:39 ` [PATCH 06/11] ubifs: " Christian Göttsche
2024-11-25 11:10   ` Liviu Dudau
2024-11-25 11:30   ` Richard Weinberger
2024-11-25 11:48     ` Christian Göttsche
2024-11-25 10:39 ` [PATCH 07/11] ipv4: " Christian Göttsche
2024-11-26  8:01   ` Paolo Abeni
2024-11-25 10:40 ` [PATCH 08/11] gfs2: " Christian Göttsche
2024-11-25 11:34   ` Andreas Gruenbacher
2024-11-25 10:40 ` [PATCH 09/11] fs: " Christian Göttsche
2024-11-25 12:17   ` Christian Brauner
2024-11-25 10:40 ` [PATCH 10/11] skbuff: " Christian Göttsche
2024-11-25 10:40 ` [PATCH 11/11] infiniband: " Christian Göttsche
2024-11-25 10:40 ` [PATCH 01/11] coccinelle: Add script to reorder capable() calls Christian Göttsche
2024-11-25 17:48   ` [cocci] " Markus Elfring
2024-11-26 12:55   ` Markus Elfring
2024-11-27 11:45   ` Markus Elfring
2024-11-29 12:38   ` Markus Elfring
2024-11-30  4:08   ` Serge E. Hallyn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox