Coverage Report

Created: 2025-07-12 06:35

/src/openvswitch/lib/daemon-unix.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at:
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include <config.h>
18
#include "backtrace.h"
19
#include "daemon.h"
20
#include "daemon-private.h"
21
#include <errno.h>
22
#include <fcntl.h>
23
#include <grp.h>
24
#include <pwd.h>
25
#include <signal.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <sys/resource.h>
29
#include <sys/wait.h>
30
#include <sys/stat.h>
31
#include <unistd.h>
32
#if HAVE_LIBCAPNG
33
#include <cap-ng.h>
34
#endif
35
#include "command-line.h"
36
#include "fatal-signal.h"
37
#include "dirs.h"
38
#include "lockfile.h"
39
#include "ovs-thread.h"
40
#include "process.h"
41
#include "socket-util.h"
42
#include "timeval.h"
43
#include "util.h"
44
#include "openvswitch/vlog.h"
45
46
VLOG_DEFINE_THIS_MODULE(daemon_unix);
47
48
#ifdef __linux__
49
0
#define LINUX 1
50
#else
51
#define LINUX 0
52
#endif
53
54
#if HAVE_LIBCAPNG
55
#define LIBCAPNG 1
56
#else
57
0
#define LIBCAPNG 0
58
#endif
59
60
/* --detach: Should we run in the background? */
61
bool detach;                    /* Was --detach specified? */
62
static bool detached;           /* Have we already detached? */
63
64
/* --pidfile: Name of pidfile (null if none). */
65
char *pidfile;
66
67
/* Device and inode of pidfile, so we can avoid reopening it. */
68
static dev_t pidfile_dev;
69
static ino_t pidfile_ino;
70
71
/* --overwrite-pidfile: Create pidfile even if one already exists and is
72
   locked? */
73
static bool overwrite_pidfile;
74
75
/* --no-chdir: Should we chdir to "/"? */
76
static bool chdir_ = true;
77
78
/* File descriptor used by daemonize_start() and daemonize_complete(). */
79
int daemonize_fd = -1;
80
81
/* --monitor: Should a supervisory process monitor the daemon and restart it if
82
 * it dies due to an error signal? */
83
bool monitor;
84
85
/* --user: Only root can use this option. Switch to new uid:gid after
86
 * initially running as root.  */
87
static bool switch_user = false;
88
static uid_t uid;
89
static gid_t gid;
90
static char *user = NULL;
91
static void daemon_become_new_user__(bool access_datapath,
92
                                     bool access_hardware_ports);
93
94
static void check_already_running(void);
95
static int lock_pidfile(FILE *, int command);
96
static pid_t fork_and_clean_up(void);
97
static void daemonize_post_detach(void);
98
99
/* Returns the file name that would be used for a pidfile if 'name' were
100
 * provided to set_pidfile().  The caller must free the returned string. */
101
char *
102
make_pidfile_name(const char *name)
103
0
{
104
0
    return (!name
105
0
            ? xasprintf("%s/%s.pid", ovs_rundir(), program_name)
106
0
            : abs_file_name(ovs_rundir(), name));
107
0
}
108
109
/* Sets that we do not chdir to "/". */
110
void
111
set_no_chdir(void)
112
0
{
113
0
    chdir_ = false;
114
0
}
115
116
/* Normally, daemonize() or damonize_start() will terminate the program with a
117
 * message if a locked pidfile already exists.  If this function is called, an
118
 * existing pidfile will be replaced, with a warning. */
119
void
120
ignore_existing_pidfile(void)
121
0
{
122
0
    overwrite_pidfile = true;
123
0
}
124
125
/* Sets up a following call to daemonize() to detach from the foreground
126
 * session, running this process in the background.  */
127
void
128
set_detach(void)
129
0
{
130
0
    detach = true;
131
0
}
132
133
/* Sets up a following call to daemonize() to fork a supervisory process to
134
 * monitor the daemon and restart it if it dies due to an error signal.  */
135
void
136
daemon_set_monitor(void)
137
0
{
138
0
    monitor = true;
139
0
}
140
141
/* If a pidfile has been configured, creates it and stores the running
142
 * process's pid in it.  Ensures that the pidfile will be deleted when the
143
 * process exits. */
