Compare commits

..
17 Commits
Author SHA1 Message Date
Alex Jaramillo 0c34fab4fa configure.ac: bump version
Small improvements after static code analysis.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-17 15:29:59 -07:00
Alex Jaramillo bd51b7c692 Use O_NOFOLLOW in open calls
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-03 13:53:55 -07:00
Alex Jaramillo 77874c9c40 Add missing free
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-03 13:53:55 -07:00
Alex Jaramillo 6a91a71475 Simplify resource disposition
Close file descriptor in one place instead of three.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-03 13:53:55 -07:00
Alex Jaramillo 0b10f69f2b Update security policy
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-02 15:19:08 -07:00
Alex Jaramillo b7f5eb0a7c README: note about tarball signature
Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-01 21:49:08 -07:00
Alex Jaramillo 4d32436b6c configure.ac: bump version
Includes static analysis fixes.

Signed-off-by: Alex Jaramillo <alex.v.jaramillo@intel.com>
2025-04-01 10:42:58 -07:00
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
16 changed files with 87 additions and 57 deletions
+6 -8
View File
@@ -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
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) \
+6 -1
View File
@@ -333,7 +333,12 @@ $ 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 this [link](https://01.org/security).
in [link](security.md).
+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.0], [https://clearlinux.org/])
AC_INIT([telemetrics-client], [2.4.3], [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])
+9
View File
@@ -0,0 +1,9 @@
# 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
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
@@ -587,7 +587,7 @@ int main(int argc, char **argv)
}
if (core_file) {
core_fd = open(core_file, O_RDONLY);
core_fd = open(core_file, O_RDONLY|O_NOFOLLOW);
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));
memcpy(classification, str, strlen(str) + 1);
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);
src_fd = open(src_file, O_RDONLY|O_NOFOLLOW);
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, 0644);
dest_fd = open(dest_file, O_WRONLY|O_CREAT|O_NOFOLLOW, 0644);
if (dest_fd == -1) {
telem_log(LOG_ERR, "Failed to create file %s:%s\n", dest_file,
strerror(errno));
+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,25 +150,32 @@ 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 clean;
}
if (fstat(fd, &buf) == -1) {
telem_perror("Unable to fstat record in spool");
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);
} else if (post_succeeded && *records_sent <= TM_SPOOL_MAX_SEND_RECORDS) {
transmit_spooled_record(record_name, &post_succeeded, buf.st_size);
@@ -194,6 +202,9 @@ void process_spooled_record(const char *spool_dir, char *name,
}
}
}
exit:
close(fd);
clean:
free(record_name);
}
@@ -344,6 +355,7 @@ 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);
int fd = open(TM_OPT_IN, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH|O_NOFOLLOW);
if (fd == -1) {
if (errno == EEXIST) {
fprintf(stderr, "Already opted in. Nothing to do.\n");
+8 -7
View File
@@ -49,9 +49,9 @@ static int version_file(void)
{
int fd;
fd = open(TM_SITE_VERSION_FILE, O_RDONLY);
fd = open(TM_SITE_VERSION_FILE, O_RDONLY|O_NOFOLLOW);
if (fd < 0) {
fd = open(TM_DIST_VERSION_FILE, O_RDONLY);
fd = open(TM_DIST_VERSION_FILE, O_RDONLY|O_NOFOLLOW);
}
return fd;
@@ -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);
+25 -22
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,32 +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);
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, json_body);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(json_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);
}
}
@@ -344,12 +347,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);
frandom = open("/dev/urandom", O_RDONLY|O_NOFOLLOW);
if (frandom < 0) {
return -1;
}