From 3be9c6bd2c4a2bd5dba317e032337810d4bac256 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Thu, 8 Apr 2021 14:09:24 +0200 Subject: [PATCH] Introduce dlog_is_fd_redirected Checks whether given FD is redirected to dlog. Change-Id: I71bc905d9c377c5ff6791d39955459d41923a29a Signed-off-by: Michal Bloch --- Makefile.am | 20 ++++++++++++++++++++ include/dlog-redirect-stdout.h | 1 + include/logpipe.h | 3 +++ packaging/dlog.spec | 1 + src/log-redirect-stdout/lib.c | 23 +++++++++++++++++++++++ src/shared/logcommon.c | 2 +- tests/dlog_test.in | 11 +++++++++++ tests/test_libredirect.c | 22 ++++++++++++++++++++++ 8 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/test_libredirect.c diff --git a/Makefile.am b/Makefile.am index 43e94bc..aa1c9b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -329,6 +329,26 @@ test_libdlogutil_LDADD = \ test_libdlogutil_SOURCES = \ tests/test_libdlogutil.c + +usrlibexeclibdlog_PROGRAMS += test_libredirect +test_libredirect_CFLAGS = \ + $(AM_CFLAGS) \ + -fPIE + +test_libredirect_LDFLAGS = \ + $(AM_LDFLAGS) \ + -pie + +test_libredirect_DEPENDENCIES = \ + libdlog_redirect_stdout.la + +test_libredirect_LDADD = \ + libdlog_redirect_stdout.la + +test_libredirect_SOURCES = \ + tests/test_libredirect.c + + check_PROGRAMS = \ src/tests/test_logger_log_storage \ src/tests/test_ptrs_list_pos \ diff --git a/include/dlog-redirect-stdout.h b/include/dlog-redirect-stdout.h index ec0d756..a391e2a 100644 --- a/include/dlog-redirect-stdout.h +++ b/include/dlog-redirect-stdout.h @@ -27,6 +27,7 @@ extern "C" { #endif int connect_dlog(int buffer, int fileno, const char *tag, int prio); +_Bool dlog_is_log_fd(int fd); #ifdef __cplusplus } diff --git a/include/logpipe.h b/include/logpipe.h index 285e36d..feb7922 100644 --- a/include/logpipe.h +++ b/include/logpipe.h @@ -28,6 +28,9 @@ #include +#define PIPE_FIFO_PATH_TEMPLATE_BASE "/run/dlog/priv/fifo/fd-" +#define PIPE_FIFO_PATH_TEMPLATE_FULL PIPE_FIFO_PATH_TEMPLATE_BASE "XXXXXX" + #define DLOG_CTRL_REQ_PIPE (struct dlog_control_msg) {sizeof(struct dlog_control_msg), DLOG_REQ_PIPE, 0} enum { diff --git a/packaging/dlog.spec b/packaging/dlog.spec index 9da9b03..a56e7cf 100644 --- a/packaging/dlog.spec +++ b/packaging/dlog.spec @@ -305,6 +305,7 @@ chsmack -e 'System' %{_libexecdir}/dlog-log-critical %{_libexecdir}/libdlog/perf_libdlog %{_libexecdir}/libdlog/test_libdlog %{_libexecdir}/libdlog/test_libdlogutil +%{_libexecdir}/libdlog/test_libredirect %{_libexecdir}/libdlog/test_filters %{_datadir}/dlog-pipe.conf.test %{_datadir}/dlog-logger.conf.test diff --git a/src/log-redirect-stdout/lib.c b/src/log-redirect-stdout/lib.c index ae6ff56..224644f 100644 --- a/src/log-redirect-stdout/lib.c +++ b/src/log-redirect-stdout/lib.c @@ -60,3 +60,26 @@ EXPORT_API int connect_dlog(int buffer, int fileno, const char *tag, int prio) return 0; } + +EXPORT_API _Bool dlog_is_log_fd(int fd) +{ + char fd_path[sizeof "/proc/self/fd/" STRINGIFY(INT_MAX)]; + snprintf(fd_path, sizeof fd_path, "/proc/self/fd/%d", fd); + + char link_path[sizeof PIPE_FIFO_PATH_TEMPLATE_BASE]; + ssize_t r = readlink(fd_path, link_path, sizeof link_path); + if (r < 0) + return false; + + /* readlink doesn't actually terminate with + * a null byte, but we don't really mind */ + if (strncmp(link_path, "/dev/log_" , sizeof "/dev/log_" - 1) + && strncmp(link_path, PIPE_FIFO_PATH_TEMPLATE_BASE, sizeof PIPE_FIFO_PATH_TEMPLATE_BASE - 1)) + return false; + + /* In theory somebody could manually open a connection + * to /dev/log_* which technically wouldn't be handled + * by dlog, but then it's still a logging FD in a way, + * so that would not even fully be a false positive. */ + return true; +} diff --git a/src/shared/logcommon.c b/src/shared/logcommon.c index fb6f520..298bcd6 100644 --- a/src/shared/logcommon.c +++ b/src/shared/logcommon.c @@ -403,7 +403,7 @@ int get_nonblocking_fifo(int fifo_fd[2], int flags) assert(fifo_fd); assert(!(flags & (O_RDONLY | O_WRONLY))); - char fifo_path[] = "/run/dlog/priv/fifo/fd-XXXXXX"; + char fifo_path[] = PIPE_FIFO_PATH_TEMPLATE_FULL; if (!mktemp(fifo_path)) return -errno; diff --git a/tests/dlog_test.in b/tests/dlog_test.in index 2d4973f..81e3368 100644 --- a/tests/dlog_test.in +++ b/tests/dlog_test.in @@ -962,6 +962,17 @@ EOF LOG_DETAILS="testing if dlogctl --disable-stdout respects buffer choice" [ "$(dlogutil -db main -v raw)" = "test" ] && ok || fail dlogutil -cb main + + LOG_DETAILS="testing if redirection check works (1/5)" + test_libredirect 0 0 && ok || fail + LOG_DETAILS="testing if redirection check works (2/5)" + dlog_redirect_stdout -- /usr/libexec/libdlog/test_libredirect 0 0 && ok || fail + LOG_DETAILS="testing if redirection check works (3/5)" + dlog_redirect_stdout --outtag X -- /usr/libexec/libdlog/test_libredirect 1 0 && ok || fail + LOG_DETAILS="testing if redirection check works (4/5)" + dlog_redirect_stdout --errtag X -- /usr/libexec/libdlog/test_libredirect 0 1 && ok || fail + LOG_DETAILS="testing if redirection check works (5/5)" + dlog_redirect_stdout --outtag X --errtag Y -- /usr/libexec/libdlog/test_libredirect 1 1 && ok || fail fi dlogutil -c diff --git a/tests/test_libredirect.c b/tests/test_libredirect.c new file mode 100644 index 0000000..eb8337c --- /dev/null +++ b/tests/test_libredirect.c @@ -0,0 +1,22 @@ +/* DLOG + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +int main(int argc, char **argv) +{ + return argc != 3 || dlog_is_log_fd(1) != (*argv[1] == '1') || dlog_is_log_fd(2) != (*argv[2] == '1'); +} -- 2.7.4