Skip to contentSkip to conversation

libselinux: string and compute_create functions

PATCH In review Eamon Walsh 2 participants 7 messages Mar 30, 2007 SELinux security module

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 libselinux: string and compute_create functions

Some new interfaces for libselinux, supporting userspace object managers:

1. class,av to string functions, completing the set.

2. "avc_compute_create" convenience interface to security_compute_create, taking userspace AVC SID's instead of security context strings.

3. man pages for these.

--

include/selinux/selinux.h |   12 ++++-
src/avc.c                 |   99 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+), 2 deletions(-)

--

src/avc.c (working copy) renamed from src/avc.c (revision 2307) +0 -0
Index: libselinux/src/avc.c
===================================================================
@@ -1338,6 +1338,105 @@
    return 0;

}

+const char *security_class_to_string(security_class_t tclass) +{
+ tclass = (tclass > 0 && tclass < NCLASSES) ? tclass : 0;
+ return class_to_string_data.str + class_to_string[tclass];
+}
+
+const char *security_av_perm_to_string(security_class_t tclass,
+ access_vector_t av)
+{

+    const uint16_t *common_pts_idx = 0;
+    access_vector_t common_base = 0;
+    unsigned int i;

+
+ if (!av)
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
+ if (av_inherit[i].tclass == tclass) {
+ common_pts_idx =
+ &common_perm_to_string.data[av_inherit[i].
+ common_pts_idx];
+ common_base = av_inherit[i].common_base;
+ break;
+ }
+ }
+
+ if (av < common_base) {
+ i = 0;
+ while (!(av & 1)) {
+ av >>= 1;
+ i++;
+ }
+ return common_perm_to_string_data.str + common_pts_idx[i];
+ }
+
+ for (i = 0; i < NVECTORS; i++) {
+ if (av_perm_to_string[i].tclass == tclass &&
+ av_perm_to_string[i].value == av)
+ return av_perm_to_string_data.str
+ + av_perm_to_string[i].nameidx;
+ }
+
+ return NULL;
+}
+
+int security_av_string(security_class_t tclass, access_vector_t av, char **res) +{

+    unsigned int i = 0;
+    size_t len = 5;
+    access_vector_t tmp = av;
+    int rc = 0;
+    const char *str;
+    char *ptr;

+
+ /* first pass computes the required length */
+ while (tmp) {
+ if (tmp & 1) {
+ str = security_av_perm_to_string(tclass, av & (1<<i));
+ if (str)
+ len += strlen(str) + 1;
+ else {

+                rc = -1;
+                errno = EINVAL;
+                goto out;
+            }
+        }
+        tmp >>= 1;
+        i++;

+ }
+
+ *res = malloc(len);
+ if (!*res) {
+ rc = -1;
+ goto out;
+ }
+

+    /* second pass constructs the string */
+    i = 0;
+    tmp = av;
+    ptr = *res;

+
+ if (!av) {
+ sprintf(ptr, "null");
+ goto out;
+ }
+
+ ptr += sprintf(ptr, "{ ");
+ while (tmp) {
+ if (tmp & 1)
+ ptr += sprintf(ptr, "%s ", security_av_perm_to_string(
+ tclass, av & (1<<i)));
+ tmp >>= 1;
+ i++;
+ }
+ sprintf(ptr, "}");
+out:
+ return rc;
+}
+
void print_access_vector(security_class_t tclass, access_vector_t av)

{
    const uint16_t *common_pts_idx = 0;
include/selinux/selinux.h (working copy) renamed from include/selinux/selinux.h (revision 2307) +0 -0
Index: libselinux/include/selinux/selinux.h
===================================================================
@@ -277,13 +277,21 @@
 

/* Common helpers */

-/* Return the security class value for a given class name. */ +/* Convert between security class values and string names */

    extern security_class_t string_to_security_class(const char *name);

+ extern const char *security_class_to_string(security_class_t cls);

-/* Return an access vector for a given class and permission name. */ +/* Convert between individual access vector permissions and string names */
+ extern const char *security_av_perm_to_string(security_class_t tclass,
+ access_vector_t perm);
extern access_vector_t string_to_av_perm(security_class_t tclass,
const char *name);

+/* Returns an access vector in a string representation. User must free the
+ * returned string via free(). */
+ extern int security_av_string(security_class_t tclass,
+ access_vector_t av, char **result);
+
/* Display an access vector in a string representation. */
extern void print_access_vector(security_class_t tclass,
access_vector_t av);

Signature · 8 lines
Eamon Walsh <[email protected]>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.
#1 lore raw

PATCH 1/3 libselinux: string and compute_create functions (resend)

Resending patch 1, was whitespace damaged.

--

include/selinux/selinux.h |   12 ++++-
src/avc.c                 |   99 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+), 2 deletions(-)

