gst/gstregistrybinary.*: Add crc32 checksum to the binary registry file and check this before accepting a registry file.

Original commit message from CVS:
* gst/gstregistrybinary.c: (_gst_crc32),
(gst_registry_binary_write),
(gst_registry_binary_initialize_magic),
(gst_registry_binary_write_cache),
(gst_registry_binary_check_magic),
(gst_registry_binary_read_cache):
* gst/gstregistrybinary.h:
Add crc32 checksum to the binary registry file and check this before
accepting a registry file.
Also free the data list when writing to the registry file fails.
This commit is contained in:
Sebastian Dröge 2008-04-16 14:18:58 +00:00
parent dc71d29b62
commit 550392c6da
3 changed files with 192 additions and 22 deletions

View file

@ -1,3 +1,17 @@
2008-04-16 Sebastian Dröge <slomo@circular-chaos.org>
* gst/gstregistrybinary.c: (_gst_crc32),
(gst_registry_binary_write),
(gst_registry_binary_initialize_magic),
(gst_registry_binary_write_cache),
(gst_registry_binary_check_magic),
(gst_registry_binary_read_cache):
* gst/gstregistrybinary.h:
Add crc32 checksum to the binary registry file and check this before
accepting a registry file.
Also free the data list when writing to the registry file fails.
2008-04-16 Sebastian Dröge <slomo@circular-chaos.org> 2008-04-16 Sebastian Dröge <slomo@circular-chaos.org>
* gst/gstregistrybinary.c: (gst_registry_binary_save_feature), * gst/gstregistrybinary.c: (gst_registry_binary_save_feature),

View file

