From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from jazzdrum.ncsc.mil (zombie.ncsc.mil [144.51.88.131]) by tarius.tycho.ncsc.mil (8.13.1/8.13.1) with SMTP id l3OLGOYs013779 for ; Tue, 24 Apr 2007 17:16:24 -0400 Received: from mx1.redhat.com (jazzdrum.ncsc.mil [144.51.5.7]) by jazzdrum.ncsc.mil (8.12.10/8.12.10) with ESMTP id l3OLGNJc007278 for ; Tue, 24 Apr 2007 21:16:23 GMT Subject: Re: [PATCH 12/33] libsemanage: basic serialization From: Karl MacMillan To: jbrindle@tresys.com Cc: selinux@tycho.nsa.gov In-Reply-To: <20070423213731.972575000@tresys.com> References: <20070423213455.741326000@tresys.com> <20070423213731.972575000@tresys.com> Content-Type: text/plain Date: Tue, 24 Apr 2007 17:16:21 -0400 Message-Id: <1177449381.3428.0.camel@localhost.localdomain> Mime-Version: 1.0 Sender: owner-selinux@tycho.nsa.gov List-Id: selinux@tycho.nsa.gov On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote: > plain text document attachment (semanage.serialize.diff) > This is the serialization infrastructure for libsemanage. > We have talked about this in the past, but I think the duplication between libsemanage and libsepol should be removed. This is just ridiculous. Karl > --- > libsemanage/include/semanage/handle.h | 17 + > libsemanage/src/handle.c | 28 ++ > libsemanage/src/handle_internal.h | 5 > libsemanage/src/libsemanage.map | 1 > libsemanage/src/serialize.c | 389 ++++++++++++++++++++++++++++++++++ > libsemanage/src/serialize.h | 45 +++ > 6 files changed, 485 insertions(+) > > Index: selinux-pms-support/libsemanage/include/semanage/handle.h > =================================================================== > --- selinux-pms-support.orig/libsemanage/include/semanage/handle.h > +++ selinux-pms-support/libsemanage/include/semanage/handle.h > @@ -21,6 +21,11 @@ > #ifndef _SEMANAGE_HANDLE_H_ > #define _SEMANAGE_HANDLE_H_ > > +#define SEMANAGE_SERIAL_VERSION_MAJOR 1 > +#define SEMANAGE_SERIAL_VERSION_MINOR 0 > + > +#include > + > /* All accesses with semanage are through a "semanage_handle". The > * handle may ultimately reference local config files, > * the binary policy file, a module store, or a policy management server. > @@ -38,6 +43,18 @@ semanage_handle_t *semanage_handle_creat > * previously called if the handle was connected. */ > void semanage_handle_destroy(semanage_handle_t *); > > +/* Get the serialization version. */ > +int semanage_handle_get_version(semanage_handle_t *sh, uint32_t * major, uint32_t * minor); > + > +/* Set the serialization version. */ > +int semanage_handle_set_version(semanage_handle_t *sh, uint32_t major, uint32_t minor); > + > +/* Serialize the serialization version. */ > +int semanage_handle_version_serialize(semanage_handle_t *sh, char **data, uint64_t *size); > + > +/* Unserialize the serialization version. */ > +int semanage_handle_version_unserialize(semanage_handle_t *sh, char **data, uint64_t *size); > + > /* This is the type of connection to the store, for now only > * direct is supported */ > enum semanage_connect_type { > Index: selinux-pms-support/libsemanage/src/handle.c > =================================================================== > --- selinux-pms-support.orig/libsemanage/src/handle.c > +++ selinux-pms-support/libsemanage/src/handle.c > @@ -82,6 +82,34 @@ semanage_handle_t *semanage_handle_creat > return NULL; > } > > +int semanage_handle_get_version(semanage_handle_t *sh, uint32_t * major, uint32_t * minor) > +{ > + return sepol_handle_get_version(sh->sepolh, major, minor); > +} > + > +hidden_def(semanage_handle_get_version) > + > +int semanage_handle_set_version(semanage_handle_t *sh, uint32_t major, uint32_t minor) > +{ > + return sepol_handle_set_version(sh->sepolh, major, minor); > +} > + > +hidden_def(semanage_handle_set_version) > + > +int semanage_handle_version_serialize(semanage_handle_t *sh, char **data, uint64_t *size) > +{ > + return sepol_handle_version_serialize(sh->sepolh, data, size); > +} > + > +hidden_def(semanage_handle_version_serialize) > + > +int semanage_handle_version_unserialize(semanage_handle_t *sh, char **data, uint64_t *size) > +{ > + return sepol_handle_version_unserialize(sh->sepolh, data, size); > +} > + > +hidden_def(semanage_handle_version_unserialize) > + > void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild) > { > > Index: selinux-pms-support/libsemanage/src/handle_internal.h > =================================================================== > --- selinux-pms-support.orig/libsemanage/src/handle_internal.h > +++ selinux-pms-support/libsemanage/src/handle_internal.h > @@ -8,4 +8,9 @@ hidden_proto(semanage_begin_transaction) > hidden_proto(semanage_handle_destroy) > hidden_proto(semanage_reload_policy) > hidden_proto(semanage_access_check) > +hidden_proto(semanage_handle_get_version) > +hidden_proto(semanage_handle_set_version) > +hidden_proto(semanage_handle_version_serialize) > +hidden_proto(semanage_handle_version_unserialize) > + > #endif > Index: selinux-pms-support/libsemanage/src/libsemanage.map > =================================================================== > --- selinux-pms-support.orig/libsemanage/src/libsemanage.map > +++ selinux-pms-support/libsemanage/src/libsemanage.map > @@ -13,6 +13,7 @@ LIBSEMANAGE_1.0 { > semanage_iface_*; semanage_port_*; semanage_context_*; > semanage_node_*; > semanage_fcontext_*; semanage_access_check; semanage_set_create_store; > + semanage_*_serialize; semanage_*_unserialize; > semanage_is_connected; > local: *; > }; > Index: selinux-pms-support/libsemanage/src/serialize.c > =================================================================== > --- /dev/null > +++ selinux-pms-support/libsemanage/src/serialize.c > @@ -0,0 +1,389 @@ > +/* Author: Caleb Case > + * > + * Copyright (C) 2004-2007 Tresys Technology, LLC > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > + > +#include "handle.h" > +#include "debug.h" > +#include "serialize.h" > +#include "byteswap.h" > + > +/* This file provides general serialize and unserialize functions. */ > + > +/** Serializes various kinds of datum. > + * > + * Two use cases: > + * 1) Calling serialize with a non-NULL size. > + * This causes serialize to calculate the expected > + * size of serializing. No serialization occurs. > + * Destructively modifies size. Data may be NULL. > + * 2) Calling serialize with a NULL size. > + * This results in data being filled with the > + * serialized information. Caller must pre-allocate > + * space for data. Destructively modifies data. > + * > + * This function acts iteratively moving the *data or size values. > + * > + * Supported datum_types (defined in serialize.h): > + * > + * SEMANAGE_SERIAL_INT32_T > + * Serializes datum to a int32_t as defined in inttypes.h > + * datum may NOT be NULL. > + * datum_length is not utilized. > + * SEMANAGE_SERIAL_UINT32_T > + * Serializes datum to a uint32_t as defined in inttypes.h > + * datum may NOT be NULL. > + * datum_length is not utilized. > + * SEMANAGE_SERIAL_SIZE_T > + * Serializes datum to a size_t as defined in stddef.h > + * datum may NOT be NULL. > + * datum_length is not utilized. > + * SEMANAGE_SERIAL_STRING > + * Serializes a char*. > + * datum may be NULL. > + * datum_length should be the length of the string as returned by strlen. > + * SEMANAGE_SERIAL_STRING_ARRAY > + * Serializes a char**. > + * datum may be NULL. > + * datum_length should be the size of the array. > + * Each string will be serialized as per SEMANAGE_SERIAL_STRING and its size > + * determined via strlen. > + * > + * NULL pointers are distinguished (where they are allowed at all). > + * In the case of strings this means that a NULL char* has a different > + * serialization from the empty string "". > + * > + */ > +int semanage_serialize(semanage_handle_t * handle, > + const void *datum, > + size_t datum_length, > + unsigned int datum_type, char **data, uint64_t * size) > +{ > + int status; > + unsigned int flags; > + uint32_t i; > + void *temp = NULL; > + > + switch (datum_type) { > + case SEMANAGE_SERIAL_INT32_T: > + case SEMANAGE_SERIAL_UINT32_T: > + if (size == NULL) { > + temp = calloc(1, sizeof(int32_t)); > + if (temp == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + *((int32_t *)temp) = cpu_to_le32(*((int32_t *) datum)); > + memcpy(*data, temp, sizeof(int32_t)); > + *data += sizeof(int32_t); > + } > + else > + *size += sizeof(int32_t); > + break; > + case SEMANAGE_SERIAL_SIZE_T: > + if (size == NULL) { > + temp = calloc(1, sizeof(uint64_t)); > + if (temp == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + *((uint64_t *)temp) = cpu_to_le64(*((size_t *) datum)); > + > + memcpy(*data, temp, sizeof(uint64_t)); > + *data += sizeof(uint64_t); > + } > + else > + *size += sizeof(uint64_t); > + break; > + case SEMANAGE_SERIAL_STRING: > + /* Flags (intended as a bitmap): > + * 0 == NULL > + * 1 == Non NULL > + */ > + flags = (datum == NULL) ? 0 : 1; > + > + status = > + semanage_serialize(handle, &flags, 0, SEMANAGE_SERIAL_UINT32_T, data, > + size); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Write if not null. */ > + if (flags & 1) { > + /* Size. */ > + status = > + semanage_serialize(handle, &datum_length, 0, > + SEMANAGE_SERIAL_SIZE_T, data, size); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Datum. */ > + if (size == NULL) { > + status = > + snprintf(*data, datum_length + 1, "%s", > + (char *)datum); > + if (status < 0 || (unsigned)status > datum_length) > + goto cleanup; > + else { > + *data += status + 1; > + status = STATUS_SUCCESS; > + } > + } else { > + *size += datum_length + 1; > + } > + } > + break; > + case SEMANAGE_SERIAL_STRING_ARRAY: > + /* Flags (intended as a bitmap): > + * 0 == NULL > + * 1 == Non NULL > + */ > + flags = (datum == NULL) ? 0 : 1; > + > + status = > + semanage_serialize(handle, &flags, 0, SEMANAGE_SERIAL_UINT32_T, data, > + size); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Write if not null. */ > + if (flags & 1) { > + /* Size. */ > + status = > + semanage_serialize(handle, &datum_length, 0, > + SEMANAGE_SERIAL_UINT32_T, data, size); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Datum. */ > + for (i = 0; i < datum_length; i++) { > + status = > + semanage_serialize(handle, ((char **)datum)[i], > + strlen(((char **)datum)[i]), > + SEMANAGE_SERIAL_STRING, data, size); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + } > + } > + break; > + default: > + status = STATUS_ERR; > + goto cleanup; > + } > + > + /* Cleanup. */ > + status = STATUS_SUCCESS; > +cleanup: > + free(temp); > + return status; > +} > + > +/** Unserializes various kinds of datum as serialized by semanage_serialize. > + * > + * This function acts iteratively moving the *data AND size values. > + * size is decremented as data is unserialized. > + * > + * It also allocates memory for datum and, depending on datum_type, datum_length. > + * Caller must free. > + * > + * Supported datum_types (defined in serialize.h): > + * > + * SEMANAGE_SERIAL_INT32_T > + * Unserializes data into an int32_t as defined in inttypes.h. > + * datum_length may be NULL. > + * SEMANAGE_SERIAL_UINT32_T > + * Unserializes data into an uint32_t as defined in inttypes.h. > + * datum_length may be NULL. > + * SEMANAGE_SERIAL_SIZE_T > + * Unserializes data into an size_t as defined in stddef.h. > + * datum_length may be NULL. > + * SEMANAGE_SERIAL_STRING > + * Unserializes data into a NULL terminated char*. > + * datum_length may NOT be NULL and will be the size of the string. > + * SEMANAGE_SERIAL_STRING_ARRAY > + * Unserializes data into a char**. > + * Each entry in the array will be unserialized as per SEMANAGE_SERIAL_STRING. > + * datum_length may NOT be NULL and will be the size of the array. > + */ > +int semanage_unserialize(semanage_handle_t * handle, > + char **data, uint64_t * size, > + void **datum, > + size_t ** datum_length, > + unsigned int datum_type) > +{ > + int status; > + unsigned int *flags = NULL; > + uint32_t i; > + void *temp = NULL; > + size_t *temp_length = NULL; > + > + switch (datum_type) { > + case SEMANAGE_SERIAL_INT32_T: > + case SEMANAGE_SERIAL_UINT32_T: > + *datum = calloc(1, sizeof(int32_t)); > + if (*datum == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + memcpy(*datum, *data, sizeof(int32_t)); > + **((int32_t **)datum) = le32_to_cpu(**((int32_t **) datum)); > + > + *size -= sizeof(int32_t); > + *data += sizeof(int32_t); > + break; > + case SEMANAGE_SERIAL_SIZE_T: > + temp = calloc(1, sizeof(uint64_t)); > + if (temp == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + memcpy(temp, *data, sizeof(uint64_t)); > + > + *((uint64_t *) temp) = le64_to_cpu(*((uint64_t *) temp)); > + > + if (*((uint64_t *) temp) > UINT_MAX) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + *datum = calloc(1, sizeof(size_t)); > + if (datum == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + **((size_t **)datum) = *((uint64_t *) temp); > + > + *size -= sizeof(uint64_t); > + *data += sizeof(uint64_t); > + break; > + case SEMANAGE_SERIAL_STRING: > + /* Flags (intended as a bitmap): > + * 0 == NULL > + * 1 == Non NULL > + */ > + status = > + semanage_unserialize(handle, > + data, size, > + (void **)(&flags), NULL, > + SEMANAGE_SERIAL_UINT32_T); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + if (*flags & 1) { > + /* Size. */ > + status = > + semanage_unserialize(handle, > + data, size, > + (void **)datum_length, NULL, > + SEMANAGE_SERIAL_SIZE_T); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Datum. */ > + *datum = calloc(**datum_length + 1, sizeof(char)); > + if (*datum == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + memcpy(*datum, *data, **datum_length + 1); > + > + *size -= **datum_length + 1; > + *data += **datum_length + 1; > + } else { > + *datum = NULL; > + *datum_length = NULL; > + } > + > + free(flags); > + flags = NULL; > + break; > + case SEMANAGE_SERIAL_STRING_ARRAY: > + /* Flags (intended as a bitmap): > + * 0 == NULL > + * 1 == Non NULL > + */ > + status = > + semanage_unserialize(handle, > + data, size, > + (void **)(&flags), NULL, > + SEMANAGE_SERIAL_UINT32_T); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Write if not null. */ > + if (*flags & 1) { > + /* Size. */ > + status = > + semanage_unserialize(handle, > + data, size, > + (void **)datum_length, NULL, > + SEMANAGE_SERIAL_UINT32_T); > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + /* Datum. */ > + *datum = > + calloc(sizeof(char *), > + sizeof(char *) * (**datum_length)); > + if (*datum == NULL) { > + status = STATUS_ERR; > + goto cleanup; > + } > + > + for (i = 0; i < **datum_length; i++) { > + status = semanage_unserialize(handle, > + data, > + size, > + (void **)&(((char **)(*datum))[i]), > + &temp_length, > + SEMANAGE_SERIAL_STRING); > + > + if (status != STATUS_SUCCESS) > + goto cleanup; > + > + free(temp_length); > + temp_length = NULL; > + } > + } > + > + free(flags); > + flags = NULL; > + break; > + default: > + status = STATUS_ERR; > + goto cleanup; > + } > + > + /* Cleanup. */ > + status = STATUS_SUCCESS; > +cleanup: > + free(flags); > + free(temp); > + free(temp_length); > + return status; > +} > + > Index: selinux-pms-support/libsemanage/src/serialize.h > =================================================================== > --- /dev/null > +++ selinux-pms-support/libsemanage/src/serialize.h > @@ -0,0 +1,45 @@ > +/* Author: Caleb Case > + * > + * Copyright (C) 2005-2007 Tresys Technology, LLC > + * Copyright (C) 2005 Red Hat Inc. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#ifndef _SEMANAGE_SERIALIZE_INTERNAL_H_ > +#define _SEMANAGE_SERIALIZE_INTERNAL_H_ > + > +#include > +#include "handle.h" > + > +/* Datum types. */ > +#define SEMANAGE_SERIAL_INT32_T 0 > +#define SEMANAGE_SERIAL_UINT32_T 1 > +#define SEMANAGE_SERIAL_SIZE_T 2 > +#define SEMANAGE_SERIAL_STRING 3 > +#define SEMANAGE_SERIAL_STRING_ARRAY 4 > + > +int semanage_serialize(semanage_handle_t * handle, > + const void *datum, > + size_t datum_size, > + unsigned int datum_type, char **data, uint64_t * size); > + > +int semanage_unserialize(semanage_handle_t * handle, > + char **data, uint64_t * size, > + void **datum, > + size_t ** datum_length, > + unsigned int datum_type); > + > +#endif > -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message.