PERFORCE change 43059 for review

Andrew Reisse areisse at FreeBSD.org
Wed Nov 26 10:19:35 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=43059

Change 43059 by areisse at 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


More information about the p4-projects mailing list