1/* Fortify tests for syslog interface.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 Copyright The GNU Toolchain Authors.
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
19
20#include <stdarg.h>
21#include <setjmp.h>
22#include <syslog.h>
23#include <string.h>
24#include <unistd.h>
25#include <stdio.h>
26
27#include <support/check.h>
28#include <support/support.h>
29#include <support/capture_subprocess.h>
30
31static const char *str2 = "F";
32static char buf2[10] = "%s";
33
34static volatile int chk_fail_ok;
35static jmp_buf chk_fail_buf;
36
37static void
38handler (int sig)
39{
40 if (chk_fail_ok)
41 {
42 chk_fail_ok = 0;
43 longjmp (chk_fail_buf, 1);
44 }
45 else
46 _exit (127);
47}
48
49#define FAIL() \
50 do { \
51 printf ("Failure on line %d\n", __LINE__); \
52 support_record_failure (); \
53 } while (0)
54#define CHK_FAIL_START \
55 chk_fail_ok = 1; \
56 if (! setjmp (chk_fail_buf)) \
57 {
58#define CHK_FAIL_END \
59 chk_fail_ok = 0; \
60 FAIL (); \
61 }
62
63static void
64call_vsyslog (int priority, const char *format, ...)
65{
66 va_list va;
67 va_start (va, format);
68 vsyslog (pri: priority, fmt: format, ap: va);
69 va_end (va);
70}
71
72static void
73run_syslog_chk (void *closure)
74{
75 int n1;
76 CHK_FAIL_START
77 syslog (LOG_USER | LOG_DEBUG, buf2, str2, &n1, str2, &n1);
78 CHK_FAIL_END
79}
80
81static void
82run_vsyslog_chk (void *closure)
83{
84 int n1;
85 CHK_FAIL_START
86 call_vsyslog (LOG_USER | LOG_DEBUG, format: buf2, str2, &n1, str2, &n1);
87 CHK_FAIL_END
88}
89
90static int
91do_test (void)
92{
93 set_fortify_handler (handler);
94
95 int n1, n2;
96
97 n1 = n2 = 0;
98 syslog (LOG_USER | LOG_DEBUG, "%s%n%s%n", str2, &n1, str2, &n2);
99 TEST_COMPARE (n1, 1);
100 TEST_COMPARE (n2, 2);
101
102 n1 = n2 = 0;
103 call_vsyslog (LOG_USER | LOG_DEBUG, format: "%s%n%s%n", str2, &n1, str2, &n2);
104 TEST_COMPARE (n1, 1);
105 TEST_COMPARE (n2, 2);
106
107 strcpy (buf2 + 2, "%n%s%n");
108
109 /* The wrapper tests need to be in a subprocess because the abort called by
110 printf does not unlock the internal syslog lock. */
111 {
112 struct support_capture_subprocess result
113 = support_capture_subprocess (callback: run_syslog_chk, NULL);
114 support_capture_subprocess_check (&result, context: "syslog", status_or_signal: 0, allowed: sc_allow_stderr);
115 support_capture_subprocess_free (&result);
116 }
117
118 {
119 struct support_capture_subprocess result
120 = support_capture_subprocess (callback: run_vsyslog_chk, NULL);
121 support_capture_subprocess_check (&result, context: "syslog", status_or_signal: 0, allowed: sc_allow_stderr);
122 support_capture_subprocess_free (&result);
123 }
124
125 return 0;
126}
127
128#include <support/test-driver.c>
129

source code of glibc/debug/tst-fortify-syslog.c