144
static void
145
make_pidfile(void)
146
0
{
147
0
    long int pid = getpid();
148
0
    struct stat s;
149
0
    char *tmpfile;
150
0
    FILE *file;
151
0
    int error;
152
153
    /* Create a temporary pidfile. */
154
0
    if (overwrite_pidfile) {
155
0
        tmpfile = xasprintf("%s.tmp%ld", pidfile, pid);
156
0
        fatal_signal_add_file_to_unlink(tmpfile);
157
0
    } else {
158
        /* Everyone shares the same file which will be treated as a lock.  To
159
         * avoid some uncomfortable race conditions, we can't set up the fatal
160
         * signal unlink until we've acquired it. */
161
0
        tmpfile = xasprintf("%s.tmp", pidfile);
162
0
    }
163
164
0
    file = fopen(tmpfile, "a+");
165
0
    if (!file) {
166
0
        VLOG_FATAL("%s: create failed (%s)", tmpfile, ovs_strerror(errno));
167
0
    }
168
169
0
    error = lock_pidfile(file, F_SETLK);
170
0
    if (error) {
171
        /* Looks like we failed to acquire the lock.  Note that, if we failed
172
         * for some other reason (and '!overwrite_pidfile'), we will have
173
         * left 'tmpfile' as garbage in the file system. */
174
0
        VLOG_FATAL("%s: fcntl(F_SETLK) failed (%s)", tmpfile,
175
0
                   ovs_strerror(error));
176
0
    }
177
178
0
    if (!overwrite_pidfile) {
179
        /* We acquired the lock.  Make sure to clean up on exit, and verify
180
         * that we're allowed to create the actual pidfile. */
181
0
        fatal_signal_add_file_to_unlink(tmpfile);
182
0
        check_already_running();
183
0
    }
184
185
0
    if (fstat(fileno(file), &s) == -1) {
186
0
        VLOG_FATAL("%s: fstat failed (%s)", tmpfile, ovs_strerror(errno));
187
0
    }
188
189
0
    if (ftruncate(fileno(file), 0) == -1) {
190
0
        VLOG_FATAL("%s: truncate failed (%s)", tmpfile, ovs_strerror(errno));
191
0
    }
192
193
0
    fprintf(file, "%ld\n", pid);
194
0
    if (fflush(file) == EOF) {
195
0
        VLOG_FATAL("%s: write failed (%s)", tmpfile, ovs_strerror(errno));
196
0
    }
197
198
0
    error = rename(tmpfile, pidfile);
199
200
    /* Due to a race, 'tmpfile' may be owned by a different process, so we
201
     * shouldn't delete it on exit. */
202
0
    fatal_signal_remove_file_to_unlink(tmpfile);
203
204
0
    if (error < 0) {
205
0
        VLOG_FATAL("failed to rename \"%s\" to \"%s\" (%s)",
206
0
                   tmpfile, pidfile, ovs_strerror(errno));
207
0
    }
208
209
    /* Ensure that the pidfile will get deleted on exit. */
210
0
    fatal_signal_add_file_to_unlink(pidfile);
211
212
    /* Clean up.
213
     *
214
     * We don't close 'file' because its file descriptor must remain open to
215
     * hold the lock. */
216
0
    pidfile_dev = s.st_dev;
217
0
    pidfile_ino = s.st_ino;
218
0
    free(tmpfile);
219
0
}
220
221
/* Calls fork() and on success returns its return value.  On failure, logs an
222
 * error and exits unsuccessfully.
223
 *
224
 * Post-fork, but before returning, this function calls a few other functions
225
 * that are generally useful if the child isn't planning to exec a new
226
 * process. */
227
static pid_t
228
fork_and_clean_up(void)
229
0
{
230
0
    pid_t pid = xfork();
231
0
    if (pid > 0) {
232
        /* Running in parent process. */
233
0
        fatal_signal_fork();
234
0
    } else if (!pid) {
235
        /* Running in child process. */
236
0
        lockfile_postfork();
237
0
    }
238
0
    return pid;
239
0
}
240
241
/* Forks, then:
242
 *
243
 *   - In the parent, waits for the child to signal that it has completed its
244
 *     startup sequence.  Then stores -1 in '*fdp' and returns the child's
245
 *     pid in '*child_pid' argument.
246
 *
247
 *   - In the child, stores a fd in '*fdp' and returns 0 through '*child_pid'
248
 *     argument.  The caller should pass the fd to fork_notify_startup() after
249
 *     it finishes its startup sequence.
250
 *
251
 * Returns 0 on success.  If something goes wrong and child process was not
252
 * able to signal its readiness by calling fork_notify_startup(), then this
253
 * function returns -1. However, even in case of failure it still sets child
254
 * process id in '*child_pid'. */
