Edit

IABSD.fr/src/usr.sbin/ntpd/util.c

Branch :

  • Show log

    Commit

  • Author : otto
    Date : 2023-12-20 15:36:36
    Hash : 8745f5cf
    Message : introduce log_ntp_addr() and use it where applicable, avoids a null pointer deref in constraint.c reported by bluhm@; ok millert@

  • usr.sbin/ntpd/util.c
  • /*	$OpenBSD: util.c,v 1.28 2023/12/20 15:36:36 otto Exp $ */
    
    /*
     * Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org>
     *
     * Permission to use, copy, modify, and distribute this software for any
     * purpose with or without fee is hereby granted, provided that the above
     * copyright notice and this permission notice appear in all copies.
     *
     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     */
    
    #include <fcntl.h>
    #include <limits.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    
    #include "ntpd.h"
    
    double
    gettime_corrected(void)
    {
    	return (gettime() + getoffset());
    }
    
    double
    getoffset(void)
    {
    	struct timeval	tv;
    	if (adjtime(NULL, &tv) == -1)
    		return (0.0);
    	return (tv.tv_sec + 1.0e-6 * tv.tv_usec);
    }
    
    double
    gettime(void)
    {
    	struct timeval	tv;
    
    	if (gettimeofday(&tv, NULL) == -1)
    		fatal("gettimeofday");
    
    	return (gettime_from_timeval(&tv));
    }
    
    double
    gettime_from_timeval(struct timeval *tv)
    {
    	/*
    	 * Account for overflow on OSes that have a 32-bit time_t.
    	 */
    	return ((uint64_t)tv->tv_sec + JAN_1970 + 1.0e-6 * tv->tv_usec);
    }
    
    time_t
    getmonotime(void)
    {
    	struct timespec	ts;
    
    	if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
    		fatal("clock_gettime");
    
    	return (ts.tv_sec);
    }
    
    
    void
    d_to_tv(double d, struct timeval *tv)
    {
    	tv->tv_sec = d;
    	tv->tv_usec = (d - tv->tv_sec) * 1000000;
    	while (tv->tv_usec < 0) {
    		tv->tv_usec += 1000000;
    		tv->tv_sec -= 1;
    	}
    }
    
    double
    lfp_to_d(struct l_fixedpt lfp)
    {
    	double	base, ret;
    
    	lfp.int_partl = ntohl(lfp.int_partl);
    	lfp.fractionl = ntohl(lfp.fractionl);
    
    	/* see comment in ntp.h */
    	base = NTP_ERA;
    	if (lfp.int_partl <= INT32_MAX)
    		base++; 
    	ret = base * SECS_IN_ERA;
    	ret += (double)(lfp.int_partl) + ((double)lfp.fractionl / L_DENOMINATOR);
    
    	return (ret);
    }
    
    struct l_fixedpt
    d_to_lfp(double d)
    {
    	struct l_fixedpt	lfp;
    
    	while (d > SECS_IN_ERA)
    		d -= SECS_IN_ERA;
    	lfp.int_partl = htonl((u_int32_t)d);
    	lfp.fractionl = htonl((u_int32_t)((d - (u_int32_t)d) * L_DENOMINATOR));
    
    	return (lfp);
    }
    
    double
    sfp_to_d(struct s_fixedpt sfp)
    {
    	double	ret;
    
    	sfp.int_parts = ntohs(sfp.int_parts);
    	sfp.fractions = ntohs(sfp.fractions);
    
    	ret = (double)(sfp.int_parts) + ((double)sfp.fractions / S_DENOMINATOR);
    
    	return (ret);
    }
    
    struct s_fixedpt
    d_to_sfp(double d)
    {
    	struct s_fixedpt	sfp;
    
    	sfp.int_parts = htons((u_int16_t)d);
    	sfp.fractions = htons((u_int16_t)((d - (u_int16_t)d) * S_DENOMINATOR));
    
    	return (sfp);
    }
    
    char *
    print_rtable(int r)
    {
    	static char b[11];
    
    	b[0] = 0;
    	if (r > 0)
    		snprintf(b, sizeof(b), "rtable %d", r);
    
    	return (b);
    }
    
    const char *
    log_sockaddr(struct sockaddr *sa)
    {
    	static char	buf[NI_MAXHOST];
    
    	if (getnameinfo(sa, SA_LEN(sa), buf, sizeof(buf), NULL, 0,
    	    NI_NUMERICHOST))
    		return ("(unknown)");
    	else
    		return (buf);
    }
    
    const char *
    log_ntp_addr(struct ntp_addr *addr)
    {
    	if (addr == NULL)
    		return ("(unknown)");
    	return log_sockaddr((struct sockaddr *)&addr->ss);
    }
    
    pid_t
    start_child(char *pname, int cfd, int argc, char **argv)
    {
    	char		**nargv;
    	int		  nargc, i;
    	pid_t		  pid;
    
    	/* Prepare the child process new argv. */
    	nargv = calloc(argc + 3, sizeof(char *));
    	if (nargv == NULL)
    		fatal("%s: calloc", __func__);
    
    	/* Copy the program name first. */
    	nargc = 0;
    	nargv[nargc++] = argv[0];
    
    	/* Set the process name and copy the original args. */
    	nargv[nargc++] = "-P";
    	nargv[nargc++] = pname;
    	for (i = 1; i < argc; i++)
    		nargv[nargc++] = argv[i];
    
    	nargv[nargc] = NULL;
    
    	switch (pid = fork()) {
    	case -1:
    		fatal("%s: fork", __func__);
    		break;
    	case 0:
    		/* Prepare the parent socket and execute. */
    		if (cfd != PARENT_SOCK_FILENO) {
    			if (dup2(cfd, PARENT_SOCK_FILENO) == -1)
    				fatal("dup2");
    		} else if (fcntl(cfd, F_SETFD, 0) == -1)
    			fatal("fcntl");
    
    		execvp(argv[0], nargv);
    		fatal("%s: execvp", __func__);
    		break;
    
    	default:
    		/* Close child's socket end. */
    		close(cfd);
    		break;
    	}
    
    	free(nargv);
    	return (pid);
    }
    
    int
    sanitize_argv(int *argc, char ***argv)
    {
    	char		**nargv;
    	int		  nargc;
    	int		  i;
    
    	/*
    	 * We need at least three arguments:
    	 * Example: '/usr/sbin/ntpd' '-P' 'foobar'.
    	 */
    	if (*argc < 3)
    		return (-1);
    
    	*argc -= 2;
    
    	/* Allocate new arguments vector and copy pointers. */
    	nargv = calloc((*argc) + 1, sizeof(char *));
    	if (nargv == NULL)
    		return (-1);
    
    	nargc = 0;
    	nargv[nargc++] = (*argv)[0];
    	for (i = 1; i < *argc; i++)
    		nargv[nargc++] = (*argv)[i + 2];
    
    	nargv[nargc] = NULL;
    	*argv = nargv;
    	return (0);
    }