Compare commits

..
Author SHA1 Message Date
Alex Jaramillo d866f468f8 Local Makefile
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-21 13:47:54 -07:00
Alex Jaramillo 07d334c718 Fizzing iorecord.c
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-21 13:45:44 -07:00
Alex Jaramillo a2367132bd Fuzzing configuration.c
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-21 13:13:10 -07:00
Alex Jaramillo ed42b6ed3f Fuzzing libtelemetry
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-03-21 10:02:13 -07:00
25 changed files with 319 additions and 88 deletions
+8 -6
View File
@@ -8,13 +8,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/checkout@v1
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get --fix-missing install libcurl4-gnutls-dev valgrind libelf-dev libdw-dev libjson-c-dev check
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
- name: autogen
run: sh autogen.sh
- name: configure
View File
+2 -1
View File
@@ -4,7 +4,7 @@ ACLOCAL_AMFLAGS = -I build-aux/m4
EXTRA_DIST = \
AUTHORS \
LICENSE
LICENSE.LGPL-2.1
DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdunitdir) \
@@ -21,6 +21,7 @@ include $(top_srcdir)/src/nica/local.mk
include $(top_srcdir)/src/probes/local.mk
include $(top_srcdir)/src/journal/local.mk
include $(top_srcdir)/tests/local.mk
include $(top_srcdir)/fuzz/local.mk
release:
@git rev-parse v$(PACKAGE_VERSION) &> /dev/null; \
+1 -13
View File
@@ -1,10 +1,3 @@
## DISCONTINUATION OF PROJECT.
This project will no longer be maintained by Intel.
Intel will not provide or guarantee development of or support for this project, including but not limited to, maintenance, bug fixes, new releases or updates. Patches to this project are no longer accepted by Intel. If you have an ongoing need to use this project, are interested in independently developing it, or would like to maintain patches for the community, please create your own fork of the project.
Contact: webadmin@linux.intel.com
![](https://github.com/clearlinux/telemetrics-client/workflows/C%2FC++%20CI/badge.svg)
Telemetrics-client
@@ -340,12 +333,7 @@ $ org.clearlinux/hello/world Mon 2018-04-02 17:48:01 UTC a19a0d41ba16788881e
$ hello
```
## Using tarball
When building the telemetrics-client using the tarball, a signature is provided for
validation. Please follow the steps outlined in the release's README.txt for guidance.
## Security Disclosures
To report a security issue or receive security advisories please follow procedures
in [link](security.md).
in this [link](https://01.org/security).
+1 -1
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.4.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])
+3
View File
@@ -0,0 +1,3 @@
fuzz_libtelem
fuzz_config
fuzz_iorec
+54
View File
@@ -0,0 +1,54 @@
bin_PROGRAMS = fuzz_libtelem fuzz_config fuzz_iorec
CC = clang
CFLAGS = \
-g \
-I../. \
-I../src/. \
-DLOCALSTATEDIR=\"/tmp\" \
-DDATADIR="" \
-DBACKEND_ADDR=\"abcde\"
# Define the source files for each binary
fuzz_libtelem_SOURCES = \
fuzz_libtelem.c
fuzz_config_SOURCES = \
../src/configuration.c \
../src/nica/hashmap.c \
../src/nica/inifile.c \
utils.c \
fuzz_config.c
fuzz_iorec_SOURCES = \
utils.c \
fuzz_iorec.c
fuzz_iorec_CFLAGS = \
$(CFLAGS) \
-fsanitize=address,fuzzer
fuzz_libtelem_CFLAGS = \
$(CFLAGS) \
-fsanitize=address,fuzzer \
-ltelemetry
fuzz_config_CFLAGS = \
$(CFLAGS) \
-fsanitize=fuzzer # There's a false positive in configuration.c:189:56
all: $(bin_PROGRAMS)
fuzz_libtelem: $(fuzz_libtelem_SOURCES)
$(CC) $(fuzz_libtelem_CFLAGS) -o $@ $^
fuzz_config: $(fuzz_config_SOURCES)
$(CC) $(fuzz_config_CFLAGS) -o $@ $^
fuzz_iorec: $(fuzz_iorec_SOURCES)
$(CC) $(fuzz_iorec_CFLAGS) -o $@ $^
clean:
rm -f $(bin_PROGRAMS) *.o
.PHONY: all clean
+21
View File
@@ -0,0 +1,21 @@
# Fuzzing telemetrics-client
## Build
```
make
```
## Run
```
#fuzz_config
fuzz_config -close_fd_mask=2
#fuzz_libtelem
fuzz_libtelem
```
# Link runs in background
```
sudo systemd-run --unit=fuzzing.service -r --uid=$(id -u) \
--working-directory=${PWD}/fuzz -E LD_LIBRARY_PATH=${PWD}/src/.libs/ fuzz/<fuzzer_> -max_total_time=86400 -runs=10000000 fuzz/corpus
```
+32
View File
@@ -0,0 +1,32 @@
#include <configuration.h>
#include <string.h>
#include <unistd.h>
#include "utils.h"
void test_configuration(const uint8_t *data, size_t size) {
char content[16384];
char config_file[] = "/tmp/config_fuzzerXXXXXX";
static struct configuration config = { { 0 }, { 0 }, { 0 }, false, NULL };
// Get a null ended string
strncpy(content, (const char *)data, size);
save_data(config_file, content);
read_config_from_file(config_file, &config);
for (int i = 0; i < 6; i++) {
if (config.strValues[i] == NULL) {
continue;
}
}
unlink(config_file);
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
test_configuration(data, size);
return 0;
}
+28
View File
@@ -0,0 +1,28 @@
#include <configuration.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "utils.h"
void test_read_record(const uint8_t *data, size_t size) {
char content[16384];
char record_file[] = "/tmp/record_fuzzerXXXXXX";
static struct configuration config = { { 0 }, { 0 }, { 0 }, false, NULL };
// Get a null ended string
strncpy(content, (const char *)data, size);
save_data(record_file, content);
// read_record(char *fullpath, char *headers[], char **body, char **cfg_file)
unlink(record_file);
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
test_read_record(data, size);
return 0;
}
+73
View File
@@ -0,0 +1,73 @@
#include <telemetry.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int test_tm_set_payload(char *payload) {
int ret = 0;
static uint32_t severity = 1;
static uint32_t payload_version = 1;
static const char *opt_class = "clearlinux/debug/fuzzing";
struct telem_ref *t_ref = NULL;
if ((ret = tm_create_record(&t_ref, (uint32_t)severity,
(char *)opt_class, payload_version)) < 0) {
return ret;
}
ret = tm_set_payload(t_ref, payload);
tm_free_record(t_ref);
return ret;
}
void test_tm_set_config_file(char *path) {
/*
No need to check returning value because
the important part is not it fails, but
if this crashes.
*/
tm_set_config_file(path);
}
int test_tm_set_event_id(char *full_id) {
int ret = 0;
char *id = NULL;
static uint32_t severity = 1;
static uint32_t payload_version = 1;
static const char *opt_class = "clearlinux/debug/fuzzing";
struct telem_ref *t_ref = NULL;
if ((ret = tm_create_record(&t_ref, (uint32_t)severity,
(char *)opt_class, payload_version)) < 0) {
return ret;
}
id = strndup(full_id, 32);
ret = tm_set_event_id(t_ref, id);
free(id);
tm_free_record(t_ref);
return ret;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
int ret = 0;
char *payload = NULL;
/*
tm_set_payload expects a null terminated string, this
step duplicates data into a null terminated string.
*/
payload = strndup((char *)data, size);
if (payload == NULL) {
goto end;
}
test_tm_set_payload(payload);
test_tm_set_config_file(payload);
test_tm_set_event_id(payload);
free(payload);
end:
return ret;
}
+30
View File
@@ -0,0 +1,30 @@
COMPILER = clang
CLANG_FLAGS = \
-g \
-fsanitize=address,fuzzer
SOURCES = fuzz/libtelem_fuzzer.c
BIN = fuzz/libtelem_fuzzer
HALF_DAY_SEC = 43200
FUZZ_FLAGS = \
-max_len=16384 \
-timeout=10 \
-only_ascii=1 \
-runs=1000000 \
-max_total_time=$(HALF_DAY_SEC)
build_fuzz_libtelem:
LD_LIBRARY_PATH=src/.libs $(COMPILER) $(CLANG_FLAGS) -ltelemetry $(SOURCES) -o $(BIN)
fuzz: build_fuzz_kibtelem
$(BIN) fuzz/corpus $(FUZZ_FLAGS)
# vim: filetype=automake tabstop=8 shiftwidth=8 noexpandtab
create a makefile that builds {3 binaries}
{4 binaries}: fuzz_libtelem fuzz_config fuzz_iorec
each one has different compiling flags and SOURCES
+24
View File
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int save_data(char *filename, const char *data) {
FILE *temp_file = NULL;
int fd;
fd = mkstemp(filename);
if (fd == -1) {
return 1;
}
temp_file = fdopen(fd, "w");
if (temp_file == NULL) {
close(fd);
return 1;
}
fprintf(temp_file, "%s", data);
fclose(temp_file);
return 0;
}
+1
View File
@@ -0,0 +1 @@
int save_data(char *filename, const char *data);
-9
View File
@@ -1,9 +0,0 @@
# Security Policy
Intel is committed to rapidly addressing security vulnerabilities affecting our
customers and providing clear guidance on the solution, impact, severity and
mitigation.
## Reporting a Vulnerability
Please report any security vulnerabilities in this project [utilizing the
guidelines here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html).
+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. '-1' ensures it's null terminated
size_t newlen = fread(*body, sizeof(char), (size_t)size - 1, fp);
//read rest of file
size_t newlen = fread(*body, sizeof(char), (size_t)size, fp);
if (newlen == 0) {
telem_perror("Error reading staged file");
result = false;
+1 -3
View File
@@ -421,7 +421,6 @@ 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;
}
@@ -662,8 +661,7 @@ 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");
rc = 1;
goto quit;
return rc;
}
// update record count
telem_journal->record_count = telem_journal->record_count - count;
+1 -1
View File
@@ -587,7 +587,7 @@ int main(int argc, char **argv)
}
if (core_file) {
core_fd = open(core_file, O_RDONLY|O_NOFOLLOW);
core_fd = open(core_file, O_RDONLY);
if (core_fd == -1) {
telem_perror("Failed to open input core file");
goto fail;
+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) + 1);
memcpy(classification, str, strlen(str));
break;
case 'l':
payload_options |= PAYLOAD_LOCALE;
+2 -2
View File
@@ -44,14 +44,14 @@ int copy_file(char *src_file, char *dest_file)
ssize_t bytes_read, bytes_written;
int ret = -1;
src_fd = open(src_file, O_RDONLY|O_NOFOLLOW);
src_fd = open(src_file, O_RDONLY);
if (src_fd == -1) {
telem_log(LOG_ERR, "Failed to open file %s:%s\n", src_file,
strerror(errno));
goto end;
}
dest_fd = open(dest_file, O_WRONLY|O_CREAT|O_NOFOLLOW, 0644);
dest_fd = open(dest_file, O_WRONLY | O_CREAT, 0644);
if (dest_fd == -1) {
telem_log(LOG_ERR, "Failed to create file %s:%s\n", dest_file,
strerror(errno));
+8 -20
View File
@@ -25,7 +25,6 @@
#include <limits.h>
#include <stdbool.h>
#include <errno.h>
#include <fcntl.h>
#include "spool.h"
#include "telempostdaemon.h"
@@ -150,32 +149,25 @@ void process_spooled_record(const char *spool_dir, char *name,
}
(*records_processed)++;
// 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 clean;
}
if (fstat(fd, &buf) == -1) {
telem_perror("Unable to fstat record in spool");
goto exit;
ret = stat(record_name, &buf);
if (ret == -1) {
telem_perror("Unable to stat record in spool");
free(record_name);
return;
}
/*
* 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 file is a regular file , if uid is diff 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);
} else if (post_succeeded && *records_sent <= TM_SPOOL_MAX_SEND_RECORDS) {
transmit_spooled_record(record_name, &post_succeeded, buf.st_size);
@@ -202,9 +194,6 @@ void process_spooled_record(const char *spool_dir, char *name,
}
}
}
exit:
close(fd);
clean:
free(record_name);
}
@@ -355,7 +344,6 @@ int spool_record_compare(const void *entrya, const void *entryb, void *path)
ret = stat(pathb, &statentryb);
if (ret == -1) {
telem_log(LOG_ERR, "Unable to stat %s: %s\n", patha, strerror(errno));
free(patha);
free(pathb);
return 0;
}
+1 -1
View File
@@ -428,7 +428,7 @@ static int telemctl_opt_in(void)
/* Create a brand new file TM_OPT_IN, we may fail because the file exists already.
* In that case we are already opted in and we are done here. */
int fd = open(TM_OPT_IN, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH|O_NOFOLLOW);
int fd = open(TM_OPT_IN, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1) {
if (errno == EEXIST) {
fprintf(stderr, "Already opted in. Nothing to do.\n");
+2 -2
View File
@@ -49,9 +49,9 @@ static int version_file(void)
{
int fd;
fd = open(TM_SITE_VERSION_FILE, O_RDONLY|O_NOFOLLOW);
fd = open(TM_SITE_VERSION_FILE, O_RDONLY);
if (fd < 0) {
fd = open(TM_DIST_VERSION_FILE, O_RDONLY|O_NOFOLLOW);
fd = open(TM_DIST_VERSION_FILE, O_RDONLY);
}
return fd;
+22 -25
View File
@@ -266,7 +266,7 @@ 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());
@@ -288,35 +288,32 @@ 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);
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);
// 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;
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, custom_headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_body);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(json_body));
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY);
if (strlen(cert_file) > 0) {
if (access(cert_file, F_OK) != -1) {
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;
}
curl_easy_setopt(curl, CURLOPT_CAINFO, cert_file);
telem_log(LOG_INFO, "cafile was set to %s\n", cert_file);
}
}
@@ -347,12 +344,12 @@ 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;
+1 -1
View File
@@ -143,7 +143,7 @@ int get_random_id(char **buff)
int frandom = -1;
uint64_t random_id[2] = { '\0' };
frandom = open("/dev/urandom", O_RDONLY|O_NOFOLLOW);
frandom = open("/dev/urandom", O_RDONLY);
if (frandom < 0) {
return -1;
}