255
static int
256
fork_and_wait_for_startup(int *fdp, pid_t *child_pid)
257
0
{
258
0
    int fds[2];
259
0
    pid_t pid;
260
0
    int ret = 0;
261
262
0
    xpipe(fds);
263
264
0
    pid = fork_and_clean_up();
265
0
    if (pid > 0) {
266
        /* Running in parent process. */
267
0
        size_t bytes_read;
268
0
        char c;
269
270
0
        close(fds[1]);
271
0
        if (read_fully(fds[0], &c, 1, &bytes_read) != 0) {
272
0
            int retval;
273
0
            int status;
274
275
0
            do {
276
0
                retval = waitpid(pid, &status, 0);
277
0
            } while (retval == -1 && errno == EINTR);
278
279
0
            if (retval == pid) {
280
0
                if (WIFEXITED(status) && WEXITSTATUS(status)) {
281
                    /* Child exited with an error.  Convey the same error
282
                     * to our parent process as a courtesy. */
283
0
                    exit(WEXITSTATUS(status));
284
0
                } else {
285
0
                    char *status_msg = process_status_msg(status);
286
0
                    VLOG_ERR("fork child died before signaling startup (%s)",
287
0
                             status_msg);
288
0
                    ret = -1;
289
0
                    free(status_msg);
290
0
                }
291
0
            } else if (retval < 0) {
292
0
                VLOG_FATAL("waitpid failed (%s)", ovs_strerror(errno));
293
0
            } else {
294
0
                OVS_NOT_REACHED();
295
0
            }
296
0
        }
297
0
        *fdp = fds[0];
298
0
    } else if (!pid) {
299
        /* Running in child process. */
300
0
        close(fds[0]);
301
0
        *fdp = fds[1];
302
0
    }
303
0
    *child_pid = pid;
304
0
    return ret;
305
0
}
306
307
static void
308
fork_notify_startup(int fd)
309
0
{
310
0
    if (fd != -1) {
311
0
        size_t bytes_written;
312
0
        int error;
313
314
0
        error = write_fully(fd, "", 1, &bytes_written);
315
0
        if (error) {
316
0
            VLOG_FATAL("pipe write failed (%s)", ovs_strerror(error));
317
0
        }
318
0
    }
319
0
}
320
321
static bool
322
should_restart(int status)
323
0
{
324
0
    if (WIFSIGNALED(status)) {
325
0
        static const int error_signals[] = {
326
            /* This list of signals is documented in daemon.man.  If you
327
             * change the list, update the documentation too. */
328
0
            SIGABRT, SIGALRM, SIGBUS, SIGFPE, SIGILL, SIGPIPE, SIGSEGV,
329
0
            SIGXCPU, SIGXFSZ
330
0
        };
331
332
0
        size_t i;
333
334
0
        for (i = 0; i < ARRAY_SIZE(error_signals); i++) {
335
0
            if (error_signals[i] == WTERMSIG(status)) {
336
0
                return true;
337
0
            }
338
0
        }
339
0
    }
340
0
    return false;
341
0
}
342
343
static void
344
monitor_daemon(pid_t daemon_pid)
345
0
{
346
    /* XXX Should log daemon's stderr output at startup time. */
347
0
    time_t last_restart;
348
0
    char *status_msg;
349
0
    int crashes;
350
0
    bool child_ready = true;
351
352
0
    set_subprogram_name("monitor");
353
0
    status_msg = xstrdup("healthy");
354
0
    last_restart = TIME_MIN;
355
0
    crashes = 0;
356
0
    for (;;) {
357
0
        int retval;
358
0
        int status;
359
360
0
        ovs_cmdl_proctitle_set("monitoring pid %lu (%s)",
361
0
                               (unsigned long int) daemon_pid, status_msg);
362
363
0
        if (child_ready) {
364
0
            char *log_file = vlog_get_log_file();
365
0
            vlog_close_log_file();
366
0
            int error;
367
0
            do {
368
0
                retval = waitpid(daemon_pid, &status, 0);
369
0
                error = retval == -1 ? errno : 0;
370
0
            } while (error == EINTR);
371
0
            vlog_set_log_file(log_file);
372
0
            free(log_file);
373
0
            if (error) {
374
0
                VLOG_FATAL("waitpid failed (%s)", ovs_strerror(error));
375
0
            }
376
0
        }
377
378
0
        if (!child_ready || retval == daemon_pid) {
379
0
            char *s = process_status_msg(status);
380
0
            if (should_restart(status)) {
381
0
                free(status_msg);
382
0
                status_msg = xasprintf("%d crashes: pid %lu died, %s",
383
0
                                       ++crashes,
384
0
                                       (unsigned long int) daemon_pid, s);
385
0
                free(s);
386
387
0
                if (WCOREDUMP(status)) {
388
                    /* Disable further core dumps to save disk space. */
389
0
                    struct rlimit r;
390
391
0
                    r.rlim_cur = 0;
392
0
                    r.rlim_max = 0;
393
0
                    if (setrlimit(RLIMIT_CORE, &r) == -1) {
394
0
                        VLOG_WARN("failed to disable core dumps: %s",
395
0
                                  ovs_strerror(errno));
396
0
                    }
397
0
                }
398
399
0
                log_received_backtrace(daemonize_fd);
400
0
                close(daemonize_fd);
401
0
                daemonize_fd = -1;
402
403
                /* Throttle restarts to no more than once every 10 seconds. */
404
0
                if (time(NULL) < last_restart + 10) {
405
0
                    VLOG_WARN("%s, waiting until 10 seconds since last "
406
0
                              "restart", status_msg);
407
0
                    for (;;) {
408
0
                        time_t now = time(NULL);
409
0
                        time_t wakeup = last_restart + 10;
410
0
                        if (now >= wakeup) {
411
0
                            break;
412
0
                        }
413
0
                        xsleep(wakeup - now);
414
0
                    }
415
0
                }
416
0
                last_restart = time(NULL);
417
418
0
                VLOG_ERR("%s, restarting", status_msg);
419
0
                child_ready = !fork_and_wait_for_startup(&daemonize_fd,
420
0
                                                         &daemon_pid);
421
0
                if (child_ready && !daemon_pid) {
422
                    /* Child process needs to break out of monitoring
423
                     * loop. */
424
0
                    break;
425
0
                }
426
0
            } else {
427
0
                VLOG_INFO("pid %lu died, %s, exiting",
428
0
                          (unsigned long int) daemon_pid, s);
429
0
                free(s);
430
0
                exit(0);
431
0
            }
432
0
        }
433
0
    }
434
0
    free(status_msg);
435
436
    /* Running in new daemon process. */
437
0
    ovs_cmdl_proctitle_restore();
438
0
    set_subprogram_name(program_name);
439
0
}
440
441
/* If daemonization is configured, then starts daemonization, by forking and
442
 * returning in the child process.  The parent process hangs around until the
443
 * child lets it know either that it completed startup successfully (by calling
444
 * daemonize_complete()) or that it failed to start up (by exiting with a
445
 * nonzero exit code). */
