@@ -27,6 +27,14 @@ extern "C" {
extern const char *context_str(context_t con);
+/*
+ * Return the string value of the context_t.
+ * Similar to context_str(3), but the client owns the string
+ * and needs to free it via free(3).
+ */
+
+ extern char *context_to_str(context_t con);
+
/* Free the storage used by a context */
extern void context_free(context_t con);
@@ -141,6 +141,36 @@ const char *context_str(context_t context)
}
+/*
+ * Return a new string value of the context.
+ */
+char *context_to_str(context_t context)
+{
+ const context_private_t *n = context->ptr;
+ char *buf;
+ size_t total = 0;
+
+ for (int i = 0; i < 4; i++) {
+ if (n->component[i]) {
+ total += strlen(n->component[i]) + 1;
+ }
+ }
+ buf = malloc(total);
+ if (buf != NULL) {
+ char *cp = buf;
+
+ cp = stpcpy(cp, n->component[0]);
+ for (int i = 1; i < 4; i++) {
+ if (n->component[i]) {
+ *cp++ = ':';
+ cp = stpcpy(cp, n->component[i]);
+ }
+ }
+ }
+ return buf;
+}
+
+
/* Returns nonzero iff failed */
static int set_comp(context_private_t * n, int idx, const char *str)
{
@@ -145,7 +145,7 @@ static int get_context_user(FILE * fp,
char *linerole, *linetype;
char **new_reachable = NULL;
char *usercon_str;
- const char *usercon_str2;
+ char *usercon_str2;
context_t usercon;
int rc;
@@ -255,7 +255,7 @@ static int get_context_user(FILE * fp,
rc = -1;
goto out;
}
- usercon_str2 = context_str(usercon);
+ usercon_str2 = context_to_str(usercon);
if (!usercon_str2) {
context_free(usercon);
rc = -1;
@@ -264,6 +264,7 @@ static int get_context_user(FILE * fp,
/* check whether usercon is already in reachable */
if (is_in_reachable(*reachable, usercon_str2)) {
+ free(usercon_str2);
context_free(usercon);
start = end;
continue;
@@ -271,20 +272,18 @@ static int get_context_user(FILE * fp,
if (security_check_context(usercon_str2) == 0) {
new_reachable = reallocarray(*reachable, *nreachable + 2, sizeof(char *));
if (!new_reachable) {
+ free(usercon_str2);
context_free(usercon);
rc = -1;
goto out;
}
*reachable = new_reachable;
- new_reachable[*nreachable] = strdup(usercon_str2);
- if (new_reachable[*nreachable] == NULL) {
- context_free(usercon);
- rc = -1;
- goto out;
- }
+ new_reachable[*nreachable] = usercon_str2;
+ usercon_str2 = NULL;
new_reachable[*nreachable + 1] = 0;
*nreachable += 1;
}
+ free(usercon_str2);
context_free(usercon);
start = end;
}
@@ -257,3 +257,8 @@ LIBSELINUX_3.8 {
global:
matchpathcon_filespec_add64;
} LIBSELINUX_3.5;
+
+LIBSELINUX_3.9 {
+ global:
+ context_to_str;
+} LIBSELINUX_3.8;
@@ -611,7 +611,7 @@ static int compare_types(const char *curcon, const char *newcon, char **newtypec
rc |= context_role_set(conb, context_role_get(cona));
rc |= context_range_set(conb, context_range_get(cona));
if (!rc) {
- *newtypecon = strdup(context_str(conb));
+ *newtypecon = context_to_str(conb);
if (!*newtypecon) {
rc = -1;
goto err;
@@ -34,7 +34,7 @@ int setexecfilecon(const char *filename, const char *fallback_type)
if (context_type_set(con, fallback_type))
goto out;
freecon(newcon);
- newcon = strdup(context_str(con));
+ newcon = context_to_str(con);
if (!newcon)
goto out;
}