Пример #1
0
static gboolean
_read_header(SerializeArchive *sa, NVTable **nvtable)
{
  g_assert(*nvtable == NULL);

  NVTable *res = (NVTable *)g_malloc(sizeof(NVTable));
  if (!serialize_read_uint32(sa, &res->size))
    {
      goto error;
    }
  if (!serialize_read_uint32(sa, &res->used))
    {
      goto error;
    }
  if (!serialize_read_uint16(sa, &res->num_dyn_entries))
    {
      goto error;
    }
  if (!serialize_read_uint8(sa, &res->num_static_entries))
    {
      goto error;
    }

  res = (NVTable *)g_realloc(res, res->size);
  res->borrowed = FALSE;
  res->ref_cnt = 1;
  *nvtable = res;
  return TRUE;

error:
  if (res)
    g_free(res);
  return FALSE;
}
Пример #2
0
static gboolean
_read_header(SerializeArchive *sa, NVTable **nvtable)
{
  NVTable *res = NULL;
  guint32 size;

  g_assert(*nvtable == NULL);

  if (!serialize_read_uint32(sa, &size))
    goto error;

  if (size > NV_TABLE_MAX_BYTES)
    goto error;

  res = (NVTable *) g_malloc(size);
  res->size = size;

  if (!serialize_read_uint32(sa, &res->used))
    goto error;

  if (!serialize_read_uint16(sa, &res->index_size))
    goto error;

  if (!serialize_read_uint8(sa, &res->num_static_entries))
    goto error;

  /* static entries has to be known by this syslog-ng, if they are over
   * LM_V_MAX, that means we have no clue how an entry is called, as static
   * entries don't contain names.  If there are less static entries, that
   * can be ok. */

  if (res->num_static_entries > LM_V_MAX)
    goto error;

  /* validates self->used and self->index_size value as compared to "size" */
  if (!nv_table_alloc_check(res, 0))
    goto error;

  res->borrowed = FALSE;
  res->ref_cnt = 1;
  *nvtable = res;
  return TRUE;

error:
  if (res)
    g_free(res);
  return FALSE;
}
Пример #3
0
static gboolean
_read_log_stamp(SerializeArchive *sa, UnixTime *stamp)
{
  guint64 val64;
  guint32 val;

  if (!serialize_read_uint64(sa, &val64))
    return FALSE;
  stamp->ut_sec = (gint64) val64;

  if (!serialize_read_uint32(sa, &val))
    return FALSE;
  stamp->ut_usec = val;

  if (!serialize_read_uint32(sa, &val))
    return FALSE;
  stamp->ut_gmtoff = (gint) val;
  return TRUE;
}
Пример #4
0
static gboolean
_read_log_stamp(SerializeArchive *sa, LogStamp *stamp)
{
  guint64 val64;
  guint32 val;

  if (!serialize_read_uint64(sa, &val64))
    return FALSE;
  stamp->tv_sec = (gint64) val64;

  if (!serialize_read_uint32(sa, &val))
    return FALSE;
  stamp->tv_usec = val;

  if (!serialize_read_uint32(sa, &val))
    return FALSE;
  stamp->zone_offset = (gint) val;
  return TRUE;
}
Пример #5
0
static gboolean
_deserialize_static_entries(SerializeArchive *sa, NVTable *res)
{
  guint32 i;
  for (i = 0; i < res->num_static_entries; i++)
     {
       if (!serialize_read_uint32(sa, &res->static_entries[i]))
         return FALSE;
     }
  return TRUE;
}
Пример #6
0
static gboolean
log_proto_buffered_server_convert_state(LogProtoBufferedServer *self, guint8 persist_version, gpointer old_state, gsize old_state_size, LogProtoBufferedServerState *state)
{
  if (persist_version <= 2)
    {
      state->header.version = 0;
      state->file_inode = 0;
      state->raw_stream_pos = strtoll((gchar *) old_state, NULL, 10);
      state->file_size = 0;

      return TRUE;
    }
  else if (persist_version == 3)
    {
      SerializeArchive *archive;
      guint32 read_length;
      gint64 cur_size;
      gint64 cur_inode;
      gint64 cur_pos;
      guint16 version;
      gchar *buffer;
      gsize buffer_len;

      cur_inode = -1;
      cur_pos = 0;
      cur_size = 0;
      archive = serialize_buffer_archive_new(old_state, old_state_size);

      /* NOTE: the v23 conversion code adds an extra length field which we
       * need to read out. */
      g_assert(serialize_read_uint32(archive, &read_length) && read_length == old_state_size - sizeof(read_length));

      /* original v3 format starts here */
      if (!serialize_read_uint16(archive, &version) || version != 0)
        {
          msg_error("Internal error restoring log reader state, stored data has incorrect version",
                    evt_tag_int("version", version));
          goto error_converting_v3;
        }

      if (!serialize_read_uint64(archive, (guint64 *) &cur_pos) ||
          !serialize_read_uint64(archive, (guint64 *) &cur_inode) ||
          !serialize_read_uint64(archive, (guint64 *) &cur_size))
        {
          msg_error("Internal error restoring information about the current file position, restarting from the beginning");
          goto error_converting_v3;
        }

      if (!serialize_read_uint16(archive, &version) || version != 0)
        {
          msg_error("Internal error, protocol state has incorrect version",
                    evt_tag_int("version", version));
          goto error_converting_v3;
        }

      if (!serialize_read_cstring(archive, &buffer, &buffer_len))
        {
          msg_error("Internal error, error reading buffer contents",
                    evt_tag_int("version", version));
          goto error_converting_v3;
        }

      if (!self->buffer || state->buffer_size < buffer_len)
        {
          gsize buffer_size = MAX(self->super.options->init_buffer_size, buffer_len);
          self->buffer = g_realloc(self->buffer, buffer_size);
        }
      serialize_archive_free(archive);

      memcpy(self->buffer, buffer, buffer_len);
      state->buffer_pos = 0;
      state->pending_buffer_end = buffer_len;
      g_free(buffer);

      state->header.version = 0;
      state->file_inode = cur_inode;
      state->raw_stream_pos = cur_pos;
      state->file_size = cur_size;
      return TRUE;
    error_converting_v3:
      serialize_archive_free(archive);
    }
  return FALSE;
}
Пример #7
0
static inline gboolean
_read_magic(SerializeArchive *sa, guint32 *magic)
{
  return serialize_read_uint32(sa, magic);
}
Пример #8
0
static gboolean
_deserialize_dyn_value(SerializeArchive *sa, NVDynValue* dyn_value)
{
  return serialize_read_nvhandle(sa, &(dyn_value->handle)) &&
         serialize_read_uint32(sa, &(dyn_value->ofs));
};
Пример #9
0
static gboolean
_load_v4(PersistState *self, gboolean load_all_entries)
{
  gint fd;
  gint64 file_size;
  gpointer map;
  gpointer key_block;
  guint32 key_size;
  PersistFileHeader *header;
  gint key_count, i;

  fd = open(self->commited_filename, O_RDONLY);
  if (fd < 0)
    {
      /* no previous data found */
      return TRUE;
    }

  file_size = lseek(fd, 0, SEEK_END);
  if (file_size > ((1LL << 31) - 1))
    {
      msg_error("Persistent file too large",
                evt_tag_str("filename", self->commited_filename),
                evt_tag_printf("size", "%" G_GINT64_FORMAT, file_size),
                NULL);
      return FALSE;
    }
  map = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fd, 0);
  close(fd);
  if (map == MAP_FAILED)
    {
      msg_error("Error mapping persistent file into memory",
                evt_tag_str("filename", self->commited_filename),
                evt_tag_errno("error", errno),
                NULL);
      return FALSE;
    }
  header = (PersistFileHeader *) map;

  key_block = ((gchar *) map) + offsetof(PersistFileHeader, initial_key_store);
  key_size = sizeof((((PersistFileHeader *) NULL))->initial_key_store);

  key_count = GUINT32_FROM_BE(header->key_count);
  i = 0;
  while (i < key_count)
    {
      gchar *name;
      guint32 entry_ofs, chain_ofs;
      SerializeArchive *sa;

      sa = serialize_buffer_archive_new(key_block, key_size);
      while (i < key_count)
        {
          if (!serialize_read_cstring(sa, &name, NULL))
            {
              serialize_archive_free(sa);
              msg_error("Persistent file format error, unable to fetch key name",
                        NULL);
              goto free_and_exit;
            }
          if (name[0])
            {
              if (serialize_read_uint32(sa, &entry_ofs))
                {
                  PersistValueHeader *value_header;
                  i++;

                  if (entry_ofs < sizeof(PersistFileHeader) || entry_ofs > file_size)
                    {
                      serialize_archive_free(sa);
                      g_free(name);
                      msg_error("Persistent file format error, entry offset is out of bounds",
                                NULL);
                      goto free_and_exit;
                    }

                  value_header = (PersistValueHeader *) ((gchar *) map + entry_ofs - sizeof(PersistValueHeader));
                  if ((value_header->in_use) || load_all_entries)
                    {
                      gpointer new_block;
                      PersistEntryHandle new_handle;

                      new_handle = _alloc_value(self, GUINT32_FROM_BE(value_header->size), FALSE, value_header->version);
                      new_block = persist_state_map_entry(self, new_handle);
                      memcpy(new_block, value_header + 1, GUINT32_FROM_BE(value_header->size));
                      persist_state_unmap_entry(self, new_handle);
                      /* add key to the current file */
                      _add_key(self, name, new_handle);
                    }
                  g_free(name);
                }
              else
                {
                  /* bad format */
                  serialize_archive_free(sa);
                  g_free(name);
                  msg_error("Persistent file format error, unable to fetch key name",
                            NULL);
                  goto free_and_exit;
                }
            }
          else
            {
              g_free(name);
              if (serialize_read_uint32(sa, &chain_ofs))
                {
                  /* end of block, chain to the next one */
                  if (chain_ofs == 0 || chain_ofs > file_size)
                    {
                      msg_error("Persistent file format error, key block chain offset is too large or zero",
                                evt_tag_printf("key_block", "%08lx", (gulong) ((gchar *) key_block - (gchar *) map)),
                                evt_tag_printf("key_size", "%d", key_size),
                                evt_tag_int("ofs", chain_ofs),
                                NULL);
                      serialize_archive_free(sa);
                      goto free_and_exit;
                    }
                  key_block = ((gchar *) map) + chain_ofs;
                  key_size = GUINT32_FROM_BE(*(guint32 *) (((gchar *) key_block) - sizeof(PersistValueHeader)));
                  if (chain_ofs + key_size > file_size)
                    {
                      msg_error("Persistent file format error, key block size is too large",
                                evt_tag_int("key_size", key_size),
                                NULL);
                      serialize_archive_free(sa);
                      goto free_and_exit;
                    }
                  break;
                }
              else
                {
                  serialize_archive_free(sa);
                  msg_error("Persistent file format error, unable to fetch chained key block offset",
                            NULL);
                  goto free_and_exit;
                }
            }
        }
      serialize_archive_free(sa);
    }
 free_and_exit:
  munmap(map, file_size);
  return TRUE;
}