446
void
447
daemonize_start(bool access_datapath, bool access_hardware_ports)
448
0
{
449
0
    assert_single_threaded();
450
0
    daemonize_fd = -1;
451
452
0
    if (switch_user) {
453
0
        daemon_become_new_user__(access_datapath, access_hardware_ports);
454
0
        switch_user = false;
455
0
    }
456
457
0
    if (detach) {
458
0
        pid_t pid;
459
460
0
        if (fork_and_wait_for_startup(&daemonize_fd, &pid)) {
461
0
            VLOG_FATAL("could not detach from foreground session");
462
0
        }
463
0
        if (pid > 0) {
464
            /* Running in parent process. */
465
0
            exit(0);
466
0
        }
467
468
        /* Running in daemon or monitor process. */
469
0
        setsid();
470
0
    }
471
472
0
    if (monitor) {
473
0
        int saved_daemonize_fd = daemonize_fd;
474
0
        pid_t daemon_pid;
475
476
0
        if (fork_and_wait_for_startup(&daemonize_fd, &daemon_pid)) {
477
0
            VLOG_FATAL("could not initiate process monitoring");
478
0
        }
479
0
        if (daemon_pid > 0) {
480
            /* Running in monitor process. */
481
0
            fork_notify_startup(saved_daemonize_fd);
482
0
            if (detach) {
483
0
                close_standard_fds();
484
0
            }
485
0
            monitor_daemon(daemon_pid);
486
0
        }
487
        /* Running in daemon process. */
488
0
    }
489
490
0
    forbid_forking("running in daemon process");
491
492
0
    if (pidfile) {
493
0
        make_pidfile();
494
0
    }
495
496
    /* Make sure that the unixctl commands for vlog get registered in a
497
     * daemon, even before the first log message. */
498
0
    vlog_init();
499
0
}
500
501
/* If daemonization is configured, then this function notifies the parent
502
 * process that the child process has completed startup successfully.  It also
503
 * call daemonize_post_detach().
504
 *
505
 * Calling this function more than once has no additional effect. */
506
void
507
daemonize_complete(void)
508
0
{
509
0
    if (pidfile) {
510
0
        free(pidfile);
511
0
        pidfile = NULL;
512
0
    }
513
514
0
    if (!detached) {
515
0
        detached = true;
516
517
0
        fork_notify_startup(daemonize_fd);
518
0
        daemonize_post_detach();
519
0
    }
520
0
}
521
522
/* If daemonization is configured, then this function does traditional Unix
523
 * daemonization behavior: join a new session, chdir to the root (if not
524
 * disabled), and close the standard file descriptors.
525
 *
526
 * It only makes sense to call this function as part of an implementation of a
527
 * special daemon subprocess.  A normal daemon should just call
528
 * daemonize_complete(). */
