Skip to contentSkip to conversation

LSM: Support ptrace sidechannel access checks

PATCH In review Casey Schaufler 2 participants 7 messages Nov 5, 2018

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

v6 cover LSM: Support ptrace sidechannel access checks

V6: Based on Tim Chen's "[Patch v4 00/18] Provide process property
based options to enable Spectre v2 userspace-userspace protection*" patch set.
v5: Revamped to match Jiri Kosina <[email protected]>
Harden spectrev2 userspace-userspace protection v7
Fixed locking issues in the LSM code.
Dropped the new LSM hook and use a ptrace hook instead.
v4: select namespace checks if user namespaces are enabled
and credential checks are request.
v3: get_task_cred wasn't a good choice due to refcounts.
Use lower level protection instead
v2: SELinux access policy corrected.
Use real_cred instead of cred.

This patchset provide a mechanism by which a security module can advise the system about potential side-channel vulnerabilities. The existing security modules have been updated to avoid locking issues in the face of PTRACE_MODE_SCHED. A new security module is provided to make determinations regarding task attributes including namespaces.

---
 include/linux/lsm_hooks.h          |  5 +++
 kernel/ptrace.c                    |  2 -
 security/Kconfig                   |  1 +
 security/Makefile                  |  2 +
 security/apparmor/domain.c         |  2 +-
 security/apparmor/include/ipc.h    |  2 +-
 security/apparmor/ipc.c            |  8 ++--
 security/apparmor/lsm.c            |  5 ++-
 security/commoncap.c               |  3 +-
 security/security.c                |  1 +
 security/selinux/hooks.c           |  2 +
 security/sidechannel/Kconfig       | 13 ++++++
 security/sidechannel/Makefile      |  1 +
 security/sidechannel/sidechannel.c | 88 ++++++++++++++++++++++++++++++++++++++
 security/smack/smack_lsm.c         |  3 +-
 15 files changed, 127 insertions(+), 11 deletions(-)
#1 lore raw

PATCH v6 1/5 AppArmor: Prepare for PTRACE_MODE_SCHED

From: Casey Schaufler <[email protected]>

A ptrace access check with mode PTRACE_MODE_SCHED gets called from process switching code. This precludes the use of audit, as the locking is incompatible. Don't do audit in the PTRACE_MODE_SCHED case.

---
 security/apparmor/domain.c      | 2 +-
 security/apparmor/include/ipc.h | 2 +-
 security/apparmor/ipc.c         | 8 +++++---
 security/apparmor/lsm.c         | 5 +++--
 4 files changed, 10 insertions(+), 7 deletions(-)
security/apparmor/domain.c +1 -1
index 08c88de0ffda..28300f4c3ef9 100644
@@ -77,7 +77,7 @@ static int may_change_ptraced_domain(struct aa_label *to_label,
 	if (!tracer || unconfined(tracerl))
 		goto out;
 
-	error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
+	error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH, true);
 
 out:
 	rcu_read_unlock();
security/apparmor/include/ipc.h +1 -1
index 5ffc218d1e74..299d1c45fef0 100644
@@ -34,7 +34,7 @@ struct aa_profile;
 	"xcpu xfsz vtalrm prof winch io pwr sys emt lost"
 
 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
-		  u32 request);
+		  u32 request, bool audit);
 int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
 
 #endif /* __AA_IPC_H */
security/apparmor/ipc.c +5 -3
index 527ea1557120..9ed110afc822 100644
@@ -121,15 +121,17 @@ static int profile_tracer_perm(struct aa_profile *tracer,
  * Returns: %0 else error code if permission denied or error
  */
 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
-		  u32 request)
+		  u32 request, bool audit)
 {
 	struct aa_profile *profile;
 	u32 xrequest = request << PTRACE_PERM_SHIFT;
 	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
 
 	return xcheck_labels(tracer, tracee, profile,
-			profile_tracer_perm(profile, tracee, request, &sa),
-			profile_tracee_perm(profile, tracer, xrequest, &sa));
+			profile_tracer_perm(profile, tracee, request,
+					    audit ? &sa : NULL),
+			profile_tracee_perm(profile, tracer, xrequest,
+					    audit ? &sa : NULL));
 }
 
 
