int main(int argc, char **argv) { struct av_decision avd; security_class_t tclass; int ret; if (argc != 4) { fprintf(stderr, "usage: %s scontext tcontext tclass\n", argv[0]); exit(1); } tclass = string_to_security_class(argv[3]); if (!tclass) { fprintf(stderr, "%s: invalid class '%s'\n", argv[0], argv[3]); exit(2); } ret = security_compute_av(argv[1], argv[2], tclass, 1, &avd); if (ret < 0) { fprintf(stderr, "%s: security_compute_av failed\n", argv[0]); exit(3); } printf("allowed="); print_access_vector(tclass, avd.allowed); printf("\n"); if (avd.decided != ~0U) { printf("decided="); print_access_vector(tclass, avd.decided); printf("\n"); } if (avd.auditallow) { printf("auditallow="); print_access_vector(tclass, avd.auditallow); printf("\n"); } if (avd.auditdeny != ~0U) { printf("auditdeny"); print_access_vector(tclass, avd.auditdeny); printf("\n"); } exit(0); }
static ssize_t sel_write_access(struct file *file, char *buf, size_t size) { char *scon, *tcon; u32 ssid, tsid; u16 tclass; u32 req; struct av_decision avd; ssize_t length; length = task_has_security(current, SECURITY__COMPUTE_AV); if (length) return length; length = -ENOMEM; scon = kzalloc(size+1, GFP_KERNEL); if (!scon) return length; tcon = kzalloc(size+1, GFP_KERNEL); if (!tcon) goto out; length = -EINVAL; if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4) goto out2; length = security_context_to_sid(scon, strlen(scon)+1, &ssid); if (length < 0) goto out2; length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); if (length < 0) goto out2; length = security_compute_av(ssid, tsid, tclass, req, &avd); if (length < 0) goto out2; length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%x %x %x %x %u", avd.allowed, avd.decided, avd.auditallow, avd.auditdeny, avd.seqno); out2: kfree(tcon); out: kfree(scon); return length; }
static int check_selinux_access (const char *changed_user, uid_t changed_uid, access_vector_t requested_access) { int status = -1; security_context_t user_context; context_t c; const char *user; /* if in permissive mode then allow the operation */ if (security_getenforce() == 0) { return 0; } /* get the context of the process which executed passwd */ if (getprevcon(&user_context) != 0) { return -1; } /* get the "user" portion of the context (the part before the first colon) */ c = context_new(user_context); user = context_user_get(c); /* if changing a password for an account with UID==0 or for an account where the identity matches then return success */ if (changed_uid != 0 && strcmp(changed_user, user) == 0) { status = 0; } else { struct av_decision avd; int retval; retval = security_compute_av(user_context, user_context, SECCLASS_PASSWD, requested_access, &avd); if ((retval == 0) && ((requested_access & avd.allowed) == requested_access)) { status = 0; } } context_free(c); freecon(user_context); return status; }
static int mls_range_allowed(pam_handle_t *pamh, security_context_t src, security_context_t dst, int debug) { struct av_decision avd; int retval; unsigned int bit = CONTEXT__CONTAINS; context_t src_context = context_new (src); context_t dst_context = context_new (dst); context_range_set(dst_context, context_range_get(src_context)); if (debug) pam_syslog(pamh, LOG_NOTICE, "Checking if %s mls range valid for %s", dst, context_str(dst_context)); retval = security_compute_av(context_str(dst_context), dst, SECCLASS_CONTEXT, bit, &avd); context_free(src_context); context_free(dst_context); if (retval || ((bit & avd.allowed) != bit)) return 0; return 1; }
static int flask_security_access(struct xen_flask_access *arg) { struct av_decision avd; int rv; rv = domain_has_security(current->domain, SECURITY__COMPUTE_AV); if ( rv ) return rv; rv = security_compute_av(arg->ssid, arg->tsid, arg->tclass, arg->req, &avd); if ( rv < 0 ) return rv; arg->allowed = avd.allowed; arg->audit_allow = avd.auditallow; arg->audit_deny = avd.auditdeny; arg->seqno = avd.seqno; return rv; }
static int get_security_context(char *name, int crontab_fd, security_context_t *rcontext, char *tabname) { security_context_t *context_list = NULL; security_context_t current_con; int list_count = 0; security_context_t file_context=NULL; struct av_decision avd; int retval=0; char *seuser = NULL; char *level = NULL; int i; if (name != NULL) { if (getseuserbyname(name, &seuser, &level)) { log_it(name, getpid(), "getseuserbyname FAILED", tabname); return (security_getenforce() > 0); } } else { seuser = strdup("system_u"); } *rcontext = NULL; if(getcon(¤t_con)) { log_it(name, getpid(), "Can't get current context", tabname); return -1; } list_count = get_ordered_context_list_with_level(seuser, level, current_con, &context_list); freecon(current_con); free(seuser); free(level); if (list_count == -1) { if (security_getenforce() > 0) { log_it(name, getpid(), "No SELinux security context", tabname); return -1; } else { log_it(name, getpid(), "No security context but SELinux in permissive mode," " continuing", tabname); return 0; } } if (fgetfilecon(crontab_fd, &file_context) < OK) { if (security_getenforce() > 0) { log_it(name, getpid(), "getfilecon FAILED", tabname); freeconary(context_list); return -1; } else { log_it(name, getpid(), "getfilecon FAILED but SELinux in " "permissive mode, continuing", tabname); *rcontext = strdup(context_list[0]); freeconary(context_list); return 0; } } /* * Since crontab files are not directly executed, * crond must ensure that the crontab file has * a context that is appropriate for the context of * the user cron job. It performs an entrypoint * permission check for this purpose. */ for(i = 0; i < list_count; i++) { retval = security_compute_av(context_list[i], file_context, SECCLASS_FILE, FILE__ENTRYPOINT, &avd); if(!retval && ((FILE__ENTRYPOINT & avd.allowed) == FILE__ENTRYPOINT)) { *rcontext = strdup(context_list[i]); freecon(file_context); freeconary(context_list); return 0; } } freecon(file_context); if (security_getenforce() > 0) { log_it(name, getpid(), "ENTRYPOINT FAILED", tabname); freeconary(context_list); return -1; } else { log_it(name, getpid(), "ENTRYPOINT FAILED but SELinux in permissive mode, continuing", tabname); *rcontext = strdup(context_list[0]); freeconary(context_list); } return 0; }