--

src/avc.c +0 -0
Index: libselinux/src/avc.c
===================================================================
@@ -1338,6 +1338,105 @@
	return 0;
}

+const char *security_class_to_string(security_class_t tclass)
+{
+ tclass = (tclass > 0 && tclass < NCLASSES) ? tclass : 0;
+ return class_to_string_data.str + class_to_string[tclass];
+}
+
+const char *security_av_perm_to_string(security_class_t tclass,
+ access_vector_t av)
+{
+ const uint16_t *common_pts_idx = 0;
+ access_vector_t common_base = 0;
+ unsigned int i;
+
+ if (!av)
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
+ if (av_inherit[i].tclass == tclass) {
+ common_pts_idx =
+ &common_perm_to_string.data[av_inherit[i].
+ common_pts_idx];
+ common_base = av_inherit[i].common_base;
+ break;
+ }
+ }
+
+ if (av < common_base) {
+ i = 0;
+ while (!(av & 1)) {
+ av >>= 1;
+ i++;
+ }
+ return common_perm_to_string_data.str + common_pts_idx[i];
+ }
+
+ for (i = 0; i < NVECTORS; i++) {
+ if (av_perm_to_string[i].tclass == tclass &&
+ av_perm_to_string[i].value == av)
+ return av_perm_to_string_data.str
+ + av_perm_to_string[i].nameidx;
+ }
+
+ return NULL;
+}
+
+int security_av_string(security_class_t tclass, access_vector_t av, char **res) +{
+ unsigned int i = 0;
+ size_t len = 5;
+ access_vector_t tmp = av;
+ int rc = 0;
+ const char *str;
+ char *ptr;
+
+ /* first pass computes the required length */
+ while (tmp) {
+ if (tmp & 1) {
+ str = security_av_perm_to_string(tclass, av & (1<<i));
+ if (str)
+ len += strlen(str) + 1;
+ else {
+ rc = -1;
+ errno = EINVAL;
+ goto out;
+ }
+ }
+ tmp >>= 1;
+ i++;
+ }
+
+ *res = malloc(len);
+ if (!*res) {
+ rc = -1;
+ goto out;
+ }
+
+ /* second pass constructs the string */
+ i = 0;
+ tmp = av;
+ ptr = *res;
+
+ if (!av) {
+ sprintf(ptr, "null");
+ goto out;
+ }
+
+ ptr += sprintf(ptr, "{ ");
+ while (tmp) {
+ if (tmp & 1)
+ ptr += sprintf(ptr, "%s ", security_av_perm_to_string(
+ tclass, av & (1<<i)));
+ tmp >>= 1;
+ i++;
+ }
+ sprintf(ptr, "}");
+out:
+ return rc;
+}
+
void print_access_vector(security_class_t tclass, access_vector_t av)