security/apparmor/lsm.c +3 -2
index 8b8b70620bbe..da9d0b228857 100644
@@ -118,7 +118,8 @@ static int apparmor_ptrace_access_check(struct task_struct *child,
 	tracee = aa_get_task_label(child);
 	error = aa_may_ptrace(tracer, tracee,
 			(mode & PTRACE_MODE_READ) ? AA_PTRACE_READ
-						  : AA_PTRACE_TRACE);
+						  : AA_PTRACE_TRACE,
+			!(mode & PTRACE_MODE_SCHED));
 	aa_put_label(tracee);
 	end_current_label_crit_section(tracer);
 
@@ -132,7 +133,7 @@ static int apparmor_ptrace_traceme(struct task_struct *parent)
 
 	tracee = begin_current_label_crit_section();
 	tracer = aa_get_task_label(parent);
-	error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
+	error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE, true);
 	aa_put_label(tracer);
 	end_current_label_crit_section(tracee);
 
Signature · 1 line
2.17.1
#2 lore raw

PATCH v6 2/5 Smack: Prepare for PTRACE_MODE_SCHED

In reply to Casey Schaufler

From: Casey Schaufler <[email protected]>

A ptrace access check with mode PTRACE_MODE_SCHED gets called from process switching code. This precludes the use of audit, as the locking is incompatible. Don't do audit in the PTRACE_MODE_SCHED case.

---
 security/smack/smack_lsm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
security/smack/smack_lsm.c +2 -1
index 340fc30ad85d..ffa95bcab599 100644
@@ -422,7 +422,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
 	struct task_smack *tsp;
 	struct smack_known *tracer_known;
 
-	if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
+	if ((mode & PTRACE_MODE_NOAUDIT) == 0 &&
+	    (mode & PTRACE_MODE_SCHED) == 0) {
 		smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
 		smk_ad_setfield_u_tsk(&ad, tracer);
 		saip = &ad;
Signature · 1 line
2.17.1
#3 lore raw

PATCH v6 3/5 SELinux: Prepare for PTRACE_MODE_SCHED

In reply to Casey Schaufler

From: Casey Schaufler <[email protected]>

A ptrace access check with mode PTRACE_MODE_SCHED gets called from process switching code. This precludes the use of audit or avc, as the locking is incompatible. The only available check that can be made without using avc is a comparison of the secids. This is not very satisfactory as it will indicate possible vulnerabilies much too aggressively.

---
 security/selinux/hooks.c | 2 ++
 1 file changed, 2 insertions(+)
security/selinux/hooks.c +2 -0
index ad9a9b8e9979..160239791007 100644
@@ -2267,6 +2267,8 @@ static int selinux_ptrace_access_check(struct task_struct *child,
 	u32 sid = current_sid();
 	u32 csid = task_sid(child);
 
+	if (mode & PTRACE_MODE_SCHED)
+		return sid == csid ? 0 : -EACCES;
 	if (mode & PTRACE_MODE_READ)
 		return avc_has_perm(&selinux_state,
 				    sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Signature · 1 line
2.17.1
#4 lore raw

PATCH v6 4/5 Capability: Complete PTRACE_MODE_SCHED

In reply to Casey Schaufler

From: Casey Schaufler <[email protected]>

Allow a complete ptrace access check with mode PTRACE_MODE_SCHED. Disable the inappropriate privilege check in the capability code that does incompatible locking.

---
 kernel/ptrace.c      | 2 --
 security/commoncap.c | 3 ++-
 2 files changed, 2 insertions(+), 3 deletions(-)
kernel/ptrace.c +0 -2
index 99cfddde6a55..0b6a9df51c3b 100644
@@ -331,8 +331,6 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 	     !ptrace_has_cap(mm->user_ns, mode)))
 	    return -EPERM;
 
-	if (mode & PTRACE_MODE_SCHED)
-		return 0;
 	return security_ptrace_access_check(task, mode);
 }
 
security/commoncap.c +2 -1
index 2e489d6a3ac8..70a7e3d19c16 100644
@@ -152,7 +152,8 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
 	if (cred->user_ns == child_cred->user_ns &&
 	    cap_issubset(child_cred->cap_permitted, *caller_caps))
 		goto out;
