1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/types.h> 31 #include <sys/capsicum.h> 32 #include <sys/file.h> 33 #include <sys/stat.h> 34 35 #include <err.h> 36 #include <errno.h> 37 #include <fcntl.h> 38 #include <libgen.h> 39 #include <libutil.h> 40 #include <signal.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <time.h> 45 #include <unistd.h> 46 47 struct pidfh { 48 int pf_dirfd; 49 int pf_fd; 50 char pf_dir[MAXPATHLEN + 1]; 51 char pf_filename[MAXPATHLEN + 1]; 52 dev_t pf_dev; 53 ino_t pf_ino; 54 }; 55 56 static int _pidfile_remove(struct pidfh *pfh, int freeit); 57 58 static int 59 pidfile_verify(const struct pidfh *pfh) 60 { 61 struct stat sb; 62 63 if (pfh == NULL || pfh->pf_fd == -1) 64 return (EDOOFUS); 65 /* 66 * Check remembered descriptor. 67 */ 68 if (fstat(pfh->pf_fd, &sb) == -1) 69 return (errno); 70 if (sb.st_dev != pfh->pf_dev || sb.st_ino != pfh->pf_ino) 71 return (EDOOFUS); 72 return (0); 73 } 74 75 static int 76 pidfile_read_impl(int dirfd, const char *filename, pid_t *pidptr) 77 { 78 char buf[16], *endptr; 79 int error, fd, i; 80 81 fd = openat(dirfd, filename, O_RDONLY | O_CLOEXEC); 82 if (fd == -1) 83 return (errno); 84 85 i = read(fd, buf, sizeof(buf) - 1); 86 error = errno; /* Remember errno in case close() wants to change it. */ 87 close(fd); 88 if (i == -1) 89 return (error); 90 else if (i == 0) 91 return (EAGAIN); 92 buf[i] = '\0'; 93 94 *pidptr = strtol(buf, &endptr, 10); 95 if (endptr != &buf[i]) 96 return (EINVAL); 97 98 return (0); 99 } 100 101 static int 102 pidfile_read(int dirfd, const char *filename, pid_t *pidptr) 103 { 104 struct timespec rqtp; 105 int count; 106 107 count = 20; 108 rqtp.tv_sec = 0; 109 rqtp.tv_nsec = 5000000; 110 for (;;) { 111 errno = pidfile_read_impl(dirfd, filename, pidptr); 112 if (errno != EAGAIN || --count == 0) 113 break; 114 nanosleep(&rqtp, 0); 115 } 116 if (errno == EAGAIN) 117 *pidptr = -1; 118 return (errno); 119 } 120 121 struct pidfh * 122 pidfile_open(const char *pathp, mode_t mode, pid_t *pidptr) 123 { 124 char path[MAXPATHLEN]; 125 struct pidfh *pfh; 126 struct stat sb; 127 int error, fd, dirfd, dirlen, filenamelen; 128 cap_rights_t caprights; 129 130 pfh = malloc(sizeof(*pfh)); 131 if (pfh == NULL) 132 return (NULL); 133 134 if (pathp == NULL) { 135 dirlen = snprintf(pfh->pf_dir, sizeof(pfh->pf_dir), 136 "/var/run/"); 137 filenamelen = snprintf(pfh->pf_filename, 138 sizeof(pfh->pf_filename), "%s.pid", getprogname()); 139 } else { 140 if (strlcpy(path, pathp, sizeof(path)) >= sizeof(path)) { 141 free(pfh); 142 errno = ENAMETOOLONG; 143 return (NULL); 144 } 145 dirlen = strlcpy(pfh->pf_dir, dirname(path), 146 sizeof(pfh->pf_dir)); 147 (void)strlcpy(path, pathp, sizeof(path)); 148 filenamelen = strlcpy(pfh->pf_filename, basename(path), 149 sizeof(pfh->pf_filename)); 150 } 151 152 if (dirlen >= (int)sizeof(pfh->pf_dir) || 153 filenamelen >= (int)sizeof(pfh->pf_filename)) { 154 free(pfh); 155 errno = ENAMETOOLONG; 156 return (NULL); 157 } 158 159 dirfd = open(pfh->pf_dir, O_CLOEXEC | O_DIRECTORY | O_NONBLOCK); 160 if (dirfd == -1) { 161 error = errno; 162 free(pfh); 163 errno = error; 164 return (NULL); 165 } 166 167 /* 168 * Open the PID file and obtain exclusive lock. 169 * We truncate PID file here only to remove old PID immediately, 170 * PID file will be truncated again in pidfile_write(), so 171 * pidfile_write() can be called multiple times. 172 */ 173 fd = flopenat(dirfd, pfh->pf_filename, 174 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NONBLOCK, mode); 175 if (fd == -1) { 176 if (errno == EWOULDBLOCK) { 177 if (pidptr == NULL) { 178 errno = EEXIST; 179 } else { 180 errno = pidfile_read(dirfd, 181 pfh->pf_filename, pidptr); 182 if (errno == 0 || errno == EAGAIN) 183 errno = EEXIST; 184 } 185 } 186 error = errno; 187 close(dirfd); 188 free(pfh); 189 errno = error; 190 return (NULL); 191 } 192 193 /* 194 * Remember file information, so in pidfile_write() we are sure we write 195 * to the proper descriptor. 196 */ 197 if (fstat(fd, &sb) == -1) { 198 goto failed; 199 } 200 201 if (cap_rights_limit(dirfd, 202 cap_rights_init(&caprights, CAP_UNLINKAT)) < 0 && errno != ENOSYS) { 203 goto failed; 204 } 205 206 if (cap_rights_limit(fd, cap_rights_init(&caprights, CAP_PWRITE, 207 CAP_FSTAT, CAP_FTRUNCATE, CAP_EVENT)) < 0 && 208 errno != ENOSYS) { 209 goto failed; 210 } 211 212 pfh->pf_dirfd = dirfd; 213 pfh->pf_fd = fd; 214 pfh->pf_dev = sb.st_dev; 215 pfh->pf_ino = sb.st_ino; 216 217 return (pfh); 218 219 failed: 220 error = errno; 221 unlinkat(dirfd, pfh->pf_filename, 0); 222 close(dirfd); 223 close(fd); 224 free(pfh); 225 errno = error; 226 return (NULL); 227 } 228 229 int 230 pidfile_write(struct pidfh *pfh) 231 { 232 char pidstr[16]; 233 int error, fd; 234 235 /* 236 * Check remembered descriptor, so we don't overwrite some other 237 * file if pidfile was closed and descriptor reused. 238 */ 239 errno = pidfile_verify(pfh); 240 if (errno != 0) { 241 /* 242 * Don't close descriptor, because we are not sure if it's ours. 243 */ 244 return (-1); 245 } 246 fd = pfh->pf_fd; 247 248 /* 249 * Truncate PID file, so multiple calls of pidfile_write() are allowed. 250 */ 251 if (ftruncate(fd, 0) == -1) { 252 error = errno; 253 _pidfile_remove(pfh, 0); 254 errno = error; 255 return (-1); 256 } 257 258 snprintf(pidstr, sizeof(pidstr), "%u", getpid()); 259 if (pwrite(fd, pidstr, strlen(pidstr), 0) != (ssize_t)strlen(pidstr)) { 260 error = errno; 261 _pidfile_remove(pfh, 0); 262 errno = error; 263 return (-1); 264 } 265 266 return (0); 267 } 268 269 int 270 pidfile_close(struct pidfh *pfh) 271 { 272 int error; 273 274 error = pidfile_verify(pfh); 275 if (error != 0) { 276 errno = error; 277 return (-1); 278 } 279 280 if (close(pfh->pf_fd) == -1) 281 error = errno; 282 if (close(pfh->pf_dirfd) == -1 && error == 0) 283 error = errno; 284 285 free(pfh); 286 if (error != 0) { 287 errno = error; 288 return (-1); 289 } 290 return (0); 291 } 292 293 static int 294 _pidfile_remove(struct pidfh *pfh, int freeit) 295 { 296 int error; 297 298 error = pidfile_verify(pfh); 299 if (error != 0) { 300 errno = error; 301 return (-1); 302 } 303 304 if (funlinkat(pfh->pf_dirfd, pfh->pf_filename, pfh->pf_fd, 0) == -1) { 305 if (errno == EDEADLK) 306 return (-1); 307 error = errno; 308 } 309 if (close(pfh->pf_fd) == -1 && error == 0) 310 error = errno; 311 if (close(pfh->pf_dirfd) == -1 && error == 0) 312 error = errno; 313 if (freeit) 314 free(pfh); 315 else 316 pfh->pf_fd = -1; 317 if (error != 0) { 318 errno = error; 319 return (-1); 320 } 321 return (0); 322 } 323 324 int 325 pidfile_remove(struct pidfh *pfh) 326 { 327 328 return (_pidfile_remove(pfh, 1)); 329 } 330 331 int 332 pidfile_fileno(const struct pidfh *pfh) 333 { 334 335 if (pfh == NULL || pfh->pf_fd == -1) { 336 errno = EDOOFUS; 337 return (-1); 338 } 339 return (pfh->pf_fd); 340 } 341 342 int 343 pidfile_signal(const char *pathp, int sig, pid_t *pidptr) 344 { 345 pid_t pid; 346 int fd; 347 348 fd = flopenat(AT_FDCWD, pathp, 349 O_RDONLY | O_CLOEXEC | O_NONBLOCK); 350 if (fd >= 0) { 351 /* 352 * The file exists but is not locked, 353 * so the daemon is dead. Nothing to do. 354 */ 355 close(fd); 356 errno = ENOENT; 357 return (errno); 358 } 359 if (errno != EWOULDBLOCK) { 360 return (errno); 361 } 362 errno = pidfile_read(AT_FDCWD, pathp, &pid); 363 if (errno != 0) 364 return (errno); 365 /* 366 * Refuse to send broadcast or group signals, this has 367 * happened due to the bugs in pidfile(3). 368 */ 369 if (pid <= 0) 370 return (EDOM); 371 kill(pid, sig); 372 if (pidptr != NULL) 373 *pidptr = pid; 374 return (errno); 375 } 376