summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Kloska <sebastian.kloska@snafu.de>2019-12-10 13:34:54 +0100
committerSaya Sugiura <39760799+ssugiura@users.noreply.github.com>2019-12-10 21:34:54 +0900
commitfe9df82ec5eee1da774d0dbe589df2aac0f73e0c (patch)
treedebcd66c128ae41aa34df4b6593d1e3699d316d9
parent52c275c51e253223230e235584ab07523a830303 (diff)
downloadDLT-daemon-fe9df82ec5eee1da774d0dbe589df2aac0f73e0c.tar.gz
BugFix: SEGFAULT when using AppArmor (#192)
* Symptome: If access to the trace directory is not granted by AppArmor access(...) still reports otherwise. dlt_offline_trace_get_total_size(...) tries to open the dir via opendir(...) and tries a readdir without any further check, which results in an SEGFAULT * Solution: (1) Make dlt_offline_trace_get_total_size return ssize_t instead of unsigned long, which gives us a chance to return an error state (2) Check the return value from opendir(...) and bail out on error. Use this to return DLT_RETURN_ERROR in dlt_offline_trace_check_size. * ToDo: (1) Error state is not yet checked and reported back. On Error we just don't generate any offline log files without any further complain. (2) Find a replacement for access(...) which reports properly under AppArmor. (3) Report the confusing behaviour of access(...) to the AppArmor team. Signed-off-by: Sebastian Kloska <seebastian.kloska@snafu.de>
-rw-r--r--include/dlt/dlt_offline_trace.h2
-rw-r--r--src/shared/dlt_offline_trace.c31
2 files changed, 18 insertions, 15 deletions
diff --git a/include/dlt/dlt_offline_trace.h b/include/dlt/dlt_offline_trace.h
index d54e19c..b5e096c 100644
--- a/include/dlt/dlt_offline_trace.h
+++ b/include/dlt/dlt_offline_trace.h
@@ -128,7 +128,7 @@ extern DltReturnValue dlt_offline_trace_write(DltOfflineTrace *trace,
* Get size of currently used offline trace buffer
* @return size in bytes
*/
-extern unsigned long dlt_offline_trace_get_total_size(DltOfflineTrace *trace);
+extern ssize_t dlt_offline_trace_get_total_size(DltOfflineTrace *trace);
/**
* Provides info about the offline logs storage directory
diff --git a/src/shared/dlt_offline_trace.c b/src/shared/dlt_offline_trace.c
index 8ab917b..303d6b3 100644
--- a/src/shared/dlt_offline_trace.c
+++ b/src/shared/dlt_offline_trace.c
@@ -99,19 +99,16 @@ unsigned int dlt_offline_trace_storage_dir_info(char *path, char *file_name, cha
else if (strlen(tmp_old) > strlen(files[i]->d_name))
tmp_old = files[i]->d_name;
else /* filename is equal, do a string compare */
- if (strcmp(tmp_old, files[i]->d_name) > 0)
- tmp_old = files[i]->d_name;
+ if (strcmp(tmp_old, files[i]->d_name) > 0)
+ tmp_old = files[i]->d_name;
}
if ((tmp_new == NULL) || (strlen(tmp_new) <= strlen(files[i]->d_name))) {
- if (tmp_new == NULL) {
+ if (tmp_new == NULL)
tmp_new = files[i]->d_name;
- }
/* when file name is longer, it is younger */
else if (strlen(tmp_new) < strlen(files[i]->d_name))
- {
tmp_new = files[i]->d_name;
- }
else if (strcmp(tmp_new, files[i]->d_name) < 0)
tmp_new = files[i]->d_name;
}
@@ -119,15 +116,13 @@ unsigned int dlt_offline_trace_storage_dir_info(char *path, char *file_name, cha
}
if (num > 0) {
- if (tmp_old != NULL) {
+ if (tmp_old != NULL)
if (strlen(tmp_old) < NAME_MAX)
strncpy(oldest, tmp_old, NAME_MAX);
- }
- if (tmp_new != NULL) {
+ if (tmp_new != NULL)
if (strlen(tmp_old) < NAME_MAX)
strncpy(newest, tmp_new, NAME_MAX);
- }
}
/* free scandir result */
@@ -218,7 +213,7 @@ DltReturnValue dlt_offline_trace_create_new_file(DltOfflineTrace *trace)
char oldest[NAME_MAX + 1] = { 0 };
/* targeting newest file, ignoring number of files in dir returned */
dlt_offline_trace_storage_dir_info(trace->directory,
- DLT_OFFLINETRACE_FILENAME_BASE, newest, oldest);
+ DLT_OFFLINETRACE_FILENAME_BASE, newest, oldest);
idx = dlt_offline_trace_get_idx_of_log_file(newest) + 1;
dlt_offline_trace_file_name(trace->filename, sizeof(trace->filename),
@@ -245,16 +240,19 @@ DltReturnValue dlt_offline_trace_create_new_file(DltOfflineTrace *trace)
return DLT_RETURN_OK; /* OK */
}
-unsigned long dlt_offline_trace_get_total_size(DltOfflineTrace *trace)
+ssize_t dlt_offline_trace_get_total_size(DltOfflineTrace *trace)
{
struct dirent *dp;
char filename[PATH_MAX + 1];
- unsigned long size = 0;
+ ssize_t size = 0;
struct stat status;
/* go through all dlt files in directory */
DIR *dir = opendir(trace->directory);
+ if (!dir)
+ return -1;
+
while ((dp = readdir(dir)) != NULL)
if (strstr(dp->d_name, DLT_OFFLINETRACE_FILENAME_BASE)) {
int res = snprintf(filename, sizeof(filename), "%s/%s", trace->directory, dp->d_name);
@@ -354,12 +352,17 @@ DltReturnValue dlt_offline_trace_check_size(DltOfflineTrace *trace)
return DLT_RETURN_ERROR;
}
+ ssize_t s = 0;
+
/* check size of complete offline trace */
- while ((int)dlt_offline_trace_get_total_size(trace) > (trace->maxSize - trace->fileSize))
+ while ((s = dlt_offline_trace_get_total_size(trace)) > (trace->maxSize - trace->fileSize))
/* remove oldest files as long as new file will not fit in completely into complete offline trace */
if (dlt_offline_trace_delete_oldest_file(trace) < 0)
return DLT_RETURN_ERROR;
+ if (s == -1)
+ return DLT_RETURN_ERROR;
+
return DLT_RETURN_OK; /* OK */
}