529
static void
530
daemonize_post_detach(void)
531
0
{
532
0
    if (detach) {
533
0
        if (chdir_) {
534
0
            ignore(chdir("/"));
535
0
        }
536
0
        close_standard_fds();
537
0
    }
538
0
}
539
540
void
541
daemon_usage(void)
542
0
{
543
0
    printf(
544
0
        "\nDaemon options:\n"
545
0
        "  --detach                run in background as daemon\n"
546
0
        "  --monitor               creates a process to monitor this daemon\n"
547
0
        "  --user=username[:group] changes the effective daemon user:group\n"
548
0
        "  --no-chdir              do not chdir to '/'\n"
549
0
        "  --pidfile[=FILE]        create pidfile (default: %s/%s.pid)\n"
550
0
        "  --overwrite-pidfile     with --pidfile, start even if already "
551
0
                                   "running\n",
552
0
        ovs_rundir(), program_name);
553
0
}
554
555
static int
556
lock_pidfile__(FILE *file, int command, struct flock *lck)
557
0
{
558
0
    int error;
559
560
0
    lck->l_type = F_WRLCK;
561
0
    lck->l_whence = SEEK_SET;
562
0
    lck->l_start = 0;
563
0
    lck->l_len = 0;
564
0
    lck->l_pid = 0;
565
566
0
    do {
567
0
        error = fcntl(fileno(file), command, lck) == -1 ? errno : 0;
568
0
    } while (error == EINTR);
569
0
    return error;
570
0
}
571
572
static int
573
lock_pidfile(FILE *file, int command)
574
0
{
575
0
    struct flock lck;
576
577
0
    return lock_pidfile__(file, command, &lck);
578
0
}
579
580
static pid_t
581
read_pidfile__(const char *pidfile_, bool delete_if_stale)
582
0
{
583
0
    struct stat s, s2;
584
0
    struct flock lck;
585
0
    char line[128];
586
0
    FILE *file;
587
0
    int error;
588
589
0
    if ((pidfile_ino || pidfile_dev)
590
0
        && !stat(pidfile_, &s)
591
0
        && s.st_ino == pidfile_ino && s.st_dev == pidfile_dev) {
592
        /* It's our own pidfile.  We can't afford to open it, because closing
593
         * *any* fd for a file that a process has locked also releases all the
594
         * locks on that file.
595
         *
596
         * Fortunately, we know the associated pid anyhow: */
597
0
        return getpid();
598
0
    }
599
600
0
    file = fopen(pidfile_, "r+");
601
0
    if (!file) {
602
0
        if (errno == ENOENT && delete_if_stale) {
603
0
            return 0;
604
0
        }
605
0
        error = errno;
606
0
        VLOG_WARN("%s: open: %s", pidfile_, ovs_strerror(error));
607
0
        goto error;
608
0
    }
609
610
0
    error = lock_pidfile__(file, F_GETLK, &lck);
611
0
    if (error) {
612
0
        VLOG_WARN("%s: fcntl: %s", pidfile_, ovs_strerror(error));
613
0
        goto error;
614
0
    }
615
0
    if (lck.l_type == F_UNLCK) {
616
        /* pidfile exists but it isn't locked by anyone.  We need to delete it
617
         * so that a new pidfile can go in its place.  But just calling
618
         * unlink(pidfile) makes a nasty race: what if someone else unlinks it
619
         * before we do and then replaces it by a valid pidfile?  We'd unlink
620
         * their valid pidfile.  We do a little dance to avoid the race, by
621
         * locking the invalid pidfile.  Only one process can have the invalid
622
         * pidfile locked, and only that process has the right to unlink it. */
623
0
        if (!delete_if_stale) {
624
0
            error = ESRCH;
625
0
            VLOG_DBG("%s: pid file is stale", pidfile_);
626
0
            goto error;
627
0
        }
628
629
        /* Get the lock. */
630
0
        error = lock_pidfile(file, F_SETLK);
631
0
        if (error) {
632
            /* We lost a race with someone else doing the same thing. */
633
0
            VLOG_WARN("%s: lost race to lock pidfile", pidfile_);
634
0
            goto error;
635
0
        }
636
637
        /* Is the file we have locked still named 'pidfile_'? */
638
0
        if (stat(pidfile_, &s) || fstat(fileno(file), &s2)
639
0
            || s.st_ino != s2.st_ino || s.st_dev != s2.st_dev) {
640
            /* No.  We lost a race with someone else who got the lock before
641
             * us, deleted the pidfile, and closed it (releasing the lock). */
642
0
            error = EALREADY;
643
0
            VLOG_WARN("%s: lost race to delete pidfile", pidfile_);
644
0
            goto error;
645
0
        }
646
647
        /* We won the right to delete the stale pidfile. */
648
0
        if (unlink(pidfile_)) {
649
0
            error = errno;
650
0
            VLOG_WARN("%s: failed to delete stale pidfile (%s)",
651
0
                      pidfile_, ovs_strerror(error));
652
0
            goto error;
653
0
        }
654
0
        VLOG_DBG("%s: deleted stale pidfile", pidfile_);
655
0
        fclose(file);
656
0
        return 0;
657
0
    }
658
659
0
    if (!fgets(line, sizeof line, file)) {
660
0
        if (ferror(file)) {
661
0
            error = errno;
662
0
            VLOG_WARN("%s: read: %s", pidfile_, ovs_strerror(error));
663
0
        } else {
664
0
            error = ESRCH;
665
0
            VLOG_WARN("%s: read: unexpected end of file", pidfile_);
666
0
        }
667
0
        goto error;
668
0
    }
669
670
0
    if (lck.l_pid != strtoul(line, NULL, 10)) {
671
        /* The process that has the pidfile locked is not the process that
672
         * created it.  It must be stale, with the process that has it locked
673
         * preparing to delete it. */
674
0
        error = ESRCH;
675
0
        VLOG_WARN("%s: stale pidfile for pid %s being deleted by pid %ld",
676
0
                  pidfile_, line, (long int) lck.l_pid);
677
0
        goto error;
678
0
    }
679
680
0
    fclose(file);
681
0
    return lck.l_pid;
682
683
0
error:
684
0
    if (file) {
685
0
        fclose(file);
686
0
    }
687
0
    return -error;
688
0
}
689
690
/* Opens and reads a PID from 'pidfile_'.  Returns the positive PID if
691
 * successful, otherwise a negative errno value. */
692
pid_t
693
read_pidfile(const char *pidfile_)
694
0
{
695
0
    return read_pidfile__(pidfile_, false);
696
0
}
697
698
/* Checks whether a process with the given 'pidfile' is already running and,
699
 * if so, aborts.  If 'pidfile' is stale, deletes it. */
