Compare commits

..
28 Commits
Author SHA1 Message Date
Alex Jaramillo 3a73ca4e75 Insure body is null terminated
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-01 10:02:15 -07:00
Alex Jaramillo b506773879 Add missing free
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-01 10:02:15 -07:00
Alex Jaramillo 3b3f882c3a Include null terminator from str
memcpy should copy the null terminator too. The code as it is works
because the destination has null terminators, but we should not relly on
those. We should copy the str and it's null termination.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-31 21:07:42 -07:00
Alex Jaramillo 4f97b51f10 Handle curl_easy_setopt return codes
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-31 21:07:42 -07:00
Alex Jaramillo f3e29b5e5a TOCTOU mitigation
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-31 21:07:42 -07:00
Alex Jaramillo 5820a1b959 Fix potential resource leak
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-31 21:07:42 -07:00
Alex Jaramillo 44d423a7c4 Use correct license file name in make dist
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-27 10:11:22 -07:00
Alex Jaramillo 1bcaf35a6c Make the license detectable
This change updates the project's license file to ensure it is detectable
by GitHub, enhancing its visibility on the project landing page.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-27 09:35:45 -07:00
Alex Jaramillo 00556dde05 Update github action
- Use latest version of checkout action.
- Checkout the head of the PR commit.
- Install json-c dependency.
- Use libcheck from OS.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-27 09:15:55 -07:00
Alex Jaramillo d162311e31 telemetry.c: improvements
- tm_set_payload: check payload for NULL value before duplication, this
  is desirable due the use of strnlen and strndup.

- tm_set_payload: replace strlen with strnlen to use MAX_PAYLOAD_LENGTH
  during function call instead of checking after the fact.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-19 15:35:45 -07:00
Alex Jaramillo f23bc1ae12 configure.ac: bump version
Replace clear text record format with json to transmit records to
telemetry collector.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-13 18:32:18 -07:00
Brett T. Warden d0ee68ba43 Publish a JSON message to telemetry server
Replace the custom HTTP headers and plain text payload with a JSON
object. This is the new v3 API implementation.
2025-03-10 12:06:12 -07:00
Brett T. Warden 9bb9288153 Link telemetry post daemon against json-c
also link its test
2025-03-10 12:06:12 -07:00
Brett T. Warden b9ec06fe9a Check for json-c
json-c is now required, in order to construct the JSON payload.
2025-03-10 12:06:12 -07:00
Brett T. Warden 32b306daa9 Update default URL API to v3
Updating the HTTP API from v2 to v3 to support JSON message
encapsulation instead of custom HTTP headers with a single-field POST
field for the payload.
2025-03-10 12:06:12 -07:00
Alex Jaramillo c3b8d81b6d configure.ac: bump version
Increase the version to 2.3.5 to release fix for missing records in
journal and preempt klogscanner service start inside containers.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2020-02-24 21:37:06 +00:00
Alex Jaramillo f4f012af7b fix first record missing from journal
This change fixes the condition when the first record after telempostd
starts is not inserted in the telemetry journal.

Notice! there is a change in the logic, while previously records
where inserted to juornal as soon the record was processed. After this
change records will be inserted in the journal only when successfully
delivered or record_server_delivery_enabled is set to false.
2020-02-24 13:27:32 -08:00
Thiago Macieira 9db4e1d8c9 Don't try to start the klogscanner service inside a container
We can't access the klog.

● klogscanner.service - Telemetrics Kernel Log Scanner
     Loaded: loaded (/usr/lib/systemd/system/klogscanner.service; disabled; vendor preset: disabled)
     Active: failed (Result: exit-code) since Fri 2020-01-31 10:44:58 PST; 8min ago
    Process: 21 ExecStart=/usr/bin/klogscanner (code=exited, status=1/FAILURE)
   Main PID: 21 (code=exited, status=1/FAILURE)

