/* * Clean up the process immediately after the installation of new credentials * due to exec */ static void kse_bprm_committed_creds(struct linux_binprm *bprm) { const struct task_security_struct *tsec = current_security(); if (tsec) return; }
/* * LSM hook implementation that authorizes deletion of labeled policies. */ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) { const struct task_security_struct *tsec = current_security(); if (!ctx) return 0; return avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL); }
int selinux_secmark_relabel_packet_permission(u32 sid) { if (selinux_enabled) { const struct task_security_struct *__tsec; u32 tsid; __tsec = current_security(); tsid = __tsec->sid; return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO, NULL); } return 0; }
/* * LSM hook implementation that authorizes deletion of labeled policies. */ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) { const struct task_security_struct *tsec = current_security(); int rc = 0; if (ctx) { rc = avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL); if (rc == 0) atomic_dec(&selinux_xfrm_refcount); } return rc; }
static int kse_bprm_set_creds(struct linux_binprm *bprm) { const struct task_security_struct *old_tsec; struct task_security_struct *new_tsec; struct inode *inode = bprm->file->f_path.dentry->d_inode; int rc; rc = cap_bprm_set_creds(bprm); if (rc) return rc; if (bprm->cred_prepared) return 0; rc = task_inode_perm(current, inode, bprm->file->f_path.dentry, FILE__EXECUTE); if (rc) return rc; /* Default to the current task SID. */ old_tsec = current_security(); new_tsec = bprm->cred->security; copy_mlevel(&new_tsec->mlevel, &old_tsec->mlevel); new_tsec->ilevel.level_value = old_tsec->ilevel.level_value; #if 0 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) new_tsec->sid = old_tsec->sid; if (new_tsec->sid == old_tsec->sid) { rc = task_inode_perm(current, inode, FILE__EXECUTE_NO_TRANS); if (rc) return rc; } else { /* Check permissions for the transition. */ rc = task_inode_perm(current, inode, PROCESS__TRANSITION); if (rc) return rc; rc = task_inode_perm(current, inode, FILE__ENTRYPOINT); if (rc) return rc; } #endif return 0; }
/* * Allocates a xfrm_sec_state and populates it using the supplied security * xfrm_user_sec_ctx context. */ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx, gfp_t gfp) { int rc; const struct task_security_struct *tsec = current_security(); struct xfrm_sec_ctx *ctx = NULL; u32 str_len; if (ctxp == NULL || uctx == NULL || uctx->ctx_doi != XFRM_SC_DOI_LSM || uctx->ctx_alg != XFRM_SC_ALG_SELINUX) return -EINVAL; str_len = uctx->ctx_len; if (str_len >= PAGE_SIZE) return -ENOMEM; ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp); if (!ctx) return -ENOMEM; ctx->ctx_doi = XFRM_SC_DOI_LSM; ctx->ctx_alg = XFRM_SC_ALG_SELINUX; ctx->ctx_len = str_len; memcpy(ctx->ctx_str, &uctx[1], str_len); ctx->ctx_str[str_len] = '\0'; rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp); if (rc) goto err; rc = avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL); if (rc) goto err; *ctxp = ctx; atomic_inc(&selinux_xfrm_refcount); return 0; err: kfree(ctx); return rc; }
/* * Security blob allocation for xfrm_policy and xfrm_state * CTX does not have a meaningful value on input */ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx, u32 sid) { int rc = 0; const struct task_security_struct *tsec = current_security(); struct xfrm_sec_ctx *ctx = NULL; char *ctx_str = NULL; u32 str_len; BUG_ON(uctx && sid); if (!uctx) goto not_from_user; if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX) return -EINVAL; str_len = uctx->ctx_len; if (str_len >= PAGE_SIZE) return -ENOMEM; *ctxp = ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->ctx_doi = uctx->ctx_doi; ctx->ctx_len = str_len; ctx->ctx_alg = uctx->ctx_alg; memcpy(ctx->ctx_str, uctx+1, str_len); ctx->ctx_str[str_len] = 0; rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid); if (rc) goto out; /* * Does the subject have permission to set security context? */ rc = avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL); if (rc) goto out; return rc; not_from_user: rc = security_sid_to_context(sid, &ctx_str, &str_len); if (rc) goto out; *ctxp = ctx = kmalloc(sizeof(*ctx) + str_len, GFP_KERNEL); if (!ctx) { rc = -ENOMEM; goto out; } ctx->ctx_doi = XFRM_SC_DOI_LSM; ctx->ctx_alg = XFRM_SC_ALG_SELINUX; ctx->ctx_sid = sid; ctx->ctx_len = str_len; memcpy(ctx->ctx_str, ctx_str, str_len); goto out2; out: *ctxp = NULL; kfree(ctx); out2: kfree(ctx_str); return rc; }
/* init inode security attrs and context string, * according to attrs of current task * i_security to xattr string */ int iss_to_context(int init, struct mac_level *mlevel, struct integrity_level *ilevel, char **scontext, u32 *scontext_len) { const struct task_security_struct *tss = current_security(); int i = 0; char *cate = NULL; char *cp = NULL; char temp[5]; if (mlevel == NULL || ilevel == NULL) return -EINVAL; *scontext = NULL; *scontext_len = 0; if (init && tss) { copy_mlevel(mlevel, &tss->mlevel); ilevel->level_value = tss->ilevel.level_value; pr_debug("itc,csum %d, ml %d, il %d, pid %d\n", tss->mlevel.level_catsum, tss->mlevel.level_value, tss->ilevel.level_value, current->pid); //iss->initialized = 1; } pr_debug("itc,csum %d, ml %d, il %d, p %d\n", mlevel->level_catsum, mlevel->level_value, ilevel->level_value, current->pid); if (mlevel->level_catsum) cp = kmalloc(mlevel->level_catsum*3 - 1 + 8, GFP_KERNEL); else cp = kmalloc(MAC_CAT_MAX*3 - 1 + 8, GFP_KERNEL); if (cp == NULL) { pr_debug("itc, cp NOMEM csum %d\n", mlevel->level_catsum); dump_stack(); return -ENOMEM; } if (mlevel->level_catsum) { cate = kmalloc(mlevel->level_catsum*3-1, GFP_KERNEL); if (cate == NULL) { pr_debug("itc, cate NOMEM csum\n"); dump_stack(); return -ENOMEM; } memset(cate, 0, mlevel->level_catsum*3-1); } for (i = 0; cate && i < MAC_CAT_MAX; i++) { if (mlevel->level_category[i] == 1) { if (strlen(cate) > 0) strcat(cate, ","); memset(temp, 0, 5); sprintf(temp, "c%d", i); strcat(cate, temp); } } /* empty category */ if (cate == NULL) //cate = kstrdup("c0", GFP_KERNEL); cate = kstrdup("", GFP_KERNEL); sprintf(cp, "%d:%d:%s:%d", mlevel->level_type, mlevel->level_value, cate, ilevel->level_value); pr_debug("itc %d:%d:%s:%d, pid %d\n", mlevel->level_type, mlevel->level_value, cate, ilevel->level_value, current->pid); if (cp == NULL) cp = kstrdup("2:2:c0:2\0", GFP_KERNEL); if (cate) kfree(cate); *scontext = cp; *scontext_len = strlen(*scontext); return 0; }