Coverage Report

Created: 2023-06-07 06:46

/src/sudo/lib/util/str2sig.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SPDX-License-Identifier: ISC
3
 *
4
 * Copyright (c) 2019-2020 Todd C. Miller <Todd.Miller@sudo.ws>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/*
20
 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
21
 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22
 */
23
24
#include <config.h>
25
26
#ifndef HAVE_STR2SIG
27
28
#include <errno.h>
29
#include <string.h>
30
#ifdef HAVE_STRINGS_H
31
# include <strings.h>
32
#endif /* HAVE_STRINGS_H */
33
#include <ctype.h>
34
#include <signal.h>
35
#include <unistd.h>
36
37
#include "sudo_compat.h"
38
#include "sudo_util.h"
39
40
#if !defined(HAVE_SIGABBREV_NP)
41
# if defined(HAVE_DECL_SYS_SIGNAME) && HAVE_DECL_SYS_SIGNAME == 1
42
#   define sigabbrev_np(_x) sys_signame[(_x)]
43
# elif defined(HAVE_DECL__SYS_SIGNAME) && HAVE_DECL__SYS_SIGNAME == 1
44
#   define sigabbrev_np(_x) _sys_signame[(_x)]
45
# elif defined(HAVE_SYS_SIGABBREV)
46
0
#   define sigabbrev_np(_x) sys_sigabbrev[(_x)]
47
#  if defined(HAVE_DECL_SYS_SIGABBREV) && HAVE_DECL_SYS_SIGABBREV == 0
48
    /* sys_sigabbrev is not declared by glibc */
49
    extern const char *const sys_sigabbrev[NSIG];
50
#  endif
51
# else
52
#   define sigabbrev_np(_x) sudo_sys_signame[(_x)]
53
    extern const char *const sudo_sys_signame[NSIG];
54
# endif
55
#endif /* !HAVE_SIGABBREV_NP */
56
57
/*
58
 * Many systems use aliases for source backward compatibility.
59
 */
60
static struct sigalias {
61
    const char *name;
62
    int number;
63
} sigaliases[] = {
64
#ifdef SIGABRT
65
    { "ABRT", SIGABRT },
66
#endif
67
#ifdef SIGCLD
68
    { "CLD",  SIGCLD },
69
#endif
70
#ifdef SIGIO
71
    { "IO",   SIGIO },
72
#endif
73
#ifdef SIGIOT
74
    { "IOT",  SIGIOT },
75
#endif
76
#ifdef SIGLOST
77
    { "LOST", SIGLOST },
78
#endif
79
#ifdef SIGPOLL
80
    { "POLL", SIGPOLL },
81
#endif
82
    { NULL, -1 }
83
};
84
85
/*
86
 * Translate signal name to number.
87
 */
88
int
89
sudo_str2sig(const char *signame, int *result)
90
0
{
91
0
    struct sigalias *alias;
92
0
    const char *errstr;
93
0
    int signo;
94
95
    /* Could be a signal number encoded as a string. */
96
0
    if (isdigit((unsigned char)signame[0])) {
97
0
  signo = sudo_strtonum(signame, 0, NSIG - 1, &errstr);
98
0
  if (errstr != NULL)
99
0
      return -1;
100
0
  *result = signo;
101
0
  return 0;
102
0
    }
103
104
    /* Check real-time signals. */
105
0
#if defined(SIGRTMIN)
106
0
    if (strncmp(signame, "RTMIN", 5) == 0) {
107
0
  if (signame[5] == '\0') {
108
0
      *result = SIGRTMIN;
109
0
      return 0;
110
0
  }
111
0
  if (signame[5] == '+') {
112
0
      if (isdigit((unsigned char)signame[6])) {
113
0
# ifdef _SC_RTSIG_MAX
114
0
    const long rtmax = sysconf(_SC_RTSIG_MAX);
115
# else
116
    const long rtmax = SIGRTMAX - SIGRTMIN;
117
# endif
118
0
    const int off = signame[6] - '0';
119
120
0
    if (rtmax > 0 && off < rtmax / 2) {
121
0
        *result = SIGRTMIN + off;
122
0
        return 0;
123
0
    }
124
0
      }
125
0
  }
126
0
    }
127
0
#endif
128
0
#if defined(SIGRTMAX)
129
0
    if (strncmp(signame, "RTMAX", 5) == 0) {
130
0
  if (signame[5] == '\0') {
131
0
      *result = SIGRTMAX;
132
0
      return 0;
133
0
  }
134
0
  if (signame[5] == '-') {
135
0
      if (isdigit((unsigned char)signame[6])) {
136
0
# ifdef _SC_RTSIG_MAX
137
0
    const long rtmax = sysconf(_SC_RTSIG_MAX);
138
# else
139
    const long rtmax = SIGRTMAX - SIGRTMIN;
140
# endif
141
0
    const int off = signame[6] - '0';
142
143
0
    if (rtmax > 0 && off < rtmax / 2) {
144
0
        *result = SIGRTMAX - off;
145
0
        return 0;
146
0
    }
147
0
      }
148
0
  }
149
0
    }
150
0
#endif
151
152
    /* Check aliases. */
153
0
    for (alias = sigaliases; alias->name != NULL; alias++) {
154
0
  if (strcmp(signame, alias->name) == 0) {
155
0
      *result = alias->number;
156
0
      return 0;
157
0
  }
158
0
    }
159
160
0
    for (signo = 1; signo < NSIG; signo++) {
161
0
  const char *cp = sigabbrev_np(signo);
162
0
  if (cp != NULL) {
163
      /* On macOS sys_signame[] may contain lower-case names. */
164
0
      if (strcasecmp(signame, cp) == 0) {
165
0
    *result = signo;
166
0
    return 0;
167
0
      }
168
0
  }
169
0
    }
170
171
0
    errno = EINVAL;
172
0
    return -1;
173
0
}
174
#endif /* HAVE_STR2SIG */