700
static void
701
check_already_running(void)
702
0
{
703
0
    long int pid = read_pidfile__(pidfile, true);
704
0
    if (pid > 0) {
705
0
        VLOG_FATAL("%s: already running as pid %ld, aborting", pidfile, pid);
706
0
    } else if (pid < 0) {
707
0
        VLOG_FATAL("%s: pidfile check failed (%s), aborting",
708
0
                   pidfile, ovs_strerror(-pid));
709
0
    }
710
0
}
711
712

713
/* stub functions for non-windows platform. */
714
715
void
716
service_start(int *argc OVS_UNUSED, char **argv[] OVS_UNUSED)
717
0
{
718
0
}
719
720
void
721
service_stop(void)
722
0
{
723
0
}
724
725
bool
726
should_service_stop(void)
727
0
{
728
0
    return false;
729
0
}
730
731

732
static bool
733
gid_matches(gid_t expected, gid_t value)
734
0
{
735
0
    return expected == -1 || expected == value;
736
0
}
737
738
static bool
739
gid_verify(gid_t gid_)
740
0
{
741
0
    gid_t r, e;
742
0
743
0
    r = getgid();
744
0
    e = getegid();
745
0
    return (gid_matches(gid_, r) &&
746
0
            gid_matches(gid_, e));
747
0
}
748
749
static void
750
daemon_switch_group(gid_t gid_)
751
0
{
752
0
    if ((setgid(gid_) == -1) || !gid_verify(gid_)) {
753
0
        VLOG_FATAL("%s: fail to switch group to gid as %d, aborting",
754
0
                   pidfile, gid_);
755
0
    }
756
0
}
757
758
static bool
759
uid_matches(uid_t expected, uid_t value)
760
0
{
761
0
    return expected == -1 || expected == value;
762
0
}
763
764
static bool
765
uid_verify(const uid_t uid_)
766
0
{
767
0
    uid_t r, e;
768
0
769
0
    r = getuid();
770
0
    e = geteuid();
771
0
    return (uid_matches(uid_, r) &&
772
0
            uid_matches(uid_, e));
773
0
}
774
775
static void
776
daemon_switch_user(const uid_t uid_, const char *user_)
777
0
{
778
0
    if ((setuid(uid_) == -1) || !uid_verify(uid_)) {
779
0
        VLOG_FATAL("%s: fail to switch user to %s, aborting",
780
0
                   pidfile, user_);
781
0
    }
782
0
}
783
784
/* Use portable Unix APIs to switch uid:gid, when datapath
785
 * access is not required.  On Linux systems, all capabilities
786
 * will be dropped.  */
787
static void
788
daemon_become_new_user_unix(void)
789
0
{
790
0
    /* "Setuid Demystified" by Hao Chen, etc outlines some caveats of
791
0
     * around unix system call setuid() and friends. This implementation
792
0
     * mostly follow the advice given by the paper.  The paper is
793
0
     * published in 2002, so things could have changed.  */
794
0
795
0
    /* Change both real and effective uid and gid will permanently
796
0
     * drop the process' privilege.  "Setuid Demystified" suggested
797
0
     * that calling getuid() after each setuid() call to verify they
798
0
     * are actually set, because checking return code alone is not
799
0
     * sufficient.  */
800
0
    daemon_switch_group(gid);
801
0
    if (user && initgroups(user, gid) == -1) {
802
0
        VLOG_FATAL("%s: fail to add supplementary group gid %d, "
803
0
                   "aborting", pidfile, gid);
804
0
    }
805
0
    daemon_switch_user(uid, user);
806
0
}
807
808
/* Linux specific implementation of daemon_become_new_user()
809
 * using libcap-ng.   */
810
static void
811
daemon_become_new_user_linux(bool access_datapath OVS_UNUSED,
812
                             bool access_hardware_ports OVS_UNUSED)
813
0
{
814
0
#if defined __linux__ &&  HAVE_LIBCAPNG
815
0
    int ret;
816
0
817
0
    ret = capng_get_caps_process();
818
0
819
0
    if (!ret) {
820
0
        if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) {
821
0
            const capng_type_t cap_sets = CAPNG_EFFECTIVE|CAPNG_PERMITTED;
822
0
823
0
            capng_clear(CAPNG_SELECT_BOTH);
824
0
825
0
            ret = capng_update(CAPNG_ADD, cap_sets, CAP_IPC_LOCK)
826
0
                  || capng_update(CAPNG_ADD, cap_sets, CAP_NET_BIND_SERVICE);
827
0
828
0
            if (access_datapath && !ret) {
829
0
                ret = capng_update(CAPNG_ADD, cap_sets, CAP_NET_ADMIN)
830
0
                      || capng_update(CAPNG_ADD, cap_sets, CAP_NET_RAW)
831
0
                      || capng_update(CAPNG_ADD, cap_sets, CAP_NET_BROADCAST);
832
0
#ifdef DPDK_NETDEV
833
0
                if (access_hardware_ports && !ret) {
834
0
                    ret = capng_update(CAPNG_ADD, cap_sets, CAP_SYS_RAWIO);
835
0
                    if (!ret) {
836
0
                        VLOG_INFO("The Linux capability CAP_SYS_RAWIO "
837
0
                                  "is enabled.");
838
0
                    }
839
0
                }
840
0
#else
841
0
                if (access_hardware_ports) {
842
0
                    VLOG_WARN("No driver requires Linux capability "
843
0
                              "CAP_SYS_RAWIO, disabling it.");
844
0
                }
845
0
#endif
846
0
            }
847
0
        } else {
848
0
            ret = -1;
849
0
        }
850
0
    }