{
	const uint16_t *common_pts_idx = 0;
include/selinux/selinux.h +0 -0
Index: libselinux/include/selinux/selinux.h
===================================================================
@@ -277,13 +277,21 @@
 

/* Common helpers */

-/* Return the security class value for a given class name. */ +/* Convert between security class values and string names */

	extern security_class_t string_to_security_class(const char *name);

+ extern const char *security_class_to_string(security_class_t cls);

-/* Return an access vector for a given class and permission name. */ +/* Convert between individual access vector permissions and string names */
+ extern const char *security_av_perm_to_string(security_class_t tclass,

+						      access_vector_t perm);
	extern access_vector_t string_to_av_perm(security_class_t tclass,
						 const char *name);

+/* Returns an access vector in a string representation. User must free the
+ * returned string via free(). */
+ extern int security_av_string(security_class_t tclass,
+ access_vector_t av, char **result);
+
/* Display an access vector in a string representation. */

	extern void print_access_vector(security_class_t tclass,
					access_vector_t av);

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#2 lore raw

Re: [PATCH 1/3] libselinux: string and compute_create functions (resend)

Quoted 1 line · Eamon Walsh

Resending patch 1, was whitespace damaged.

for future reference:
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

Merged, with a couple comments below to follow up on.

Quoted 21 lines

--

 include/selinux/selinux.h |   12 ++++-
 src/avc.c                 |   99 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 2 deletions(-)

--
Index: libselinux/src/avc.c
===================================================================

src/avc.c +10 -0
 
+int security_av_string(security_class_t tclass, access_vector_t av, char **res)
+{
+	unsigned int i = 0;
+	size_t len = 5;
+	access_vector_t tmp = av;
+	int rc = 0;
+	const char *str;
+	char *ptr;
+
+	/* first pass computes the required length */

src/avc.c

Quoted 10 lines
src/avc.c +10 -0
+	while (tmp) {
+		if (tmp & 1) {
+			str = security_av_perm_to_string(tclass, av & (1<<i));
+			if (str)
+				len += strlen(str) + 1;
+			else {
+				rc = -1;
+				errno = EINVAL;
+				goto out;
+			}

This fails if the av contains any permissions not defined in the headers, which can occur for e.g. allow a b:c *; (as with unconfined domains). avc_dump_av() will instead display any remaining permission bits as a hex value after the string list.

We should also consolidate this with avc_dump_av() and print_access_vector(), and deprecate print_access_vector(), converting over any users to using the new function instead.

Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.
#3 lore raw

PATCH 2/3 libselinux: string and compute_create functions

In reply to Eamon Walsh

avc_compute_create function, same as security_compute_create but takes userspace AVC SID's.

--

include/selinux/avc.h |   19 +++++++++++++++++++
src/avc.c             |   25 +++++++++++++++++++++++++
2 files changed, 44 insertions(+)

--

avc.c +0 -0
Index: src/avc.c
===================================================================
@@ -1006,6 +1006,31 @@
	return rc;
}

+int avc_compute_create(security_id_t ssid, security_id_t tsid,
+ security_class_t tclass, security_id_t *newsid)
+{
+ int rc;
+ *ctx = NULL;
+ avc_get_lock(avc_lock);
+ if (ssid->refcnt > 0 && tsid->refcnt > 0) {
+ security_context_t ctx;
+ rc = security_compute_create_raw(ssid->ctx, tsid->ctx, tclass,
+ &ctx);
+ if (rc)
+ goto out;
+ rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
+ if (!rc)
+ (*newsid)->refcnt++;
+ freecon(ctx);
+ } else {
+ errno = EINVAL; /* bad reference count */
+ rc = -1;
+ }
+out:
+ avc_release_lock(avc_lock);
+ return rc;
+}
+
int avc_add_callback(int (*callback) (uint32_t event, security_id_t ssid,
security_id_t tsid, security_class_t tclass,

selinux/avc.h +0 -0
Index: include/selinux/avc.h
===================================================================
@@ -274,6 +274,25 @@
		       security_class_t tclass, access_vector_t requested,
		       struct av_decision *avd, int result, void *auditdata);

+/**
+ * avc_compute_create - Compute SID for labeling a new object.
+ * @ssid: source security identifier
+ * @tsid: target security identifier
+ * @tclass: target security class
+ * @newsid: pointer to SID reference
+ *
+ * Call the security server to obtain a context for labeling a
+ * new object. Look up the context in the SID table, making
+ * a new entry if not found. Increment the reference counter
+ * for the SID. Store a pointer to the SID structure into the
+ * memory referenced by @newsid, returning %0 on success or -%1 on
+ * error with @errno set. + */
+ int avc_compute_create(security_id_t ssid,

+			       security_id_t tsid,
+			       security_class_t tclass,
+			       security_id_t *newsid);

+
/*
* security event callback facility
*/

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#4 lore raw
Quoted 2 lines · Eamon Walsh

avc_compute_create function, same as security_compute_create but takes userspace AVC SID's.

Merged with fix described below.

Quoted 11 lines

--

 include/selinux/avc.h |   19 +++++++++++++++++++
 src/avc.c             |   25 +++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

--
Index: src/avc.c
===================================================================

avc.c line 1013

Quoted 8 lines
avc.c +5 -0
@@ -1006,6 +1006,31 @@
 	return rc;
 }
 
+int avc_compute_create(security_id_t ssid,  security_id_t tsid,
+		       security_class_t tclass, security_id_t *newsid)
+{
+	int rc;
+	*ctx = NULL;

s/ctx/newsid/

Quoted 23 lines
avc.c +20 -0
+	avc_get_lock(avc_lock);
+	if (ssid->refcnt > 0 && tsid->refcnt > 0) {
+		security_context_t ctx;
+		rc = security_compute_create_raw(ssid->ctx, tsid->ctx, tclass,
+						 &ctx);
+		if (rc)
+			goto out;
+		rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
+		if (!rc)
+			(*newsid)->refcnt++;
+		freecon(ctx);
+	} else {
+		errno = EINVAL;	/* bad reference count */
+		rc = -1;
+	}
+out:
+	avc_release_lock(avc_lock);
+	return rc;
+}
+
 int avc_add_callback(int (*callback) (uint32_t event, security_id_t ssid,
 				      security_id_t tsid,
 				      security_class_t tclass,
Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.
#5 lore raw

PATCH 3/3 libselinux: string and compute_create functions

In reply to Eamon Walsh

Man pages for new (and old string) functions.

--

avc_compute_create.3         |   58 +++++++++++++++++++++++++++++++
security_av_perm_to_string.3 |    1 security_av_string.3         |    1 security_class_to_string.3   |   80 +++++++++++++++++++++++++++++++++++++++++++
string_to_av_perm.3          |    1 string_to_security_class.3   |    1 6 files changed, 142 insertions(+)

--

security_av_string.3 +1 -0
Index: security_av_string.3
===================================================================
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3
avc_compute_create.3 +57 -0

57 lines not on this page · raw message

security_av_perm_to_string.3 +1 -0
Index: security_av_perm_to_string.3
===================================================================
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3
string_to_av_perm.3 +1 -0
Index: string_to_av_perm.3
===================================================================
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3
security_class_to_string.3 +80 -0

80 lines not on this page · raw message

string_to_security_class.3 +1 -0
Index: string_to_security_class.3
===================================================================
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#6 lore raw
Quoted 10 lines · Eamon Walsh

Man pages for new (and old string) functions.

--

 avc_compute_create.3         |   58 +++++++++++++++++++++++++++++++
 security_av_perm_to_string.3 |    1 
 security_av_string.3         |    1 
 security_class_to_string.3   |   80 +++++++++++++++++++++++++++++++++++++++++++
 string_to_av_perm.3          |    1 
 string_to_security_class.3   |    1 
 6 files changed, 142 insertions(+)

For future reference, patches should be -p1 or -p0 appliable from top of the tree.

Merged.

Quoted 180 lines

--
Index: security_av_string.3
===================================================================

security_av_string.3 +1 -0
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3

Index: avc_compute_create.3
===================================================================

avc_compute_create.3 +58 -0
@@ -0,0 +1,58 @@
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.\" Author: Eamon Walsh ([email protected]) 2007
+.TH "avc_compute_create" "3" "30 Mar 2007" "" "SE Linux API documentation"
+.SH "NAME"
+avc_compute_create \- obtain SELinux label for new object.
+.SH "SYNOPSIS"
+.B #include <selinux/selinux.h>
+.br
+.B #include <selinux/avc.h>
+.sp
+.BI "int avc_compute_create(security_id_t " ssid ", security_id_t " tsid ,
+.in +\w'int avc_compute_create('u
+.BI "security_class_t " tclass ", security_id_t *" newsid ");"
+.in
+.SH "DESCRIPTION"
+.B avc_compute_create
+is used to compute a SID to use for labeling a new object in a particular class based on a SID pair.  This call is identical to
+.BR security_compute_create ,
+but does not require converting from userspace SID's to contexts and back again.
+
+.B avc_compute_create
+returns a SID for the computed context in the memory referenced by
+.IR sid ,
+incrementing its reference count by 1.
+
+.SH "RETURN VALUE"
+On success, zero is returned.  On error, \-1 is returned and
+.I errno
+is set appropriately.
+
+.SH "ERRORS"
+.TP
+.B EINVAL
+The
+.I tclass
+and/or the security contexts referenced by
+.I ssid
+and
+.I tsid
+are not recognized by the currently loaded policy, or 
+.I tsid
+or
+.I ssid
+has a zero reference count and is invalid.
+
+.TP
+.B ENOMEM
+An attempt to allocate memory failed.
+
+.SH "AUTHOR"
+Eamon Walsh <[email protected]>
+
+.SH "SEE ALSO"
+.BR avc_init (3),
+.BR avc_context_to_sid (3),
+.BR security_compute_create (3),
+.BR selinux (8)

Index: security_av_perm_to_string.3
===================================================================

security_av_perm_to_string.3 +1 -0
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3

Index: string_to_av_perm.3
===================================================================

string_to_av_perm.3 +1 -0
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3

Index: security_class_to_string.3
===================================================================

security_class_to_string.3 +80 -0
@@ -0,0 +1,80 @@
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.\" Author: Eamon Walsh ([email protected]) 2007
+.TH "security_class_to_string" "3" "30 Mar 2007" "" "SE Linux API documentation"
+.SH "NAME"
+security_class_to_string, security_av_perm_to_string, string_to_security_class, string_to_av_perm, security_av_string \- convert
+between SELinux class and permission values and string names.
+
+.SH "SYNOPSIS"
+.B #include <selinux/selinux.h>
+.br
+.B #include <selinux/flask.h>
+.sp
+.BI "const char * security_class_to_string(security_class_t " tclass ");"
+.sp
+.BI "const char * security_av_perm_to_string(security_class_t " tclass ", access_vector_t " av ");"
+.sp
+.BI "int security_av_string(security_class_t " tclass ", access_vector_t " av ", char **" result ");"
+.sp
+.BI "security_class_t string_to_security_class(const char *" name ");"
+.sp
+.BI "access_vector_t string_to_av_perm(security_class_t " tclass ", const char *" name ");"
+
+.SH "DESCRIPTION"
+.B security_class_to_string
+returns a string name for class
+.IR tclass ,
+or NULL if the class is invalid.  The returned string must not be modified or freed.
+
+.B security_av_perm_to_string
+returns a string name for the access vector bit
+.I av
+of class
+.IR tclass ,
+or NULL if either argument is invalid.  The returned string must not be modified or freed.
+
+.B security_av_string
+computes a full access vector string representation using
+.I tclass
+and
+.IR av ,
+which may have multiple bits set.  The string is returned in the memory pointed to by
+.IR result ,
+and should be freed by the caller using
+.BR free (3).
+
+.B string_to_security_class
+returns the class value corresponding to the string name
+.IR name ,
+or zero if no such class exists.
+
+.B string_to_av_perm
+returns the access vector bit corresponding to the string name
+.I name
+and security class
+.IR tclass ,
+or zero if no such value exists.
+
+.SH "RETURN VALUE"
+.B security_av_string
+returns returns zero on success or \-1 on error with
+.I errno
+set appropriately.  All other functions return zero or NULL on error.
+
+.SH "ERRORS"
+.TP
+.B EINVAL
+A class or access vector argument is not recognized by the currently loaded policy.
+
+.TP
+.B ENOMEM
+An attempt to allocate memory failed.
+
+.SH "AUTHOR"
+Eamon Walsh <[email protected]>
+
+.SH "SEE ALSO"
+.BR selinux (8),
+.BR getcon (3),
+.BR getfilecon (3)

Index: string_to_security_class.3
===================================================================

string_to_security_class.3 +1 -1
@@ -0,0 +1 @@
+.so man3/security_class_to_string.3
 
 
 
--

This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.