/** * aa_task_setrlimit - test permission to set an rlimit * @profile - profile confining the task (NOT NULL) * @task - task the resource is being set on * @resource - the resource being set * @new_rlim - the new resource limit (NOT NULL) * * Control raising the processes hard limit. * * Returns: 0 or error code if setting resource failed */ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task, unsigned int resource, struct rlimit *new_rlim) { struct aa_profile *task_profile; int error = 0; rcu_read_lock(); task_profile = aa_get_profile(aa_cred_profile(__task_cred(task))); rcu_read_unlock(); /* TODO: extend resource control to handle other (non current) * profiles. AppArmor rules currently have the implicit assumption * that the task is setting the resource of a task confined with * the same profile or that the task setting the resource of another * task has CAP_SYS_RESOURCE. */ if ((profile != task_profile && aa_capable(profile, CAP_SYS_RESOURCE, 1)) || (profile->rlimits.mask & (1 << resource) && new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)) error = -EACCES; aa_put_profile(task_profile); return audit_resource(profile, resource, new_rlim->rlim_max, error); }
/** * aa_may_ptrace - test if tracer task can trace the tracee * @tracer_task: task who will do the tracing (NOT NULL) * @tracer: profile of the task doing the tracing (NOT NULL) * @tracee: task to be traced * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH * * Returns: %0 else error code if permission denied or error */ int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer, struct aa_profile *tracee, unsigned int mode) { /* TODO: currently only based on capability, not extended ptrace * rules, * Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH */ if (unconfined(tracer) || tracer == tracee) return 0; /* log this capability request */ return aa_capable(tracer_task, tracer, CAP_SYS_PTRACE, 1); }
int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer, struct aa_profile *tracee, unsigned int mode) { /* */ if (unconfined(tracer) || tracer == tracee) return 0; /* */ return aa_capable(tracer_task, tracer, CAP_SYS_PTRACE, 1); }
static int cross_ptrace_perm(struct aa_profile *tracer, struct aa_profile *tracee, u32 request, struct common_audit_data *sa) { if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE)) return xcheck(profile_ptrace_perm(tracer, tracee, request, sa), profile_ptrace_perm(tracee, tracer, request << PTRACE_PERM_SHIFT, sa)); /* policy uses the old style capability check for ptrace */ if (profile_unconfined(tracer) || tracer == tracee) return 0; aad(sa)->label = &tracer->label; aad(sa)->target = tracee->base.hname; aad(sa)->request = 0; aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1); return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb); }
static int profile_tracer_perm(struct aa_profile *tracer, struct aa_label *tracee, u32 request, struct common_audit_data *sa) { if (profile_unconfined(tracer)) return 0; if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE)) return profile_ptrace_perm(tracer, tracee, request, sa); /* profile uses the old style capability check for ptrace */ if (&tracer->label == tracee) return 0; aad(sa)->label = &tracer->label; aad(sa)->peer = tracee; aad(sa)->request = 0; aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, CAP_OPT_NONE); return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb); }