-	if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
+	if (!(mode & PTRACE_MODE_SCHED) &&
+	    ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
 		goto out;
 	ret = -EPERM;
 out:
Signature · 1 line
2.17.1
#5 lore raw

PATCH v6 5/5 sidechannel: Linux Security Module for sidechannel

In reply to Casey Schaufler

From: Casey Schaufler <[email protected]>

This is a new Linux Security Module (LSM) that checks for potential sidechannel issues that are not covered in the ptrace PTRACE_MODE_SCHED option. Namespace differences are checked in this intitial version. Additional checks should be added when they are determined to be useful.

---
 include/linux/lsm_hooks.h          |  5 ++
 security/Kconfig                   |  1 +
 security/Makefile                  |  2 +
 security/security.c                |  1 +
 security/sidechannel/Kconfig       | 13 +++++
 security/sidechannel/Makefile      |  1 +
 security/sidechannel/sidechannel.c | 88 ++++++++++++++++++++++++++++++
 7 files changed, 111 insertions(+)
 create mode 100644 security/sidechannel/Kconfig
 create mode 100644 security/sidechannel/Makefile
 create mode 100644 security/sidechannel/sidechannel.c
include/linux/lsm_hooks.h +5 -0
index 97a020c616ad..3cb6516dba3c 100644
@@ -2081,5 +2081,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_SIDECHANNEL
+void __init sidechannel_add_hooks(void);
+#else
+static inline void sidechannel_add_hooks(void) { };
+#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
security/Kconfig +1 -0
index d9aa521b5206..6b814a3f93ea 100644
@@ -236,6 +236,7 @@ source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/loadpin/Kconfig
 source security/yama/Kconfig
+source security/sidechannel/Kconfig
 
 source security/integrity/Kconfig
 
security/Makefile +2 -0
index 4d2d3782ddef..d0c9e1b227f9 100644
@@ -10,6 +10,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR)	+= apparmor
 subdir-$(CONFIG_SECURITY_YAMA)		+= yama
 subdir-$(CONFIG_SECURITY_LOADPIN)	+= loadpin
+subdir-$(CONFIG_SECURITY_SIDECHANNEL)	+= sidechannel
 
 # always enable default capabilities
 obj-y					+= commoncap.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/
 obj-$(CONFIG_SECURITY_APPARMOR)		+= apparmor/
 obj-$(CONFIG_SECURITY_YAMA)		+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN)		+= loadpin/
+obj-$(CONFIG_SECURITY_SIDECHANNEL)	+= sidechannel/
 obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
 
 # Object integrity file lists
security/security.c +1 -0
index 12460f20c652..6047634d86a0 100644
@@ -85,6 +85,7 @@ int __init security_init(void)
 	capability_add_hooks();
 	yama_add_hooks();
 	loadpin_add_hooks();
+	sidechannel_add_hooks();
 
 	/*
 	 * Load all the remaining security modules.
security/sidechannel/Kconfig new file +13 -0
new file mode 100644
index 000000000000..653033027415
@@ -0,0 +1,13 @@
+config SECURITY_SIDECHANNEL
+	bool "Sidechannel attack safety extra checks"
+	depends on SECURITY
+	default n
+	help
+	  Look for a variety of cases where a side-channel attack
+	  could potentially be exploited. Instruct the switching
+	  code to use the indirect_branch_prediction_barrier in
+	  cases where the passed task and the current task may be
+	  at risk.
+
+          If you are unsure how to answer this question, answer N.
+
security/sidechannel/Makefile new file +1 -0
new file mode 100644
index 000000000000..f61d83f28035
@@ -0,0 +1 @@
+obj-$(CONFIG_SECURITY_SIDECHANNEL) += sidechannel.o
security/sidechannel/sidechannel.c new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.17.1
#6 lore raw

Re: [PATCH v6 5/5] sidechannel: Linux Security Module for sidechannel

Hi:

security/sidechannel/Kconfig line 4

Quoted 10 lines · Casey Schaufler
security/sidechannel/Kconfig new file +4 -0
new file mode 100644
index 000000000000..653033027415
@@ -0,0 +1,13 @@
+config SECURITY_SIDECHANNEL
+	bool "Sidechannel attack safety extra checks"
+	depends on SECURITY
+	default n

Please drop the "default n" since it is already the default value.

security/sidechannel/Kconfig line 12

Quoted 8 lines
security/sidechannel/Kconfig new file +8 -0
+	help
+	  Look for a variety of cases where a side-channel attack
+	  could potentially be exploited. Instruct the switching
+	  code to use the indirect_branch_prediction_barrier in
+	  cases where the passed task and the current task may be
+	  at risk.
+
+          If you are unsure how to answer this question, answer N.

Use tab + 2 spaces to indent the line above.

security/sidechannel/Kconfig line 13

Quoted 1 line
security/sidechannel/Kconfig new file +1 -0
+

thanx.

Signature · 1 line
~Randy