Jan 31 10:44:58 <MACHINENAME> systemd[1]: Started Telemetrics Kernel Log Scanner.
Jan 31 10:44:58 <MACHINENAME> klogscanner[21]: ERROR: Cannot read size of kernel ring buffer: Operation not permitted
Jan 31 10:44:58 <MACHINENAME> systemd[1]: klogscanner.service: Main process exited, code=exited, status=1/FAILURE
Jan 31 10:44:58 <MACHINENAME> systemd[1]: klogscanner.service: Failed with result 'exit-code'.
2020-02-05 10:06:08 -08:00
Alex Jaramillo a0efa230b7 configure.ac: bump version
Increase the version to 2.3.4 to release CI configuration changes,
memory leaks fixes, and crash probe frame counter fix.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2020-01-30 21:58:59 +00:00
Juro Bystricky f14d6ff4c5 crash_probe.c: process_corefile: reset frame counter
process_corefile may be called twice due to retry logic.
Make sure frame_counter is initialized each time.

Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
2020-01-30 13:11:26 -08:00
Alex Jaramillo b61b152cb0 replace travis badge for github workflows 2020-01-27 11:05:46 -08:00
Alex Jaramillo ee25d1568d random shift to hprobe timer 2020-01-24 10:47:55 -08:00
avjarami 622fcfca10 pr comments and actions update 2020-01-22 16:08:15 -08:00
avjarami 33609c5607 update CI configuration 2020-01-22 16:08:15 -08:00
avjarami 8ebc882955 fix potential leaks 2020-01-22 16:08:15 -08:00
avjarami d30eb663b3 fixing memory leaks in tests 2020-01-22 16:08:15 -08:00
avjarami 885e325e1e valgrind check for tests 2020-01-22 16:08:15 -08:00
avjarami fffe18a96b Trigger verification on PR opening 2020-01-22 18:03:24 +00:00
32 changed files with 604 additions and 169 deletions
+9 -9
View File
@@ -1,6 +1,6 @@
name: C/C++ CI
on: [push]
on: [push, pull_request]
jobs:
build:
@@ -8,15 +8,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: install dependencies
run: sudo apt-get install libcurl4-gnutls-dev valgrind libelf-dev libdw-dev
- name: install check
run: wget https://github.com/libcheck/check/releases/download/0.12.0/check-0.12.0.tar.gz &&
tar xf check-0.12.0.tar.gz &&
pushd check-0.12.0 &&
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu &&
make -j8 && sudo make install && popd
run: |
sudo apt-get update
sudo apt-get --fix-missing install libcurl4-gnutls-dev valgrind libelf-dev libdw-dev libjson-c-dev check
- name: autogen
run: sh autogen.sh
- name: configure
@@ -25,5 +23,7 @@ jobs:
run: make -j8
- name: check
run: make check
- name: valgrind memcheck
run: make check-valgrind
- name: make distcheck
run: make distcheck
+1
View File
@@ -35,6 +35,7 @@ build-aux/m4/ltversion.m4
/tags
telemprobd
telempostd
telemctl
autoscan.log
configure.scan
tprobe
-35
View File
@@ -1,35 +0,0 @@
dist: trusty
compiler:
- gcc
os:
- linux
before_script:
./autogen.sh
language: c
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libcurl4-gnutls-dev
- valgrind
- autoconf
- automake
- check
- libelf-dev
- libdw-dev
install:
- wget https://github.com/libcheck/check/releases/download/0.12.0/check-0.12.0.tar.gz
- tar -xvf check-0.12.0.tar.gz
- pushd check-0.12.0 && ./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu && make -j48 && sudo make install && popd
script:
- ./configure && make && make check
after_failure: cat test-suite.log
View File
+1 -1
View File
@@ -4,7 +4,7 @@ ACLOCAL_AMFLAGS = -I build-aux/m4
EXTRA_DIST = \
AUTHORS \
LICENSE.LGPL-2.1
LICENSE
DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdunitdir) \
+1 -1
View File
@@ -1,4 +1,4 @@
[![Build Status](https://travis-ci.org/clearlinux/telemetrics-client.svg?branch=master)](https://travis-ci.org/clearlinux/telemetrics-client)
![](https://github.com/clearlinux/telemetrics-client/workflows/C%2FC++%20CI/badge.svg)
Telemetrics-client
==================
+239
View File
@@ -0,0 +1,239 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off)
# AX_VALGRIND_CHECK()
#
# DESCRIPTION
#
# AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows
# running `make check` under a variety of Valgrind tools to check for
# memory and threading errors.
#
# Defines VALGRIND_CHECK_RULES which should be substituted in your
# Makefile; and $enable_valgrind which can be used in subsequent configure
# output. VALGRIND_ENABLED is defined and substituted, and corresponds to
# the value of the --enable-valgrind option, which defaults to being
# enabled if Valgrind is installed and disabled otherwise. Individual
# Valgrind tools can be disabled via --disable-valgrind-<tool>, the
# default is configurable via the AX_VALGRIND_DFLT command or is to use
# all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT
# calls must be made before the call to AX_VALGRIND_CHECK.
#
# If unit tests are written using a shell script and automake's
# LOG_COMPILER system, the $(VALGRIND) variable can be used within the
# shell scripts to enable Valgrind, as described here:
#
# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html
#
# Usage example:
#
# configure.ac:
#
# AX_VALGRIND_DFLT([sgcheck], [off])
# AX_VALGRIND_CHECK
#
# in each Makefile.am with tests:
#
# @VALGRIND_CHECK_RULES@
# VALGRIND_SUPPRESSIONS_FILES = my-project.supp
# EXTRA_DIST = my-project.supp
#
# This results in a "check-valgrind" rule being added. Running `make
# check-valgrind` in that directory will recursively run the module's test
# suite (`make check`) once for each of the available Valgrind tools (out
# of memcheck, helgrind and drd) while the sgcheck will be skipped unless
# enabled again on the commandline with --enable-valgrind-sgcheck. The
# results for each check will be output to test-suite-$toolname.log. The
# target will succeed if there are zero errors and fail otherwise.
#
# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in
# memcheck, helgrind, drd and sgcheck. These are useful because often only
# some of those tools can be ran cleanly on a codebase.
#
# The macro supports running with and without libtool.
#
# LICENSE
#
# Copyright (c) 2014, 2015, 2016 Philip Withnall <philip.withnall@collabora.co.uk>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 17
dnl Configured tools
m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]])
m4_set_add_all([valgrind_exp_tool_set], [sgcheck])
m4_foreach([vgtool], [valgrind_tool_list],
[m4_define([en_dflt_valgrind_]vgtool, [on])])
AC_DEFUN([AX_VALGRIND_DFLT],[
m4_define([en_dflt_valgrind_$1], [$2])
])dnl
AM_EXTRA_RECURSIVE_TARGETS([check-valgrind])
m4_foreach([vgtool], [valgrind_tool_list],
[AM_EXTRA_RECURSIVE_TARGETS([check-valgrind-]vgtool)])
AC_DEFUN([AX_VALGRIND_CHECK],[
dnl Check for --enable-valgrind
AC_ARG_ENABLE([valgrind],
[AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])],
[enable_valgrind=$enableval],[enable_valgrind=])
AS_IF([test "$enable_valgrind" != "no"],[
# Check for Valgrind.
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind])
AS_IF([test "$VALGRIND" = ""],[
AS_IF([test "$enable_valgrind" = "yes"],[
AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind])
],[
enable_valgrind=no
])
],[
enable_valgrind=yes
])
])
AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"])
AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind])
# Check for Valgrind tools we care about.
[valgrind_enabled_tools=]
m4_foreach([vgtool],[valgrind_tool_list],[
AC_ARG_ENABLE([valgrind-]vgtool,
m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl
[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl
[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]),
[enable_valgrind_]vgtool[=$enableval],
[enable_valgrind_]vgtool[=])
AS_IF([test "$enable_valgrind" = "no"],[
enable_valgrind_]vgtool[=no],
[test "$enable_valgrind_]vgtool[" ]dnl
m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[
AC_CACHE_CHECK([for Valgrind tool ]vgtool,
[ax_cv_valgrind_tool_]vgtool,[
ax_cv_valgrind_tool_]vgtool[=no
m4_set_contains([valgrind_exp_tool_set],vgtool,
[m4_define([vgtoolx],[exp-]vgtool)],
[m4_define([vgtoolx],vgtool)])
AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[
ax_cv_valgrind_tool_]vgtool[=yes
])
])
AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[
AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[
AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool)
],[
enable_valgrind_]vgtool[=no
])
],[
enable_valgrind_]vgtool[=yes
])
])
AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[
valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])["
])
AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool)
])
AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["])
AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools])
[VALGRIND_CHECK_RULES='
# Valgrind check
#
# Optional:
# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions
# files to load. (Default: empty)
# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools.
# (Default: --num-callers=30)
# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of:
# memcheck, helgrind, drd, sgcheck). (Default: various)
# Optional variables
VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES))
VALGRIND_FLAGS ?= --num-callers=30
VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no
VALGRIND_helgrind_FLAGS ?= --history-level=approx
VALGRIND_drd_FLAGS ?=
VALGRIND_sgcheck_FLAGS ?=
# Internal use
valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools)))
valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS)
valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS)
valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS)
valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS)
valgrind_quiet = $(valgrind_quiet_$(V))
valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY))
valgrind_quiet_0 = --quiet
valgrind_v_use = $(valgrind_v_use_$(V))
valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY))
valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%-am,%,$''@):;
# Support running with and without libtool.
ifneq ($(LIBTOOL),)
valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute
else
valgrind_lt =
endif
# Use recursive makes in order to ignore errors during check
check-valgrind-am:
ifeq ($(VALGRIND_ENABLED),yes)
$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \
$(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool))
else
@echo "Need to reconfigure with --enable-valgrind"
endif
# Valgrind running
VALGRIND_TESTS_ENVIRONMENT = \
$(TESTS_ENVIRONMENT) \
env VALGRIND=$(VALGRIND) \
G_SLICE=always-malloc,debug-blocks \
G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly
VALGRIND_LOG_COMPILER = \
$(valgrind_lt) \
$(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS)
define valgrind_tool_rule
check-valgrind-$(1)-am:
ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes)
ifneq ($$(TESTS),)
$$(valgrind_v_use)$$(MAKE) check-TESTS \
TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \
LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \
LOG_FLAGS="$$(valgrind_$(1)_flags)" \
TEST_SUITE_LOG=test-suite-$(1).log
endif
else ifeq ($$(VALGRIND_ENABLED),yes)
@echo "Need to reconfigure with --enable-valgrind-$(1)"
else
@echo "Need to reconfigure with --enable-valgrind"
endif
endef
$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool))))
A''M_DISTCHECK_CONFIGURE_FLAGS ?=
A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind
MOSTLYCLEANFILES ?=
MOSTLYCLEANFILES += $(valgrind_log_files)
.PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools))
']
AC_SUBST([VALGRIND_CHECK_RULES])
m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])])
])
+15 -3
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([telemetrics-client], [2.3.3], [https://clearlinux.org/])
AC_INIT([telemetrics-client], [2.4.0], [https://clearlinux.org/])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.14 -Wall -Werror -Wno-extra-portability foreign subdir-objects])
AM_SILENT_RULES([yes])
@@ -20,11 +20,20 @@ AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
# Valgrind check
AX_VALGRIND_DFLT(memcheck, on)
AX_VALGRIND_DFLT(helgrind, off)
AX_VALGRIND_DFLT(drd, off)
AX_VALGRIND_DFLT(sgcheck, off)
AX_VALGRIND_CHECK
# Checks for libraries.
# check >= 0.9.12 is required for TAP output
PKG_CHECK_MODULES([CHECK], [check >= 0.12])
PKG_CHECK_MODULES([CURL], [libcurl])
PKG_CHECK_MODULES([JSON_C], [json-c])
AC_CHECK_LIB([elf], [elf_begin], [have_elflib=yes], [AC_MSG_ERROR([Unable to find libelf from elfutils])])
AC_CHECK_LIB([dw], [dwfl_begin], [have_dwlib=yes], [AC_MSG_ERROR([Unable to find libdw from elfutils])])
AS_IF([test "x$have_elflib" = "xyes" -a "x$have_dwlib" = "xyes"],
@@ -41,6 +50,7 @@ AC_CHECK_HEADERS([elfutils/libdwfl.h])
AC_CHECK_HEADERS([fcntl.h])
AC_CHECK_HEADERS([getopt.h])
AC_CHECK_HEADERS([inttypes.h])
AC_CHECK_HEADERS([json-c/json.h])
AC_CHECK_HEADERS([libelf.h])
AC_CHECK_HEADERS([limits.h])
AC_CHECK_HEADERS([stdarg.h])
@@ -120,8 +130,8 @@ AC_ARG_WITH([loglevel], AS_HELP_STRING([--with-loglevel=NUM],
AC_DEFINE_UNQUOTED([MAX_LOG_LEVEL], [${loglevel}], [Maximum log level for binaries])
AC_ARG_WITH([backendserveraddr], AS_HELP_STRING([--with-backendserveraddr=URI],
[uri to telemetrics backend server @<:@default=https://clr.telemetry.intel.com/v2/collector@:>@]), [backendaddr=${withval}])
test -z "${backendaddr}" && backendaddr=https://clr.telemetry.intel.com/v2/collector
[uri to telemetrics backend server @<:@default=https://clr.telemetry.intel.com/v3/collector@:>@]), [backendaddr=${withval}])
test -z "${backendaddr}" && backendaddr=https://clr.telemetry.intel.com/v3/collector
AC_SUBST(BACKEND_ADDR, [${backendaddr}])
AC_ARG_ENABLE([logtype], AS_HELP_STRING([--enable-logtype],
@@ -171,4 +181,6 @@ systemconfdir: $confpath
socketdir: $socketpath
loglevel: $loglevel
logtype: $logtype
valgrind: $enable_valgrind
])
+20
View File
@@ -152,6 +152,18 @@ bool set_default_config_values(struct configuration *config)
return true;
}
/* Needed for unit testing */
void free_config_struct(struct configuration *config)
{
if (keyfile != NULL) {
nc_hashmap_free(keyfile);
}
for (int i = 0; i < CONF_STR_MAX; i++) {
free(config->strValues[i]);
}
}
bool read_config_from_file(char *config_file, struct configuration *config)
{
if (keyfile != NULL) {
@@ -275,6 +287,14 @@ void free_configuration(void)
}
}
/* Needed for unit testing */
void free_config_file(void)
{
if (config_file) {
free(config_file);
}
}
const char *server_addr_config()
{
initialize_config();
+1
View File
@@ -5,6 +5,7 @@ ConditionPathExists=/etc/telemetrics/opt-in
[Timer]
OnCalendar=daily
AccuracySec=12h
RandomizedDelaySec=21600
Persistent=true
[Install]
+1
View File
@@ -1,5 +1,6 @@
[Unit]
Description=Telemetrics Kernel Log Scanner
ConditionVirtualization=!container
Requires=telemprobd.socket
After=telemprobd.socket
+2 -2
View File
@@ -124,8 +124,8 @@ bool read_record(char *fullpath, char *headers[], char **body, char **cfg_file)
}
memset(*body, 0, (size_t)size);
//read rest of file
size_t newlen = fread(*body, sizeof(char), (size_t)size, fp);
//read rest of file. '-1' ensures it's null terminated
size_t newlen = fread(*body, sizeof(char), (size_t)size - 1, fp);
if (newlen == 0) {
telem_perror("Error reading staged file");
result = false;
+3 -1
View File
@@ -421,6 +421,7 @@ static void print_record(char *record_id)
recordfp = fopen(filepath, "r");
if (!recordfp) {
telem_log(LOG_INFO, "Could not open record %s: %s\n", record_id, strerror(errno));
free(filepath);
return;
}
@@ -661,7 +662,8 @@ int prune_journal(struct TelemJournal *telem_journal, char *tmp_dir)
telem_journal->fptr = fopen(telem_journal->journal_file, "a+");
if (!telem_journal->fptr) {
telem_log(LOG_ERR, "Error re-opening journal file\n");
return rc;
rc = 1;
goto quit;
}
// update record count
telem_journal->record_count = telem_journal->record_count - count;
+1 -1
View File
@@ -61,7 +61,7 @@ endif
%D%/iorecord.c \
%D%/iorecord.h
%C%_telempostd_LDADD = $(CURL_LIBS) \
%C%_telempostd_LDADD = $(CURL_LIBS) $(JSON_C_LIBS) \
%D%/libtelem-shared.la \
%D%/libtelemetry.la
+1
View File
@@ -396,6 +396,7 @@ static int process_corefile(nc_string **backtrace)
nc_string_free(*backtrace);
}
*backtrace = nc_string_dup("");
frame_counter = 0;
if (dwfl_getthreads(d_core, thread_cb, backtrace) != DWARF_CB_OK) {
/* We aborted unwinding, due to too many frames.
+1 -1
View File
@@ -159,7 +159,7 @@ int main(int argc, char **argv)
break;
case 'H':
str = "org.clearlinux/heartbeat/ping";
memcpy(classification, str, strlen(str));
memcpy(classification, str, strlen(str) + 1);
break;
case 'l':
payload_options |= PAYLOAD_LOCALE;
+15 -2
View File
@@ -577,6 +577,10 @@ static void stack_frame_free(struct stack_frame **head)
while (*head != NULL) {
frame = (*head)->next;
// First free memory allocation for function name
if ((*head)->function) {
free((*head)->function);
}
free(*head);
*head = frame;
}
@@ -584,8 +588,8 @@ static void stack_frame_free(struct stack_frame **head)
/*
* Function parses lines of the format :
* CPU: 2 PID: 6429 Comm: insmod Tainted: P OE 3.19.0-18-generic #18-Ubuntu$
* CPU: 2 PID: 0 Comm: swapper/2 Not tainted 3.10.4-100.fc18.x86_64 #1
* CPU: 2 PID: 6429 Comm: insmod Tainted: POE 3.19.0-18-generic #18-Ubuntu$
* CPU: 2 PID: 0 Comm: swapper/2 Not tainted 3.10.4-100.fc18.x86_64 #1
* CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.0.5-300.fc22.x86_64 #1
*/
static void parse_kernel_cpu_line(char *line, char **kernel_version, char **tainted)
@@ -834,6 +838,15 @@ static nc_string *parse_backtrace(struct oops_log_msg *msg)
if (str_starts_with_casei(line, "CPU: ") ||
str_starts_with_casei(line, "PID: ")) {
/* Can't assume that these variables (tainted,
* an kernel_version) are not already allocated
* otherwise it will leak memory */
if (tainted) {
free(tainted);
}
if (kernel_version) {
free(kernel_version);
}
parse_kernel_cpu_line(line, &kernel_version, &tainted);
continue;
}
+20 -8
View File
@@ -25,6 +25,7 @@
#include <limits.h>
#include <stdbool.h>
#include <errno.h>
#include <fcntl.h>
#include "spool.h"
#include "telempostdaemon.h"
@@ -149,27 +150,37 @@ void process_spooled_record(const char *spool_dir, char *name,
}
(*records_processed)++;
ret = stat(record_name, &buf);
if (ret == -1) {
telem_perror("Unable to stat record in spool");
free(record_name);
return;
// Use file descriptor to mitigate TOCTOU
int fd = open(record_name, O_RDONLY | O_NOFOLLOW);
if (fd == -1) {
telem_perror("Unable to open record in spool");
goto exit;
}
if (fstat(fd, &buf) == -1) {
telem_perror("Unable to fstat record in spool");
close(fd);
goto exit;
}
/*
* If file is a regular file , if uid is diff than process uid
* or if mtime is greater than record expiry delete the file
* If file is a regular file, if uid is different than process uid,
* or if mtime is greater than record expiry, delete the file.
*/
if (record_expiry_config() == -1) {
telem_log(LOG_ERR, "Invalid record expiry value\n");
close(fd);
exit(EXIT_FAILURE);
}
if (!S_ISREG(buf.st_mode) ||
(current_time - buf.st_mtime > (record_expiry_config() * 60)) ||
(buf.st_uid != getuid())) {
(buf.st_uid != getuid())) {
unlink(record_name);
close(fd);
} else if (post_succeeded && *records_sent <= TM_SPOOL_MAX_SEND_RECORDS) {
close(fd);
transmit_spooled_record(record_name, &post_succeeded, buf.st_size);
if (!post_succeeded) {
@@ -194,6 +205,7 @@ void process_spooled_record(const char *spool_dir, char *name,
}
}
}
exit:
free(record_name);
}
+14 -5
View File
@@ -354,12 +354,21 @@ static void process_record(TelemDaemon *daemon, client *cl)
buf += cfg_info_size;
header_size = *(uint32_t *)buf;
/* Header size can not be bigger than buffer size bail out early */
if ((uint32_t)header_size >= (uint32_t)cl->size) {
return;
}
message_size = cl->size - (cfg_info_size + header_size);
telem_debug("DEBUG: cl->size: %zu\n", cl->size);
telem_debug("DEBUG: header_size: %zu\n", header_size);
telem_debug("DEBUG: message_size: %zu\n", message_size);
telem_debug("DEBUG: cfg_info_size: %zu\n", cfg_info_size);
assert(message_size > 0); //TODO:Check for min and max limits
telem_debug("DEBUG: cl->size: %ld\n", cl->size);
telem_debug("DEBUG: header_size: %ld\n", header_size);
telem_debug("DEBUG: message_size: %ld\n", message_size);
telem_debug("DEBUG: cfg_info_size: %ld\n", cfg_info_size);
telem_debug("Total: %zu\n", header_size + cfg_info_size + message_size);
/* Check message size bounds */
if (message_size <= 0 || message_size > MAX_PAYLOAD_LENGTH) {
telem_log(LOG_INFO, "Record message size out of bounds\n");
return;
}
msg = (char *)buf + sizeof(uint32_t);
/* Copying the headers as strtok modifies the orginal buffer */
+6 -5
View File
@@ -977,17 +977,18 @@ int tm_set_payload(struct telem_ref *t_ref, char *payload)
size_t payload_len;
int ret = 0;
payload_len = strlen((char *)payload);
if (payload_len > MAX_PAYLOAD_LENGTH) {
if (payload == NULL) {
telem_log(LOG_WARNING, "payload pointer is NULL\n");
return -EINVAL;
}
payload_len = strnlen(payload, MAX_PAYLOAD_LENGTH);
if (payload_is_ascii(payload, payload_len) != 0) {
return -EINVAL;
}
t_ref->record->payload = strdup(payload);
t_ref->record->payload = strndup(payload, payload_len);
if (!t_ref->record->payload) {
telem_log(LOG_CRIT, "CRIT: Out of memory\n");
@@ -1273,7 +1274,7 @@ int tm_send_record(struct telem_ref *t_ref)
*/
record_size = (2 * sizeof(uint32_t)) + total_size + 1;
data = calloc(sizeof(char), record_size);
data = (char *)calloc(sizeof(char), record_size);
if (!data) {
telem_log(LOG_CRIT, "CRIT: Out of memory\n");
close(sfd);
+85 -39
View File
@@ -1,7 +1,7 @@
/*
* This program is part of the Clear Linux Project
*
* Copyright 2018 Intel Corporation
* Copyright 2018-2023 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it under
* the terms and conditions of the GNU Lesser General Public License, as
@@ -25,6 +25,7 @@
#include <stdbool.h>
#include <sys/stat.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include <sys/signalfd.h>
#include "log.h"
@@ -210,13 +211,47 @@ size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
return size * nmemb;
}
char *create_json_message(char *tm_headers[], char *tm_payload)
{
/*
* Embed the telemetry record headers and the telemetry payload into a
* JSON object string.
*/
char *json_string = NULL;
json_object *root = json_object_new_object();
/* Add the telemetry record headers */
for (int i = 0; i < NUM_HEADERS; i++) {
/* ex: arch: x86_64 */
/* Split the header field into name/value */
strtok(tm_headers[i], ":");
json_object *value = json_object_new_string(strtok(NULL, " "));
json_object_object_add(root, tm_headers[i], value);
}
json_object *payload = json_object_new_string(tm_payload);
json_object_object_add(root, "payload", payload);
/* Keep our own copy of the json string */
json_string = strdup(json_object_to_json_string_ext(root,
JSON_C_TO_STRING_PLAIN |
JSON_C_TO_STRING_NOSLASHESCAPE));
/* Free the memory associated with the JSON objects */
json_object_put(root);
return json_string;
}
bool post_record_http(char *headers[], char *body, char *cfg)
{
CURL *curl;
int res = 0;
char *content = "Content-Type: application/text";
char *content = "Content-Type: application/json";
struct curl_slist *custom_headers = NULL;
char errorbuf[CURL_ERROR_SIZE];
char *json_body = NULL;
long http_response = 0;
const char *cert_file = get_cainfo_config();
const char *tid_header = get_tidheader_config();
@@ -231,12 +266,15 @@ bool post_record_http(char *headers[], char *body, char *cfg)
// settings than explicitly requested.
// However, report success so the record gets deleted.
res = 0;
goto Done;
goto done;
}
reload_config();
telem_debug("DEBUG: override server_addr:%s\n", server_addr_config());
}
// Generate the JSON message body
json_body = create_json_message(headers, body);
// Initialize the libcurl global environment once per POST. This lets us
// clean up the environment after each POST so that when the daemon is
// sitting idle, it will be consuming as little memory as possible.
@@ -250,35 +288,35 @@ bool post_record_http(char *headers[], char *body, char *cfg)
/* TODO: check if memory needs to be released */
}
// Errors for any curl_easy_* functions will store nice error messages
// in errorbuf, so send log messages with errorbuf contents
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuf);
curl_easy_setopt(curl, CURLOPT_URL, server_addr_config());
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
curl_easy_setopt(curl, CURLOPT_POST, 1);
#ifdef DEBUG
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
for (int i = 0; i < NUM_HEADERS; i++) {
custom_headers = curl_slist_append(custom_headers, headers[i]);
}
custom_headers = curl_slist_append(custom_headers, tid_header);
// This should be set by probes/libtelemetry in the future
custom_headers = curl_slist_append(custom_headers, content);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, custom_headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(body));
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY);
// Errors for any curl_easy_* functions will store nice error messages
// in errorbuf, so send log messages with errorbuf contents
if (curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuf) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_URL, server_addr_config()) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_POST, 1) != CURLE_OK ||
#ifdef DEBUG
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) != CURLE_OK ||
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, custom_headers) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_body) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(json_body)) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY) != CURLE_OK) {
telem_log(LOG_ERR, "curl_easy_setopt(): Failed to set one or more options\n");
goto exit;
}
if (strlen(cert_file) > 0) {
if (access(cert_file, F_OK) != -1) {
curl_easy_setopt(curl, CURLOPT_CAINFO, cert_file);
if (curl_easy_setopt(curl, CURLOPT_CAINFO, cert_file) != CURLE_OK) {
telem_log(LOG_ERR, "curl_easy_setopt(): Failed to set CAINFO\n");
goto exit;
}
telem_log(LOG_INFO, "cafile was set to %s\n", cert_file);
}
}
@@ -309,12 +347,17 @@ bool post_record_http(char *headers[], char *body, char *cfg)
telem_log(LOG_INFO, "Record sent successfully\n");
}
exit:
curl_slist_free_all(custom_headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
Done:
done:
if (json_body) {
free(json_body);
json_body = NULL;
}
if (saved_config_file != NULL) {
if (set_config_file(saved_config_file) != 0) {
telem_log(LOG_ERR, "set-config_file(): Failed to set %s",
@@ -490,7 +533,7 @@ static bool deliver_record(TelemPostDaemon *daemon, char *headers[], char *body,
return ret;
}
bool process_staged_record(char *filename, bool is_retry, TelemPostDaemon *daemon)
bool process_staged_record(char *filename, TelemPostDaemon *daemon)
{
int k;
bool ret = false;
@@ -530,20 +573,12 @@ bool process_staged_record(char *filename, bool is_retry, TelemPostDaemon *daemo
goto end_processing_file;
}
/* Retries should not be recorded */
if (is_retry == false) {
/** Journal entry **/
save_entry_to_journal(daemon, current_time, headers);
/** Record retention **/
apply_retention_policies(daemon, body);
}
/** Record delivery **/
if (!daemon->record_server_delivery_enabled) {
telem_log(LOG_INFO, "record server delivery disabled\n");
// Not an error condition
ret = true;
goto end_processing_file;
goto end_record_delivery;
}
/** Spool policies **/
@@ -571,6 +606,17 @@ bool process_staged_record(char *filename, bool is_retry, TelemPostDaemon *daemo
/** Deliver or spool **/
ret = deliver_record(daemon, headers, body, cfg_file);
end_record_delivery:
/** Save record once it is properly delivered, if record
* is spooled the record is not saved to journal until
* delievered on a re-try **/
if (ret) {
/** Save to journal **/
save_entry_to_journal(daemon, current_time, headers);
/** Record retention **/
apply_retention_policies(daemon, body);
}
end_processing_file:
/** Update spool size if record will be removed **/
if (ret) {
@@ -625,7 +671,7 @@ int staging_records_loop(TelemPostDaemon *daemon)
telem_log(LOG_ERR, "Failed to allocate memory for staging record full path\n");
exit(EXIT_FAILURE);
}
if (process_staged_record(record_path, true, daemon)) {
if (process_staged_record(record_path, daemon)) {
unlink(record_path);
processed++;
}
@@ -721,7 +767,7 @@ void run_daemon(TelemPostDaemon *daemon)
exit(EXIT_FAILURE);
}
/* Process inotify event */
if (process_staged_record(record_name, false, daemon)) {
if (process_staged_record(record_name, daemon)) {
unlink(record_name);
}
free(record_name);
+2 -3
View File
@@ -85,11 +85,9 @@ void close_daemon(TelemPostDaemon *daemon);
* Processed record written on disk
*
* @param filename a pointor to record on disk
* @param is_retry a boolean value that indicates if
* the record has been previously processed.
* @param daemon post to telemetry post daemon
*/
bool process_staged_record(char *filename, bool is_retry, TelemPostDaemon *daemon);
bool process_staged_record(char *filename, TelemPostDaemon *daemon);
/**
* Scans staging directory to process files that were
@@ -107,6 +105,7 @@ int staging_records_loop(TelemPostDaemon *daemon);
* @param body a pointer to the payload
* @param cfg_file a pointer to a non-default configuration
* file to be used.
* @return true if successful, false otherwise
*/
bool post_record_http(char *headers[], char *body, char *cfg_file);
+12 -2
View File
@@ -14,8 +14,10 @@
* details.
*/
#include <stdlib.h>
#include <check.h>
#include "configuration.h"
#include "configuration_check.h"
START_TEST(check_read_config_for_invalid_file)
{
@@ -52,6 +54,7 @@ START_TEST(check_read_valid_config)
"X-Telemetry-TID: 6907c830-eed9-4ce9-81ae-76daf8d88f0f");
ck_assert(config.boolValues[CONF_DAEMON_RECYCLING_ENABLED] == true);
free_config_struct(&config);
}
END_TEST
@@ -80,6 +83,8 @@ START_TEST(check_default_config)
ck_assert(config.boolValues[CONF_DAEMON_RECYCLING_ENABLED] == DEFAULT_DAEMON_RECYCLING_ENABLED);
ck_assert(config.boolValues[CONF_RECORD_RETENTION_ENABLED] == DEFAULT_RECORD_RETENTION_ENABLED);
ck_assert(config.boolValues[CONF_RECORD_SERVER_DELIVERY_ENABLED] == DEFAULT_RECORD_SERVER_DELIVERY_ENABLED);
free_config_struct(&config);
}
END_TEST
@@ -110,6 +115,8 @@ START_TEST(check_layered_config)
ck_assert(config.boolValues[CONF_DAEMON_RECYCLING_ENABLED] == DEFAULT_DAEMON_RECYCLING_ENABLED);
ck_assert(config.boolValues[CONF_RECORD_RETENTION_ENABLED] == DEFAULT_RECORD_RETENTION_ENABLED);
ck_assert(config.boolValues[CONF_RECORD_SERVER_DELIVERY_ENABLED] == DEFAULT_RECORD_SERVER_DELIVERY_ENABLED);
free_config_struct(&config);
}
END_TEST
@@ -123,6 +130,8 @@ START_TEST(check_read_valid_config_record_retention_delivery)
ck_assert(config.boolValues[CONF_RECORD_RETENTION_ENABLED] == true);
ck_assert(config.boolValues[CONF_RECORD_SERVER_DELIVERY_ENABLED] == false);
free_config_struct(&config);
}
END_TEST
@@ -176,6 +185,7 @@ int main(void)
{
Suite *s;
SRunner *sr;
int failed;
s = config_suite();
sr = srunner_create(s);
@@ -186,13 +196,13 @@ int main(void)
srunner_set_tap(sr, "-");
srunner_run_all(sr, CK_SILENT);
// failed = srunner_ntests_failed(sr);
failed = srunner_ntests_failed(sr);
srunner_free(sr);
// if you want the TAP driver to report a hard error based
// on certain conditions (e.g. number of failed tests, etc.),
// return non-zero here instead.
return 0;
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* vi: set ts=8 sw=8 sts=4 et tw=80 cino=(0: */
+4 -2
View File
@@ -17,6 +17,7 @@
#include <check.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "journal/journal.h"
@@ -239,6 +240,7 @@ int main(void)
{
Suite *s;
SRunner *sr;
int failed;
s = config_suite();
sr = srunner_create(s);
@@ -249,13 +251,13 @@ int main(void)
srunner_set_tap(sr, "-");
srunner_run_all(sr, CK_SILENT);
// failed = srunner_ntests_failed(sr);
failed = srunner_ntests_failed(sr);
srunner_free(sr);
// if you want the TAP driver to report a hard error based
// on certain conditions (e.g. number of failed tests, etc.),
// return non-zero here instead.
return 0;
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* vi: set ts=8 sw=8 sts=4 et tw=80 cino=(0: */
+7 -5
View File
@@ -243,9 +243,8 @@ END_TEST
void event_id_teardown(void)
{
if (ref) {
free(ref);
}
// Free record
create_teardown();
free(original_event_id);
}
@@ -292,6 +291,7 @@ int main(void)
{
Suite *s;
SRunner *sr;
int failed;
s = lib_suite();
sr = srunner_create(s);
@@ -299,11 +299,13 @@ int main(void)
srunner_set_log(sr, NULL);
srunner_set_tap(sr, "-");
// set CK_NOFORK to attach gdb
// srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr, CK_SILENT);
failed = srunner_ntests_failed(sr);
srunner_free(sr);
return 0;
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* vi: set ts=8 sw=8 sts=4 et tw=80 cino=(0: */
+7 -6
View File
@@ -62,7 +62,7 @@ START_TEST(check_handle_client_with_no_data)
bool success;
char *filename = ABSTOPSRCDIR "/tests/telempostd/empty_message";
success = process_staged_record(filename, false, &tdaemon);
success = process_staged_record(filename, &tdaemon);
// Return true to remove corrupted record
ck_assert(success == true);
}
@@ -75,7 +75,7 @@ START_TEST(check_handle_client_with_incorrect_data)
bool success;
char *filename = ABSTOPSRCDIR "/tests/telempostd/incorrect_message";
success = process_staged_record(filename, false, &tdaemon);
success = process_staged_record(filename, &tdaemon);
// Return true to remove corrupted record
ck_assert(success == true);
}
@@ -88,7 +88,7 @@ START_TEST(check_process_record_with_correct_size_and_data)
bool success;
char *filename = ABSTOPSRCDIR "/tests/telempostd/correct_message";
success = process_staged_record(filename, false, &tdaemon);
success = process_staged_record(filename, &tdaemon);
ck_assert(success == true);
}
END_TEST
@@ -100,7 +100,7 @@ START_TEST(check_process_record_with_incorrect_headers)
bool success;
char *filename = ABSTOPSRCDIR "/tests/telempostd/incorrect_headers";
success = process_staged_record(filename, false, &tdaemon);
success = process_staged_record(filename, &tdaemon);
// Return true to remove corrupted record
ck_assert(success == true);
}
@@ -421,6 +421,7 @@ int main(void)
{
Suite *s;
SRunner *sr;
int failed;
s = config_suite();
sr = srunner_create(s);
@@ -431,13 +432,13 @@ int main(void)
srunner_set_tap(sr, "-");
srunner_run_all(sr, CK_SILENT);
// failed = srunner_ntests_failed(sr);
failed = srunner_ntests_failed(sr);
srunner_free(sr);
// if you want the TAP driver to report a hard error based
// on certain conditions (e.g. number of failed tests, etc.),
// return non-zero here instead.
return 0;
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* vi: set ts=8 sw=8 sts=4 et tw=80 cino=(0: */
+30 -5
View File
@@ -22,6 +22,7 @@
#include <unistd.h>
#include "configuration.h"
#include "configuration_check.h"
#include "telemdaemon.h"
#include "common.h"
@@ -61,12 +62,19 @@ void setup(void)
initialize_probe_daemon(&tdaemon);
}
void teardown(void)
{
free_config_file();
}
START_TEST(check_daemon_is_initialized)
{
setup();
ck_assert(tdaemon.nfds == 0);
ck_assert(tdaemon.pollfds == NULL);
teardown();
}
END_TEST
@@ -84,9 +92,9 @@ START_TEST(check_add_del_poll_fd)
int fd = 1;
int short events = 1;
add_pollfd(&tdaemon, fd, events);
add_pollfd(&tdaemon, ++fd, events);
add_pollfd(&tdaemon, ++fd, events);
add_pollfd(&tdaemon, 1, events);
add_pollfd(&tdaemon, 2, events);
add_pollfd(&tdaemon, 3, events);
ck_assert_msg(tdaemon.nfds == 3, "Failed to add pollfd");
fd = get_poll_fd(&tdaemon, 0);
@@ -110,6 +118,10 @@ START_TEST(check_add_del_poll_fd)
ck_assert_msg(tdaemon.nfds == 0, "Failed to delete pollfd");
fd = get_poll_fd(&tdaemon, 0);
ck_assert(fd == -1);
/* Cleaning alloctions */
free(tdaemon.pollfds);
teardown();
}
END_TEST
@@ -133,6 +145,8 @@ START_TEST(check_add_remove_client)
remove_client(&(tdaemon.client_head), cl3);
//ck_assert(tdaemon.client_head.lh_first == NULL);
ck_assert_msg(is_client_list_empty(&(tdaemon.client_head)), "Failed to remove clients\n");
teardown();
}
END_TEST
@@ -171,6 +185,8 @@ START_TEST(check_handle_client_with_no_data)
ck_assert_msg(is_client_list_empty(&(tdaemon.client_head)), "Failed to remove client with no data\n");
ck_assert_msg(tdaemon.nfds == 0, "Failed to remove poll fd for client with n data\n");
close(server_fd);
teardown();
}
END_TEST
@@ -197,6 +213,8 @@ START_TEST(check_handle_client_with_incorrect_data)
ck_assert_msg(is_client_list_empty(&(tdaemon.client_head)), "Failed to remove client with no data\n");
ck_assert_msg(tdaemon.nfds == 0, "Failed to remove poll fd for client with n data\n");
close(server_fd);
teardown();
}
END_TEST
@@ -228,6 +246,8 @@ START_TEST(check_handle_client_with_incorrect_size)
ck_assert_msg(is_client_list_empty(&(tdaemon.client_head)), "Failed to remove client with no data\n");
ck_assert_msg(tdaemon.nfds == 0, "Failed to remove poll fd for client with n data\n");
close(server_fd);
teardown();
}
END_TEST
@@ -332,6 +352,8 @@ START_TEST(check_process_record_with_incorrect_headers)
ck_assert_msg(tdaemon.nfds == 0, "Failed to remove poll fd for client with incorrect headers\n");
close(server_fd);
free(record);
teardown();
}
END_TEST
@@ -361,6 +383,7 @@ int main(void)
{
Suite *s;
SRunner *sr;
int failed;
s = config_suite();
sr = srunner_create(s);
@@ -370,14 +393,16 @@ int main(void)
srunner_set_log(sr, NULL);
srunner_set_tap(sr, "-");
// set CK_NOFORK to attach gdb
// srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr, CK_SILENT);
// failed = srunner_ntests_failed(sr);
failed = srunner_ntests_failed(sr);
srunner_free(sr);
// if you want the TAP driver to report a hard error based
// on certain conditions (e.g. number of failed tests, etc.),
// return non-zero here instead.
return 0;
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* vi: set ts=8 sw=8 sts=4 et tw=80 cino=(0: */
+11 -23
View File
@@ -57,6 +57,10 @@ void setup_payload(char *oopsfile)
oops_parser_init(callback_func);
split_buf_by_line(buf, buflen);
}
if (buf) {
free(buf);
}
}
// Tests for checking backtrace
@@ -249,6 +253,8 @@ START_TEST(sysctl1_payload)
ck_assert(strstr(pl->str, "#24 sys_ioctl"));
ck_assert(strstr(pl->str, "#25 sysenter_past_esp"));
ck_assert(strstr(pl->str, "#26 quirk_ali7101_acpi"));
nc_string_free(pl);
}
END_TEST
@@ -679,27 +685,6 @@ Suite *config_suite(void)
tcase_add_test(t, bug_kernel_handle_payload);
tcase_add_test(t, bug_kernel_handle_payload_new_format);
//TODO fix
//tcase_add_test(t, badness_payload);
/*
tcase_add_test(t, watchdog_oops);
tcase_add_test(t, warning_oops);
tcase_add_test(t, warn_on_oops);
tcase_add_test(t, two_warnings_oops);
tcase_add_test(t, sysctl1_oops);
tcase_add_test(t, sysctl2_oops);
tcase_add_test(t, softlockup_oops);
tcase_add_test(t, rtnl_oops);
tcase_add_test(t, kernel_null_pointer_oops);
tcase_add_test(t, kernel_bug_oops);
tcase_add_test(t, irq_oops);
tcase_add_test(t, general_protection_fault_oops);
tcase_add_test(t, double_fault_oops);
tcase_add_test(t, bad_page_map_oops);
tcase_add_test(t, bug_kernel_handle_oops);
tcase_add_test(t, badness_oops);
*/
suite_add_tcase(s, t);
return s;
@@ -709,6 +694,7 @@ int main(void)
{
Suite *s;
SRunner *sr;
int failed;
s = config_suite();
sr = srunner_create(s);
@@ -720,14 +706,16 @@ int main(void)
srunner_set_log(sr, NULL);
srunner_set_tap(sr, "-");
// set CK_NOFORK to attach gdb
// srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr, CK_SILENT);
// failed = srunner_ntests_failed(sr);
failed = srunner_ntests_failed(sr);
srunner_free(sr);
// if you want the TAP driver to report a hard error based
// on certain conditions (e.g. number of failed tests, etc.),
// return non-zero here instead.
return 0;
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* vi: set ts=8 sw=8 sts=4 et tw=80 cino=(0: */
+24
View File
@@ -0,0 +1,24 @@
/*
* This program is part of the Clear Linux Project
*
* Copyright 2020 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it under
* the terms and conditions 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 program is distributed in the hope 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.
*/
#pragma once
/* Function used only for unit testing */
/* Frees configuration structure */
void free_config_struct(struct configuration *config);
/* Frees configuration file name string */
void free_config_file(void);
+16 -1
View File
@@ -1,4 +1,6 @@
EXTRA_DIST += %D%/taplib.sh
EXTRA_DIST += \
%D%/taplib.sh \
%D%/telemetrics-client.supp
TEST_EXTENSIONS = .sh
@@ -22,6 +24,7 @@ dist_check_SCRIPTS = \
%D%/create-core.sh
%C%_check_config_SOURCES = \
%D%/configuration_check.h \
%D%/check_config.c
%C%_check_config_CFLAGS = \
@@ -40,6 +43,7 @@ endif
endif
%C%_check_probd_SOURCES = \
%D%/configuration_check.h \
%D%/check_probd.c \
src/telemdaemon.c \
src/telemdaemon.h \
@@ -89,6 +93,7 @@ EXTRA_DIST += \
%C%_check_postd_LDADD = \
@CHECK_LIBS@ \
@CURL_LIBS@ \
@JSON_C_LIBS@ \
$(top_builddir)/src/libtelem-shared.la
if LOG_SYSTEMD
@@ -196,4 +201,14 @@ if LOG_SYSTEMD
endif
endif
@VALGRIND_CHECK_RULES@
VALGRIND_SUPPRESSIONS_FILES = %D%/telemetrics-client.supp
VALGRIND_FLAGS = \
--error-exitcode=1 \
--track-origins=yes \
--leak-resolution=low \
--verbose \
--leak-check=full \
--show-possibly-lost=no
# vim: filetype=automake tabstop=8 shiftwidth=8 noexpandtab
+17 -9
View File
@@ -1,3 +1,19 @@
/*
* This program is part of the Clear Linux Project
*
* Copyright 2015 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it under
* the terms and conditions 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 program is distributed in the hope 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.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
@@ -36,26 +52,18 @@ char *readfile(char *filepath)
if (fread(bufp, sizeof(char), buflen, fp) != buflen) {
telem_log(LOG_ERR, "Error reading file\n");
} else {
bufp[++buflen] = '\0';
bufp[buflen] = '\0';
}
}
if (fclose(fp) != 0) {
printf("Error closing file: %s\n", strerror(errno));
}
//free(bufp);
} else {
telem_log(LOG_ERR, "Wrong file pathname: %s", filepath);
}
return bufp;
}
/*
char *getbuf()
{
return bufp;
}
*/
unsigned long getbuflen()
{
+38
View File
@@ -0,0 +1,38 @@
# This program is part of the Clear Linux Project
#
# Copyright 2020 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify it under
# the terms and conditions 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 program is distributed in the hope 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.
# False positive when check is run with CK_FORK=yes
{
ck_fork_yes_false_positive
Memcheck:Leak
fun:malloc
fun:UnknownInlinedFun
fun:UnknownInlinedFun
fun:tag_string_to_list
fun:UnknownInlinedFun
fun:srunner_run_tagged
fun:main
}
# False positive returned by call to shell script from
# with in test.
{
ck_shell_call
Memcheck:Leak
fun:malloc
fun:xmalloc
fun:set_default_locale
fun:main
}