851
0
852
0
    if (!ret) {
853
0
        /* CAPNG_INIT_SUPP_GRP will be a better choice than
854
0
         * CAPNG_DROP_SUPP_GRP. However this enum value is only defined
855
0
         * with libcap-ng higher than version 0.7.4, which is not wildly
856
0
         * available on many Linux distributions yet. Taking a more
857
0
         * conservative approach to make sure OVS behaves consistently.
858
0
         *
859
0
         * XXX We may change this for future OVS releases.
860
0
         */
861
0
        ret = capng_change_id(uid, gid, CAPNG_DROP_SUPP_GRP
862
0
                              | CAPNG_CLEAR_BOUNDING);
863
0
    }
864
0
865
0
    if (ret) {
866
0
        VLOG_FATAL("%s: libcap-ng fail to switch to user and group "
867
0
                   "%d:%d, aborting", pidfile, uid, gid);
868
0
    }
869
0
#endif
870
0
}
871
872
static void
873
daemon_become_new_user__(bool access_datapath, bool access_hardware_ports)
874
0
{
875
    /* If vlog file has been created, change its owner to the non-root user
876
     * as specifed by the --user option.  */
877
0
    vlog_change_owner_unix(uid, gid);
878
879
0
    if (LINUX) {
880
0
        if (LIBCAPNG) {
881
0
            daemon_become_new_user_linux(access_datapath,
882
0
                                         access_hardware_ports);
883
0
        } else {
884
0
            VLOG_FATAL("%s: fail to downgrade user using libcap-ng. "
885
0
                       "(libcap-ng is not configured at compile time), "
886
0
                       "aborting.", pidfile);
887
0
        }
888
0
    } else {
889
0
        daemon_become_new_user_unix();
890
0
    }
891
0
}
892
893
/* Noramlly, user switch is embedded within daemonize_start().
894
 * However, there in case the user switch needs to be done
895
 * before daemonize_start(), the following API can be used.  */
896
void
897
daemon_become_new_user(bool access_datapath, bool access_hardware_ports)
898
0
{
899
0
    assert_single_threaded();
900
0
    if (switch_user) {
901
0
        daemon_become_new_user__(access_datapath, access_hardware_ports);
902
        /* daemonize_start() should not switch user again. */
903
0
        switch_user = false;
904
0
    }
905
0
}
906
907
/* Return the maximun suggested buffer size for both getpwname_r()
908
 * and getgrnam_r().
909
 *
910
 * This size may still not be big enough. in case getpwname_r()
911
 * and friends return ERANGE, a larger buffer should be supplied to
912
 * retry. (The man page did not specify the max size to stop at, we
913
 * will keep trying with doubling the buffer size for each round until
914
 * the size wrapps around size_t.  */
