Date: Wed, 26 Nov 2003 10:19:30 -0800 (PST) From: Andrew Reisse <areisse@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 43059 for review Message-ID: <200311261819.hAQIJUK1022815@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=43059 Change 43059 by areisse@areisse_ibook on 2003/11/26 10:19:18 New sebsd syscall to get the list of labels that the user can set on files. Affected files ... .. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_syscall.c#4 edit .. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_syscalls.h#3 edit .. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/services.c#3 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_syscall.c#4 (text+ko) ==== @@ -77,10 +77,12 @@ /* * Lists the SIDs currently available for transition to by a given * "context\0username\0" + * + * or, lists the SIDs that a given context can relabel files to. (username is ignored) */ static int -sys_user_sids (char *context, char *username, char *out, int *outlen) +sys_get_sids (int function, char *context, char *username, char *out, int *outlen) { u_int32_t n, nsids, scontext_len; security_id_t *sids, sid; @@ -101,7 +103,19 @@ error = security_context_to_sid(context, strlen (context), &sid); if (error) goto out; - error = security_get_user_sids(sid, username, &sids, &nsids); + switch (function) + { + case SEBSDCALL_GETUSERSIDS: + error = security_get_user_sids(sid, username, &sids, &nsids); + break; + + case SEBSDCALL_GETFILESIDS: + error = security_get_file_sids(sid, SECCLASS_FILE, &sids, &nsids); + break; + + default: + error = ENOSYS; + } if (error) goto out; for (n = 0; n < nsids; n++) { @@ -150,6 +164,7 @@ break; case SEBSDCALL_GETUSERSIDS: + case SEBSDCALL_GETFILESIDS: { struct getsid_args uap; err = copyin (args, &uap, sizeof (struct getsid_args)); @@ -171,7 +186,7 @@ } ctx[MAX_UC-1] = 0; usr[MAX_UC-1] = 0; - err = sys_user_sids (ctx, usr, uap.out, uap.outlen); + err = sys_get_sids (call, ctx, usr, uap.out, uap.outlen); sebsd_ss_free (ctx); sebsd_ss_free (usr); } ==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_syscalls.h#3 (text+ko) ==== @@ -6,6 +6,7 @@ */ #define SEBSDCALL_LOAD_POLICY 7 #define SEBSDCALL_GETUSERSIDS 6 +#define SEBSDCALL_GETFILESIDS 5 #define SEBSDCALL_NUM 7 ==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/services.c#3 (text+ko) ==== @@ -1329,6 +1329,100 @@ return rc; } +/* Return the list of sids that a user can use to relabel files to. + This could probably be more efficient. */ + +struct getfilesids +{ + struct context *scon; + security_class_t sclass; + struct class_datum *sca; + security_id_t *sids; + int maxsids; + int numsids; +}; + +static int getfilesids1 (struct avtab_key *avk, struct avtab_datum *avd, struct getfilesids *p) +{ + if (avk->source_type == p->scon->type && avk->target_class == p->sclass && + (avd->specified & AVTAB_AV) && (avtab_allowed(avd) & COMMON_FILE__RELABELTO)) + { + int ir, iu; + struct context fc; + + fc.type = avk->target_type; + + for (ir = 0; ir < policydb.p_roles.nprim; ir++) + if (ir+1 == OBJECT_R_VAL || ebitmap_get_bit (&policydb.role_val_to_struct[ir]->types, fc.type-1)) + { + fc.role = ir+1; + + for (iu = 0; iu < policydb.p_users.nprim; iu++) + if (fc.role == OBJECT_R_VAL || ebitmap_get_bit (&policydb.user_val_to_struct[iu]->roles, ir)) + { + fc.user = iu+1; + + struct constraint_node *constraint = p->sca->constraints; + while (constraint) + { + if ((constraint->permissions & COMMON_FILE__RELABELTO) && + !constraint_expr_eval(p->scon, &fc, constraint->expr)) + break; + constraint = constraint->next; + } + + security_id_t sid; + + if (constraint == NULL && 0 == sidtab_context_to_sid (&sidtab, &fc, &sid)) + { + /* passed all checks, add to list */ + if (p->numsids == p->maxsids) + { + p->maxsids += 16; + security_id_t *sids = sebsd_ss_malloc (sizeof (security_id_t) * p->maxsids, 0); + memcpy (sids, p->sids, sizeof (security_id_t) * p->numsids); + sebsd_ss_free (p->sids); + p->sids = sids; + } + p->sids[p->numsids++] = sid; + } + } + } + } + + return 0; +} + +int security_get_file_sids (security_id_t user, + security_class_t sclass, + security_id_t **sids, + int *numsids) +{ + struct context *scontext = sidtab_search(&sidtab, user); + + if (scontext == NULL) + goto out_err; + + struct getfilesids p; + p.scon = scontext; + p.sclass = sclass; + if (!sclass || sclass > policydb.p_classes.nprim) + goto out_err; + p.sca = policydb.class_val_to_struct[sclass - 1]; + p.maxsids = 32; + p.sids = sebsd_ss_malloc (sizeof (security_id_t) * p.maxsids, 0); + p.numsids = 0; + avtab_map (&policydb.te_avtab, getfilesids1, &p); + *sids = p.sids; + *numsids = p.numsids; + return 0; + + out_err: + *numsids = 0; + *sids = NULL; + return EINVAL; +} + /** * security_genfs_sid - Obtain a SID for a file in a filesystem * @fstype: filesystem type
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311261819.hAQIJUK1022815>