@ -22,8 +22,6 @@
*/ */
/* FIXME: /* FIXME:
* - Add random key to libgstreamer during build and only accept registry,
* if key matches (or is the version check enough)
* - keep registry binary blob and reference strings * - keep registry binary blob and reference strings
* - don't free/unmmap contents when leaving gst_registry_binary_read_cache() * - don't free/unmmap contents when leaving gst_registry_binary_read_cache()
* - free at gst_deinit() / _priv_gst_registry_cleanup() ? * - free at gst_deinit() / _priv_gst_registry_cleanup() ?
@ -37,7 +35,6 @@
* in parent chunk * in parent chunk
* - need more robustness * - need more robustness
* - don't parse beyond mem-block size * - don't parse beyond mem-block size
* - include md5-sum ?
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -93,6 +90,126 @@
#define align(_ptr) _ptr += (( alignment(_ptr) == 0) ? 0 : ALIGNMENT-alignment(_ptr)) #define align(_ptr) _ptr += (( alignment(_ptr) == 0) ? 0 : ALIGNMENT-alignment(_ptr))
/* CRC32 calculation */
/* The crc32() function is copyrighted and licensed as specified below.
* This only applies to this single function:
crc32.c -- compute the CRC-32 of a data stream
Copyright (C) 1995-1998 Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
*/
/* Changes for gstreamer:
* - Changed to use GLib data types
* - Change function name to _gst_crc32
*/
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
static const guint32 crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((gint)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
static guint32
_gst_crc32 (guint32 crc, const gchar * buf, guint len)
{
if (buf == NULL)
return 0L;
crc = crc ^ 0xffffffffL;
while (len >= 8) {
DO8 (buf);
len -= 8;
}
if (len)
do {
DO1 (buf);
} while (--len);
return crc ^ 0xffffffffL;
}
#undef DO1
#undef DO2
#undef DO4
#undef DO8
/* Registry saving */ /* Registry saving */
/* /*
@ -104,7 +221,8 @@
*/ */
inline static gboolean inline static gboolean
gst_registry_binary_write (GstRegistry * registry, const void *mem, gst_registry_binary_write (GstRegistry * registry, const void *mem,
const gssize size, unsigned long *file_position, gboolean align) const gssize size, unsigned long *file_position, gboolean align,
guint32 * crc32)
{ {
gchar padder[ALIGNMENT] = { 0, }; gchar padder[ALIGNMENT] = { 0, };
int padsize = 0; int padsize = 0;
@ -116,6 +234,8 @@ gst_registry_binary_write (GstRegistry * registry, const void *mem,
GST_ERROR ("Failed to write binary registry padder"); GST_ERROR ("Failed to write binary registry padder");
return FALSE; return FALSE;
} }
if (padsize > 0)
*crc32 = _gst_crc32 (*crc32, padder, padsize);
*file_position = *file_position + padsize; *file_position = *file_position + padsize;
} }
@ -123,6 +243,9 @@ gst_registry_binary_write (GstRegistry * registry, const void *mem,
GST_ERROR ("Failed to write binary registry element"); GST_ERROR ("Failed to write binary registry element");
return FALSE; return FALSE;
} }
if (size > 0)
*crc32 = _gst_crc32 (*crc32, mem, size);
*file_position = *file_position + size; *file_position = *file_position + size;
return TRUE; return TRUE;
} }
@ -144,6 +267,9 @@ gst_registry_binary_initialize_magic (GstBinaryRegistryMagic * m)
GST_ERROR ("Failed to write magic to the registry magic structure"); GST_ERROR ("Failed to write magic to the registry magic structure");
return FALSE; return FALSE;
} }
m->crc32 = 0;
return TRUE; return TRUE;
} }
@ -458,8 +584,7 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
{ {
GList *walk; GList *walk;
gchar *tmp_location; gchar *tmp_location;
GstBinaryRegistryMagic *magic; GstBinaryRegistryMagic magic;
GstBinaryChunk *magic_chunk;
GList *to_write = NULL; GList *to_write = NULL;
unsigned long file_position = 0; unsigned long file_position = 0;
@ -488,16 +613,9 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
} }
} }
magic = g_malloc (sizeof (GstBinaryRegistryMagic)); if (!gst_registry_binary_initialize_magic (&magic))
if (!gst_registry_binary_initialize_magic (magic))
goto fail; goto fail;
magic_chunk = g_malloc (sizeof (GstBinaryChunk));
magic_chunk->data = magic;
magic_chunk->size = sizeof (GstBinaryRegistryMagic);
magic_chunk->flags = GST_BINARY_REGISTRY_FLAG_NONE;
magic_chunk->align = TRUE;
/* iterate trough the list of plugins and fit them into binary structures */ /* iterate trough the list of plugins and fit them into binary structures */
for (walk = registry->plugins; walk; walk = g_list_next (walk)) { for (walk = registry->plugins; walk; walk = g_list_next (walk)) {
GstPlugin *plugin = GST_PLUGIN (walk->data); GstPlugin *plugin = GST_PLUGIN (walk->data);
@ -521,28 +639,44 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
plugin->filename); plugin->filename);
} }
} }
to_write = g_list_prepend (to_write, magic_chunk);
GST_INFO ("Writing binary registry cache"); GST_INFO ("Writing binary registry cache");
/* write magic */
if (write (registry->cache_file, &magic,
sizeof (GstBinaryRegistryMagic)) != sizeof (GstBinaryRegistryMagic)) {
GST_ERROR ("Failed to write binary registry magic");
goto fail_free_list;
}
file_position += sizeof (GstBinaryRegistryMagic);
/* write out data chunks */ /* write out data chunks */
for (walk = to_write; walk; walk = g_list_next (walk)) { for (walk = to_write; walk; walk = g_list_next (walk)) {
GstBinaryChunk *cur = walk->data; GstBinaryChunk *cur = walk->data;
if (!gst_registry_binary_write (registry, cur->data, cur->size, if (!gst_registry_binary_write (registry, cur->data, cur->size,
&file_position, cur->align)) { &file_position, cur->align, &magic.crc32)) {
if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST)) if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST))
g_free (cur->data); g_free (cur->data);
g_free (cur); g_free (cur);
g_list_free (to_write); walk->data = NULL;
goto fail; goto fail_free_list;
} }
if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST)) if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST))
g_free (cur->data); g_free (cur->data);
g_free (cur); g_free (cur);
walk->data = NULL;
} }
g_list_free (to_write); g_list_free (to_write);
if (lseek (registry->cache_file, 0, SEEK_SET) != 0) {
GST_ERROR ("Seeking to rewrite the binary registry CRC32 failed");
} else {
if (write (registry->cache_file, &magic,
sizeof (GstBinaryRegistryMagic)) != sizeof (GstBinaryRegistryMagic))
GST_ERROR ("Failed to rewrite binary registry magic");
}
if (close (registry->cache_file) < 0) if (close (registry->cache_file) < 0)
goto close_failed; goto close_failed;
@ -561,6 +695,18 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
return TRUE; return TRUE;
/* Errors */ /* Errors */
fail_free_list:
{
for (walk = to_write; walk; walk = g_list_next (walk)) {
GstBinaryChunk *cur = walk->data;
if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST))
g_free (cur->data);
g_free (cur);
}
g_list_free (to_write);
/* fall through */
}
fail: fail:
{ {
(void) close (registry->cache_file); (void) close (registry->cache_file);
@ -596,9 +742,10 @@ rename_failed:
* date, -1 is a general failure. * date, -1 is a general failure.
*/ */
static gint static gint
gst_registry_binary_check_magic (gchar ** in) gst_registry_binary_check_magic (gchar ** in, gsize size)
{ {
GstBinaryRegistryMagic *m; GstBinaryRegistryMagic *m;
guint32 crc32 = 0;
align (*in); align (*in);
GST_DEBUG ("Reading/casting for GstBinaryRegistryMagic at address %p", *in); GST_DEBUG ("Reading/casting for GstBinaryRegistryMagic at address %p", *in);
@ -625,6 +772,14 @@ gst_registry_binary_check_magic (gchar ** in)
GST_MAGIC_BINARY_VERSION_STR, m->version); GST_MAGIC_BINARY_VERSION_STR, m->version);
return -2; return -2;
} }
crc32 = _gst_crc32 (crc32, *in, size - sizeof (GstBinaryRegistryMagic));
if (crc32 != m->crc32) {
GST_WARNING ("Binary registry CRC32 different: 0x%x != 0x%x\n", crc32,
m->crc32);
return -1;
}
return 0; return 0;
} }
@ -939,7 +1094,7 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
goto Error; goto Error;
} }
/* check if header is valid */ /* check if header is valid */
if ((check_magic_result = gst_registry_binary_check_magic (&in)) < 0) { if ((check_magic_result = gst_registry_binary_check_magic (&in, size)) < 0) {
if (check_magic_result == -1) if (check_magic_result == -1)
GST_ERROR GST_ERROR

View file

@ -57,7 +57,7 @@
* This _must_ be updated whenever the registry format changes, * This _must_ be updated whenever the registry format changes,
* we currently use the core version where this change happened. * we currently use the core version where this change happened.
*/ */
#define GST_MAGIC_BINARY_VERSION_STR ("0.10.18.1") #define GST_MAGIC_BINARY_VERSION_STR ("0.10.18.2")
/* /*
* GST_MAGIC_BINARY_VERSION_LEN: * GST_MAGIC_BINARY_VERSION_LEN:
@ -70,6 +70,7 @@ typedef struct _GstBinaryRegistryMagic
{ {
gchar magic[GST_MAGIC_BINARY_REGISTRY_LEN]; gchar magic[GST_MAGIC_BINARY_REGISTRY_LEN];
gchar version[GST_MAGIC_BINARY_VERSION_LEN]; gchar version[GST_MAGIC_BINARY_VERSION_LEN];
guint32 crc32;
} GstBinaryRegistryMagic; } GstBinaryRegistryMagic;
/* /*