KTD LSM: BuildKit LSM setxattr handling

Add counter to track the number of setxattr invocations.
Do not unilaterally block setxattr operations for the 'csm' attribute.

Kernel internal calls to setxattr can occur during some FS operations.
In particular, overlayfs copy-up operations. Blocking the write causes
the operation to fail and that will cause legitimate user programs
to break, e.g. 'docker build' with BuildKit enabled.

BUG=b/227623354
SOURCE=KTD

cos-patch: bug

Signed-off-by: Ken Hofsass <hofsass@google.com>
Change-Id: Ic5ca0d96983abd70c3a405655f29ed4258582687
Reviewed-on: https://cos-review.googlesource.com/c/third_party/kernel/+/33122
Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Main-Branch-Verified: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Reviewed-by: Oleksandr Tymoshenko <ovt@google.com>
Reviewed-on: https://cos-review.googlesource.com/c/third_party/kernel/+/33230
Reviewed-by: Roy Yang <royyang@google.com>
diff --git a/security/container/monitor.c b/security/container/monitor.c
index 63b6a66..21c928e 100644
--- a/security/container/monitor.c
+++ b/security/container/monitor.c
@@ -18,6 +18,8 @@
 #include <linux/seq_file.h>
 #include <linux/string.h>
 #include <linux/sysctl.h>
+#include <overlayfs/overlayfs.h>
+#include <uapi/linux/magic.h>
 
 /* protects csm_*_enabled and configurations. */
 DECLARE_RWSEM(csm_rwsem_config);
@@ -43,6 +45,7 @@
 	{ "EventWritingFailed", &csm_stats.event_writing_failed },
 	{ "SizePickingFailed", &csm_stats.size_picking_failed },
 	{ "PipeAlreadyOpened", &csm_stats.pipe_already_opened },
+	{ "CsmSetxattr", &csm_stats.csm_setxattr },
 };
 
 /*
@@ -622,11 +625,29 @@
 	.release	= single_release,
 };
 
+static bool is_d_overlayfs_mounted(struct dentry *dentry)
+{
+	struct super_block *mnt_sb;
+
+	if (dentry == NULL || dentry->d_inode == NULL)
+		return false;
+
+	mnt_sb = dentry->d_inode->i_sb;
+	if (mnt_sb == NULL || mnt_sb->s_magic != OVERLAYFS_SUPER_MAGIC)
+		return false;
+
+	return true;
+}
+
 static int csm_setxattr(struct dentry *dentry, const char *name,
 			const void *value, size_t size, int flags)
 {
-	if (csm_enabled && !strcmp(name, XATTR_SECURITY_CSM))
-		return -EPERM;
+	if (csm_enabled &&
+	    (audit_get_contid(current) != AUDIT_CID_UNSET) &&
+	    is_d_overlayfs_mounted(dentry) &&
+	    (strcmp(name, XATTR_SECURITY_CSM) == 0))
+		csm_stats.csm_setxattr++;
+
 	return 0;
 }
 
diff --git a/security/container/monitor.h b/security/container/monitor.h
index 221d7f5..654a808 100644
--- a/security/container/monitor.h
+++ b/security/container/monitor.h
@@ -55,6 +55,7 @@
 	size_t workqueue_failed;
 	size_t size_picking_failed;
 	size_t pipe_already_opened;
+	size_t csm_setxattr;
 };
 
 extern struct container_stats csm_stats;