915
static size_t
916
get_sysconf_buffer_size(void)
917
0
{
918
0
    const size_t default_bufsize = 1024;
919
0
    long pwd_bs = 0, grp_bs = 0;
920
0
    size_t bufsize;
921
922
0
    errno = 0;
923
0
    if ((pwd_bs = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
924
0
        if (errno) {
925
0
            VLOG_FATAL("%s: Read initial passwordd struct size "
926
0
                       "failed (%s), aborting. ", pidfile,
927
0
                       ovs_strerror(errno));
928
0
        } else {
929
            /* As per API documentation, sysconf(_SC_GETPW_R_SIZE_MAX) may
930
             * return -1 without setting errno, indicating no recommended
931
             * size. In that case, fall back to the default buffer size. */
932
0
            pwd_bs = default_bufsize;
933
0
        }
934
0
    }
935
936
0
    errno = 0;
937
0
    if ((grp_bs = sysconf(_SC_GETGR_R_SIZE_MAX)) == -1) {
938
0
        if (errno) {
939
0
            VLOG_FATAL("%s: Read initial group struct size "
940
0
                       "failed (%s), aborting. ", pidfile,
941
0
                       ovs_strerror(errno));
942
0
        } else {
943
            /* See above comment on _SC_GETPW_R_SIZE_MAX, as the same applies
944
             * to _SC_GETGR_R_SIZE_MAX. */
945
0
            grp_bs = default_bufsize;
946
0
        }
947
0
    }
948
949
0
    bufsize = MAX(pwd_bs, grp_bs);
950
0
    return bufsize ? bufsize : default_bufsize;
951
0
}
952
953
/* Try to double the size of '*buf', return true
954
 * if successful, and '*sizep' will be updated with
955
 * the new size. Otherwise, return false.  */
956
static bool
957
enlarge_buffer(char **buf, size_t *sizep)
958
0
{
959
0
    size_t newsize = *sizep * 2;
960
961
0
    if (newsize > *sizep) {
962
0
        *buf = xrealloc(*buf, newsize);
963
0
        *sizep = newsize;
964
0
        return true;
965
0
    }
966
967
0
    return false;
968
0
}
969
970
/* Parse and sanity check user_spec.
971
 *
972
 * If successful, set global variables 'uid' and 'gid'
973
 * with the parsed results. Global variable 'user'
974
 * will be pointing to a string that stores the name
975
 * of the user to be switched into.
976
 *
977
 * Also set 'switch_to_new_user' to true, The actual
978
 * user switching is done as soon as daemonize_start()
979
 * is called. I/O access before calling daemonize_start()
980
 * will still be with root's credential.  */
981
void
982
daemon_set_new_user(const char *user_spec)
983
0
{
984
0
    char *pos = strchr(user_spec, ':');
985
0
    size_t init_bufsize, bufsize;
986
987
0
    init_bufsize = get_sysconf_buffer_size();
988
0
    uid = getuid();
989
0
    gid = getgid();
990
991
0
    if (geteuid() || uid) {
992
0
        VLOG_FATAL("%s: only root can use --user option", pidfile);
993
0
    }
994
995
0
    user_spec += strspn(user_spec, " \t\r\n");
996
0
    size_t len = pos ? pos - user_spec : strlen(user_spec);
997
0
    char *buf;
998
0
    struct passwd pwd, *res;
999
0
    int e;
1000
1001
0
    bufsize = init_bufsize;
1002
0
    buf = xmalloc(bufsize);
1003
0
    if (len) {
1004
0
        user = xmemdup0(user_spec, len);
1005
1006
0
        while ((e = getpwnam_r(user, &pwd, buf, bufsize, &res)) == ERANGE) {
1007
0
            if (!enlarge_buffer(&buf, &bufsize)) {
1008
0
                break;
1009
0
            }
1010
0
        }
1011
1012
0
        if (e != 0) {
1013
0
            VLOG_FATAL("%s: Failed to retrieve user %s's uid (%s), aborting.",
1014
0
                       pidfile, user, ovs_strerror(e));
1015
0
        }
1016
0
        if (res == NULL) {
1017
0
            VLOG_FATAL("%s: user %s not found, aborting.", pidfile, user);
1018
0
        }
1019
0
    } else {
1020
        /* User name is not specified, use current user.  */
1021
0
        while ((e = getpwuid_r(uid, &pwd, buf, bufsize, &res)) == ERANGE) {
1022
0
            if (!enlarge_buffer(&buf, &bufsize)) {
1023
0
                break;
1024
0
            }
1025
0
        }
1026
1027
0
        if (e != 0) {
1028
0
            VLOG_FATAL("%s: Failed to retrieve current user's name "
1029
0
                       "(%s), aborting.", pidfile, ovs_strerror(e));
1030
0
        }
1031
0
        user = xstrdup(pwd.pw_name);
1032
0
    }
1033
1034
0
    uid = pwd.pw_uid;
1035
0
    gid = pwd.pw_gid;
1036
0
    free(buf);
1037
1038
0
    if (pos) {
1039
0
        char *grpstr = pos + 1;
1040
0
        grpstr += strspn(grpstr, " \t\r\n");
1041
1042
0
        if (*grpstr) {
1043
0
            struct group grp, *gres;
1044
1045
0
            bufsize = init_bufsize;
1046
0
            buf = xmalloc(bufsize);
1047
0
            while ((e = getgrnam_r(grpstr, &grp, buf, bufsize, &gres))
1048
0
                         == ERANGE) {
1049
0
                if (!enlarge_buffer(&buf, &bufsize)) {
1050
0
                    break;
1051
0
                }
1052
0
            }
1053
1054
0
            if (e) {
1055
0
                VLOG_FATAL("%s: Failed to get group entry for %s, "
1056
0
                           "(%s), aborting.", pidfile, grpstr,
1057
0
                           ovs_strerror(e));
1058
0
            }
1059
0
            if (gres == NULL) {
1060
0
                VLOG_FATAL("%s: group %s not found, aborting.", pidfile,
1061
0
                           grpstr);
1062
0
            }
1063
1064
0
            if (gid != grp.gr_gid) {
1065
0
                char **mem;
1066
1067
0
                for (mem = grp.gr_mem; *mem; ++mem) {
1068
0
                    if (!strcmp(*mem, user)) {
1069
0
                        break;
1070
0
                    }
1071
0
                }
1072
1073
0
                if (!*mem) {
1074
0
                    VLOG_FATAL("%s: Invalid --user option %s (user %s is "
1075
0
                               "not in group %s), aborting.", pidfile,
1076
0
                               user_spec, user, grpstr);
1077
0
                }
1078
0
                gid = grp.gr_gid;
1079
0
            }
1080
0
            free(buf);
1081
0
        }
1082
0
    }
1083
1084
0
    switch_user = true;
1085
0
}