aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Pawelczyk <l.pawelczyk@partner.samsung.com>2014-03-11 12:07:05 -0400
committerCasey Schaufler <casey@schaufler-ca.com>2014-04-11 17:34:26 -0400
commit5663884caab166f87ab8c68ec7c62b1cce85a400 (patch)
treea106c1314669cbe6809f2b327395f0d37167b10f
parent959e6c7f1eee42f14d31755b1134f5615db1d9bc (diff)
Smack: unify all ptrace accesses in the smack
The decision whether we can trace a process is made in the following functions: smack_ptrace_traceme() smack_ptrace_access_check() smack_bprm_set_creds() (in case the proces is traced) This patch unifies all those decisions by introducing one function that checks whether ptrace is allowed: smk_ptrace_rule_check(). This makes possible to actually trace with TRACEME where first the TRACEME itself must be allowed and then exec() on a traced process. Additional bugs fixed: - The decision is made according to the mode parameter that is now correctly translated from PTRACE_MODE_* to MAY_* instead of being treated 1:1. PTRACE_MODE_READ requires MAY_READ. PTRACE_MODE_ATTACH requires MAY_READWRITE. - Add a smack audit log in case of exec() refused by bprm_set_creds(). - Honor the PTRACE_MODE_NOAUDIT flag and don't put smack audit info in case this flag is set. Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@partner.samsung.com> Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
-rw-r--r--security/smack/smack_lsm.c84
1 files changed, 71 insertions, 13 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b23fbdd4cdad..4d6f37644baa 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -157,6 +157,54 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
157 return rc; 157 return rc;
158} 158}
159 159
160/**
161 * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
162 * @mode - input mode in form of PTRACE_MODE_*
163 *
164 * Returns a converted MAY_* mode usable by smack rules
165 */
166static inline unsigned int smk_ptrace_mode(unsigned int mode)
167{
168 switch (mode) {
169 case PTRACE_MODE_READ:
170 return MAY_READ;
171 case PTRACE_MODE_ATTACH:
172 return MAY_READWRITE;
173 }
174
175 return 0;
176}
177
178/**
179 * smk_ptrace_rule_check - helper for ptrace access
180 * @tracer: tracer process
181 * @tracee_label: label of the process that's about to be traced
182 * @mode: ptrace attachment mode (PTRACE_MODE_*)
183 * @func: name of the function that called us, used for audit
184 *
185 * Returns 0 on access granted, -error on error
186 */
187static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
188 unsigned int mode, const char *func)
189{
190 int rc;
191 struct smk_audit_info ad, *saip = NULL;
192 struct task_smack *tsp;
193 struct smack_known *skp;
194
195 if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
196 smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
197 smk_ad_setfield_u_tsk(&ad, tracer);
198 saip = &ad;
199 }
200
201 tsp = task_security(tracer);
202 skp = smk_of_task(tsp);
203
204 rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip);
205 return rc;
206}
207
160/* 208/*
161 * LSM hooks. 209 * LSM hooks.
162 * We he, that is fun! 210 * We he, that is fun!
@@ -165,16 +213,15 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
165/** 213/**
166 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH 214 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
167 * @ctp: child task pointer 215 * @ctp: child task pointer
168 * @mode: ptrace attachment mode 216 * @mode: ptrace attachment mode (PTRACE_MODE_*)
169 * 217 *
170 * Returns 0 if access is OK, an error code otherwise 218 * Returns 0 if access is OK, an error code otherwise
171 * 219 *
172 * Do the capability checks, and require read and write. 220 * Do the capability checks.
173 */ 221 */
174static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) 222static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
175{ 223{
176 int rc; 224 int rc;
177 struct smk_audit_info ad;
178 struct smack_known *skp; 225 struct smack_known *skp;
179 226
180 rc = cap_ptrace_access_check(ctp, mode); 227 rc = cap_ptrace_access_check(ctp, mode);
@@ -182,10 +229,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
182 return rc; 229 return rc;
183 230
184 skp = smk_of_task(task_security(ctp)); 231 skp = smk_of_task(task_security(ctp));
185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
186 smk_ad_setfield_u_tsk(&ad, ctp);
187 232
188 rc = smk_curacc(skp->smk_known, mode, &ad); 233 rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__);
189 return rc; 234 return rc;
190} 235}
191 236
@@ -195,12 +240,11 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
195 * 240 *
196 * Returns 0 if access is OK, an error code otherwise 241 * Returns 0 if access is OK, an error code otherwise
197 * 242 *
198 * Do the capability checks, and require read and write. 243 * Do the capability checks, and require PTRACE_MODE_ATTACH.
199 */ 244 */
200static int smack_ptrace_traceme(struct task_struct *ptp) 245static int smack_ptrace_traceme(struct task_struct *ptp)
201{ 246{
202 int rc; 247 int rc;
203 struct smk_audit_info ad;
204 struct smack_known *skp; 248 struct smack_known *skp;
205 249
206 rc = cap_ptrace_traceme(ptp); 250 rc = cap_ptrace_traceme(ptp);
@@ -208,10 +252,9 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
208 return rc; 252 return rc;
209 253
210 skp = smk_of_task(current_security()); 254 skp = smk_of_task(current_security());
211 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
212 smk_ad_setfield_u_tsk(&ad, ptp);
213 255
214 rc = smk_tskacc(ptp, skp->smk_known, MAY_READWRITE, &ad); 256 rc = smk_ptrace_rule_check(ptp, skp->smk_known,
257 PTRACE_MODE_ATTACH, __func__);
215 return rc; 258 return rc;
216} 259}
217 260
@@ -455,7 +498,7 @@ static int smack_sb_statfs(struct dentry *dentry)
455 * smack_bprm_set_creds - set creds for exec 498 * smack_bprm_set_creds - set creds for exec
456 * @bprm: the exec information 499 * @bprm: the exec information
457 * 500 *
458 * Returns 0 if it gets a blob, -ENOMEM otherwise 501 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
459 */ 502 */
460static int smack_bprm_set_creds(struct linux_binprm *bprm) 503static int smack_bprm_set_creds(struct linux_binprm *bprm)
461{ 504{
@@ -475,7 +518,22 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
475 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) 518 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
476 return 0; 519 return 0;
477 520
478 if (bprm->unsafe) 521 if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
522 struct task_struct *tracer;
523 rc = 0;
524
525 rcu_read_lock();
526 tracer = ptrace_parent(current);
527 if (likely(tracer != NULL))
528 rc = smk_ptrace_rule_check(tracer,
529 isp->smk_task->smk_known,
530 PTRACE_MODE_ATTACH,
531 __func__);
532 rcu_read_unlock();
533
534 if (rc != 0)
535 return rc;
536 } else if (bprm->unsafe)
479 return -EPERM; 537 return -EPERM;
480 538
481 bsp->smk_task = isp->smk_task; 539 bsp->smk_task = isp->smk_task;