📄 services.c
字号:
1 + strlen(policydb.p_type_val_to_name[context->type - 1]); mls_sid_to_context(context, &scontextp); *scontextp = 0; return 0;}#include "initial_sid_to_string.h"/** * security_sid_to_context - Obtain a context for a given SID. * @sid: security identifier, SID * @scontext: security context * @scontext_len: length in bytes * * Write the string representation of the context associated with @sid * into a dynamically allocated string of the correct size. Set @scontext * to point to this string and set @scontext_len to the length of the string. */int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len){ struct context *context; int rc = 0; if ( !ss_initialized ) { if ( sid <= SECINITSID_NUM ) { char *scontextp; *scontext_len = strlen(initial_sid_to_string[sid]) + 1; scontextp = xmalloc_array(char, *scontext_len); strlcpy(scontextp, initial_sid_to_string[sid], *scontext_len); *scontext = scontextp; goto out; } printk(KERN_ERR "security_sid_to_context: called before initial " "load_policy on unknown SID %d\n", sid); rc = -EINVAL; goto out; } POLICY_RDLOCK; context = sidtab_search(&sidtab, sid); if ( !context ) { printk(KERN_ERR "security_sid_to_context: unrecognized SID " "%d\n", sid); rc = -EINVAL; goto out_unlock; } rc = context_struct_to_string(context, scontext, scontext_len);out_unlock: POLICY_RDUNLOCK;out: return rc;}static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid){ char *scontext2; struct context context; struct role_datum *role; struct type_datum *typdatum; struct user_datum *usrdatum; char *scontextp, *p, oldc; int rc = 0; if ( !ss_initialized ) { int i; for ( i = 1; i < SECINITSID_NUM; i++ ) { if ( !strcmp(initial_sid_to_string[i], scontext) ) { *sid = i; goto out; } } *sid = SECINITSID_XEN; goto out; } *sid = SECSID_NULL; /* Copy the string so that we can modify the copy as we parse it. The string should already by null terminated, but we append a null suffix to the copy to avoid problems with the existing attr package, which doesn't view the null terminator as part of the attribute value. */ scontext2 = xmalloc_array(char, scontext_len+1); if ( !scontext2 ) { rc = -ENOMEM; goto out; } memcpy(scontext2, scontext, scontext_len); scontext2[scontext_len] = 0; context_init(&context); *sid = SECSID_NULL; POLICY_RDLOCK; /* Parse the security context. */ rc = -EINVAL; scontextp = (char *) scontext2; /* Extract the user. */ p = scontextp; while ( *p && *p != ':' ) p++; if (*p == 0) goto out_unlock; *p++ = 0; usrdatum = hashtab_search(policydb.p_users.table, scontextp); if ( !usrdatum ) goto out_unlock; context.user = usrdatum->value; /* Extract role. */ scontextp = p; while ( *p && *p != ':' ) p++; if ( *p == 0 ) goto out_unlock; *p++ = 0; role = hashtab_search(policydb.p_roles.table, scontextp); if ( !role ) goto out_unlock; context.role = role->value; /* Extract type. */ scontextp = p; while ( *p && *p != ':' ) p++; oldc = *p; *p++ = 0; typdatum = hashtab_search(policydb.p_types.table, scontextp); if ( !typdatum ) goto out_unlock; context.type = typdatum->value; rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); if ( rc ) goto out_unlock; if ( (p - scontext2) < scontext_len ) { rc = -EINVAL; goto out_unlock; } /* Check the validity of the new context. */ if ( !policydb_context_isvalid(&policydb, &context) ) { rc = -EINVAL; goto out_unlock; } /* Obtain the new sid. */ rc = sidtab_context_to_sid(&sidtab, &context, sid);out_unlock: POLICY_RDUNLOCK; context_destroy(&context); xfree(scontext2);out: return rc;}/** * security_context_to_sid - Obtain a SID for a given security context. * @scontext: security context * @scontext_len: length in bytes * @sid: security identifier, SID * * Obtains a SID associated with the security context that * has the string representation specified by @scontext. * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid){ return security_context_to_sid_core(scontext, scontext_len, sid, SECSID_NULL);}/** * security_context_to_sid_default - Obtain a SID for a given security context, * falling back to specified default if needed. * * @scontext: security context * @scontext_len: length in bytes * @sid: security identifier, SID * @def_sid: default SID to assign on errror * * Obtains a SID associated with the security context that * has the string representation specified by @scontext. * The default SID is passed to the MLS layer to be used to allow * kernel labeling of the MLS field if the MLS field is not present * (for upgrading to MLS without full relabel). * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid){ return security_context_to_sid_core(scontext, scontext_len, sid, def_sid);}static int compute_sid_handle_invalid_context( struct context *scontext, struct context *tcontext, u16 tclass, struct context *newcontext){ char *s = NULL, *t = NULL, *n = NULL; u32 slen, tlen, nlen; if ( context_struct_to_string(scontext, &s, &slen) < 0 ) goto out; if ( context_struct_to_string(tcontext, &t, &tlen) < 0 ) goto out; if ( context_struct_to_string(newcontext, &n, &nlen) < 0 ) goto out; printk("security_compute_sid: invalid context %s" " for scontext=%s" " tcontext=%s" " tclass=%s", n, s, t, policydb.p_class_val_to_name[tclass-1]);out: xfree(s); xfree(t); xfree(n); if ( !flask_enforcing ) return 0; return -EACCES;}static int security_compute_sid(u32 ssid, u32 tsid, u16 tclass, u32 specified, u32 *out_sid){ struct context *scontext = NULL, *tcontext = NULL, newcontext; struct role_trans *roletr = NULL; struct avtab_key avkey; struct avtab_datum *avdatum; struct avtab_node *node; int rc = 0; if ( !ss_initialized ) { switch ( tclass ) { case SECCLASS_DOMAIN: *out_sid = ssid; break; default: *out_sid = tsid; break; } goto out; } POLICY_RDLOCK; scontext = sidtab_search(&sidtab, ssid); if ( !scontext ) { printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", ssid); rc = -EINVAL; goto out_unlock; } tcontext = sidtab_search(&sidtab, tsid); if ( !tcontext ) { printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", tsid); rc = -EINVAL; goto out_unlock; } context_init(&newcontext); /* Set the user identity. */ switch ( specified ) { case AVTAB_TRANSITION: case AVTAB_CHANGE: /* Use the process user identity. */ newcontext.user = scontext->user; break; case AVTAB_MEMBER: /* Use the related object owner. */ newcontext.user = tcontext->user; break; } /* Set the role and type to default values. */ switch ( tclass ) { case SECCLASS_DOMAIN: /* Use the current role and type of process. */ newcontext.role = scontext->role; newcontext.type = scontext->type; break; default: /* Use the well-defined object role. */ newcontext.role = OBJECT_R_VAL; /* Use the type of the related object. */ newcontext.type = tcontext->type; } /* Look for a type transition/member/change rule. */ avkey.source_type = scontext->type; avkey.target_type = tcontext->type; avkey.target_class = tclass; avkey.specified = specified; avdatum = avtab_search(&policydb.te_avtab, &avkey); /* If no permanent rule, also check for enabled conditional rules */ if ( !avdatum ) { node = avtab_search_node(&policydb.te_cond_avtab, &avkey); for ( ; node != NULL; node = avtab_search_node_next(node, specified) ) { if ( node->key.specified & AVTAB_ENABLED ) { avdatum = &node->datum; break; } } } if ( avdatum ) { /* Use the type from the type transition/member/change rule. */ newcontext.type = avdatum->data; } /* Check for class-specific changes. */ switch ( tclass ) { case SECCLASS_DOMAIN: if ( specified & AVTAB_TRANSITION ) { /* Look for a role transition rule. */ for ( roletr = policydb.role_tr; roletr; roletr = roletr->next ) { if ( roletr->role == scontext->role && roletr->type == tcontext->type ) { /* Use the role transition rule. */ newcontext.role = roletr->new_role; break; } } } break; default: break; } /* Set the MLS attributes. This is done last because it may allocate memory. */ rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext); if ( rc ) goto out_unlock; /* Check the validity of the context. */ if ( !policydb_context_isvalid(&policydb, &newcontext) ) { rc = compute_sid_handle_invalid_context(scontext, tcontext, tclass, &newcontext); if ( rc ) goto out_unlock; } /* Obtain the sid for the context. */ rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);out_unlock: POLICY_RDUNLOCK; context_destroy(&newcontext);out: return rc;}/** * security_transition_sid - Compute the SID for a new subject/object. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @out_sid: security identifier for new subject/object * * Compute a SID to use for labeling a new subject or object in the * class @tclass based on a SID pair (@ssid, @tsid). * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM * if insufficient memory is available, or %0 if the new SID was * computed successfully. */int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid){ return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);}/** * security_member_sid - Compute the SID for member selection. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @out_sid: security identifier for selected member * * Compute a SID to use when selecting a member of a polyinstantiated * object of class @tclass based on a SID pair (@ssid, @tsid). * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM * if insufficient memory is available, or %0 if the SID was * computed successfully. */int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid){ return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);}/** * security_change_sid - Compute the SID for object relabeling. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @out_sid: security identifier for selected member * * Compute a SID to use for relabeling an object of class @tclass * based on a SID pair (@ssid, @tsid). * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM * if insufficient memory is available, or %0 if the SID was * computed successfully. */int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid){ return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);}/* * Verify that each permission that is defined under the * existing policy is still defined with the same value * in the new policy. */static int validate_perm(void *key, void *datum, void *p){ struct hashtab *h; struct perm_datum *perdatum, *perdatum2; int rc = 0; h = p; perdatum = datum; perdatum2 = hashtab_search(h, key); if ( !perdatum2 ) { printk(KERN_ERR "security: permission %s disappeared", (char *)key); rc = -ENOENT; goto out; } if ( perdatum->value != perdatum2->value ) { printk(KERN_ERR "security: the value of permission %s changed", (char *)key); rc = -EINVAL; }out: return rc;}/* * Verify that each class that is defined under the * existing policy is still defined with the same * attributes in the new policy. */static int validate_class(void *key, void *datum, void *p){ struct policydb *newp; struct class_datum *cladatum, *cladatum2; int rc; newp = p; cladatum = datum; cladatum2 = hashtab_search(newp->p_classes.table, key); if ( !cladatum2 ) { printk(KERN_ERR "security: class %s disappeared\n", (char *)key); rc = -ENOENT; goto out; } if (cladatum->value != cladatum2->value) { printk(KERN_ERR "security: the value of class %s changed\n", (char *)key); rc = -EINVAL; goto out; } if ( (cladatum->comdatum && !cladatum2->comdatum) || (!cladatum->comdatum && cladatum2->comdatum) ) { printk(KERN_ERR "security: the inherits clause for the access " "vector definition for class %s changed\n", (char *)key); rc = -EINVAL; goto out; } if ( cladatum->comdatum ) { rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm, cladatum2->comdatum->permissions.table); if ( rc ) { printk(" in the access vector definition for class %s\n", (char *)key); goto out; } } rc = hashtab_map(cladatum->permissions.table, validate_perm, cladatum2->permissions.table); if ( rc ) printk(" in access vector definition for class %s\n", (char *)key);out: return rc;}/* Clone the SID into the new SID table. */static int clone_sid(u32 sid, struct context *context, void *arg){ struct sidtab *s = arg; return sidtab_insert(s, sid, context);}static inline int convert_context_handle_invalid_context(struct context *context){ int rc = 0; if ( flask_enforcing ) rc = -EINVAL; else { char *s; u32 len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -