mirror of
https://github.com/openbsd/src.git
synced 2024-12-22 16:42:56 -08:00
Replace gethostbyaddr(3) with getnameinfo(3). Remove the sigprocmask()
that was necessary for gethostbyaddr() because the latter is not signal safe. Change the return code semantics of priv_getnameinfo() to match getnameinfo(3). input and OK jca@
This commit is contained in:
parent
ea1c22cc5a
commit
bd6df50781
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: privsep.c,v 1.37 2014/08/20 19:16:27 bluhm Exp $ */
|
||||
/* $OpenBSD: privsep.c,v 1.38 2014/08/20 20:10:17 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org>
|
||||
@ -68,7 +68,7 @@ enum cmd_types {
|
||||
PRIV_OPEN_CONFIG, /* open config file for reading only */
|
||||
PRIV_CONFIG_MODIFIED, /* check if config file has been modified */
|
||||
PRIV_GETADDRINFO, /* resolve host/service names */
|
||||
PRIV_GETHOSTBYADDR, /* resolve numeric address into hostname */
|
||||
PRIV_GETNAMEINFO, /* resolve numeric address into hostname */
|
||||
PRIV_DONE_CONFIG_PARSE /* signal that the initial config parse is done */
|
||||
};
|
||||
|
||||
@ -76,7 +76,7 @@ static int priv_fd = -1;
|
||||
static volatile pid_t child_pid = -1;
|
||||
static char config_file[MAXPATHLEN];
|
||||
static struct stat cf_info;
|
||||
static int allow_gethostbyaddr = 0;
|
||||
static int allow_getnameinfo = 0;
|
||||
static volatile sig_atomic_t cur_state = STATE_INIT;
|
||||
|
||||
/* Queue for the allowed logfiles */
|
||||
@ -100,12 +100,12 @@ static int may_read(int, void *, size_t);
|
||||
int
|
||||
priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
|
||||
{
|
||||
int i, fd, socks[2], cmd, addr_len, addr_af, result, restart;
|
||||
int i, fd, socks[2], cmd, addr_len, result, restart;
|
||||
size_t path_len, hostname_len, servname_len;
|
||||
char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN];
|
||||
char servname[MAXHOSTNAMELEN];
|
||||
struct sockaddr_storage addr;
|
||||
struct stat cf_stat;
|
||||
struct hostent *hp;
|
||||
struct passwd *pw;
|
||||
struct addrinfo hints, *res0;
|
||||
struct sigaction sa;
|
||||
@ -191,11 +191,11 @@ priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
|
||||
if (stat(config_file, &cf_info) < 0)
|
||||
err(1, "stat config file failed");
|
||||
|
||||
/* Save whether or not the child can have access to gethostbyaddr(3) */
|
||||
/* Save whether or not the child can have access to getnameinfo(3) */
|
||||
if (numeric > 0)
|
||||
allow_gethostbyaddr = 0;
|
||||
allow_getnameinfo = 0;
|
||||
else
|
||||
allow_gethostbyaddr = 1;
|
||||
allow_getnameinfo = 1;
|
||||
|
||||
TAILQ_INIT(&lognames);
|
||||
increase_state(STATE_CONFIG);
|
||||
@ -322,24 +322,24 @@ priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
|
||||
}
|
||||
break;
|
||||
|
||||
case PRIV_GETHOSTBYADDR:
|
||||
dprintf("[priv]: msg PRIV_GETHOSTBYADDR received\n");
|
||||
if (!allow_gethostbyaddr)
|
||||
errx(1, "rejected attempt to gethostbyaddr");
|
||||
/* Expecting: length, address, address family */
|
||||
case PRIV_GETNAMEINFO:
|
||||
dprintf("[priv]: msg PRIV_GETNAMEINFO received\n");
|
||||
if (!allow_getnameinfo)
|
||||
errx(1, "rejected attempt to getnameinfo");
|
||||
/* Expecting: length, sockaddr */
|
||||
must_read(socks[0], &addr_len, sizeof(int));
|
||||
if (addr_len <= 0 || addr_len > sizeof(hostname))
|
||||
if (addr_len <= 0 || addr_len > sizeof(addr))
|
||||
_exit(1);
|
||||
must_read(socks[0], hostname, addr_len);
|
||||
must_read(socks[0], &addr_af, sizeof(int));
|
||||
hp = gethostbyaddr(hostname, addr_len, addr_af);
|
||||
if (hp == NULL) {
|
||||
must_read(socks[0], &addr, addr_len);
|
||||
if (getnameinfo((struct sockaddr *)&addr, addr_len,
|
||||
hostname, sizeof(hostname), NULL, 0,
|
||||
NI_NOFQDN|NI_NAMEREQD|NI_DGRAM) != 0) {
|
||||
addr_len = 0;
|
||||
must_write(socks[0], &addr_len, sizeof(int));
|
||||
} else {
|
||||
addr_len = strlen(hp->h_name) + 1;
|
||||
addr_len = strlen(hostname) + 1;
|
||||
must_write(socks[0], &addr_len, sizeof(int));
|
||||
must_write(socks[0], hp->h_name, addr_len);
|
||||
must_write(socks[0], hostname, addr_len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -656,8 +656,8 @@ priv_config_parse_done(void)
|
||||
must_write(priv_fd, &cmd, sizeof(int));
|
||||
}
|
||||
|
||||
/* Name/service to address translation. Response is placed into addr, and
|
||||
* the length is returned (zero on error) */
|
||||
/* Name/service to address translation. Response is placed into addr.
|
||||
* Return 0 for success or < 0 for error like getaddrinfo(3) */
|
||||
int
|
||||
priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
|
||||
size_t addr_len)
|
||||
@ -701,36 +701,36 @@ priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Reverse address resolution; response is placed into res, and length of
|
||||
* response is returned (zero on error) */
|
||||
/* Reverse address resolution; response is placed into host.
|
||||
* Return 0 for success or < 0 for error like getnameinfo(3) */
|
||||
int
|
||||
priv_gethostbyaddr(char *addr, int addr_len, int af, char *res, size_t res_len)
|
||||
priv_getnameinfo(struct sockaddr *sa, socklen_t salen, char *host,
|
||||
size_t hostlen)
|
||||
{
|
||||
int cmd, ret_len;
|
||||
|
||||
if (priv_fd < 0)
|
||||
errx(1, "%s called from privileged portion", __func__);
|
||||
|
||||
cmd = PRIV_GETHOSTBYADDR;
|
||||
cmd = PRIV_GETNAMEINFO;
|
||||
must_write(priv_fd, &cmd, sizeof(int));
|
||||
must_write(priv_fd, &addr_len, sizeof(int));
|
||||
must_write(priv_fd, addr, addr_len);
|
||||
must_write(priv_fd, &af, sizeof(int));
|
||||
must_write(priv_fd, &salen, sizeof(int));
|
||||
must_write(priv_fd, sa, salen);
|
||||
|
||||
/* Expect back an integer size, and then a string of that length */
|
||||
must_read(priv_fd, &ret_len, sizeof(int));
|
||||
|
||||
/* Check there was no error (indicated by a return of 0) */
|
||||
if (!ret_len)
|
||||
return 0;
|
||||
return (-1);
|
||||
|
||||
/* Check we don't overflow the passed in buffer */
|
||||
if (res_len < ret_len)
|
||||
if (hostlen < ret_len)
|
||||
errx(1, "%s: overflow attempt in return", __func__);
|
||||
|
||||
/* Read the resolved hostname */
|
||||
must_read(priv_fd, res, ret_len);
|
||||
return ret_len;
|
||||
must_read(priv_fd, host, ret_len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Pass the signal through to child */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: syslogd.c,v 1.113 2014/08/20 19:16:27 bluhm Exp $ */
|
||||
/* $OpenBSD: syslogd.c,v 1.114 2014/08/20 20:10:17 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1988, 1993, 1994
|
||||
@ -250,7 +250,7 @@ volatile sig_atomic_t WantDie;
|
||||
volatile sig_atomic_t DoInit;
|
||||
|
||||
struct filed *cfline(char *, char *);
|
||||
void cvthname(struct sockaddr_in *, char *, size_t);
|
||||
void cvthname(struct sockaddr *, char *, size_t);
|
||||
int decode(const char *, const CODE *);
|
||||
void dodie(int);
|
||||
void doinit(int);
|
||||
@ -587,7 +587,7 @@ main(int argc, char *argv[])
|
||||
(struct sockaddr *)&frominet, &len);
|
||||
if (i > 0) {
|
||||
line[i] = '\0';
|
||||
cvthname(&frominet, resolve,
|
||||
cvthname((struct sockaddr *)&frominet, resolve,
|
||||
sizeof resolve);
|
||||
dprintf("cvthname res: %s\n", resolve);
|
||||
printline(resolve, line);
|
||||
@ -1096,38 +1096,20 @@ reapchild(int signo)
|
||||
* Return a printable representation of a host address.
|
||||
*/
|
||||
void
|
||||
cvthname(struct sockaddr_in *f, char *result, size_t res_len)
|
||||
cvthname(struct sockaddr *f, char *result, size_t res_len)
|
||||
{
|
||||
sigset_t omask, nmask;
|
||||
char *p, *ip;
|
||||
int ret_len;
|
||||
|
||||
if (f->sin_family != AF_INET) {
|
||||
if (getnameinfo(f, f->sa_len, result, res_len, NULL, 0,
|
||||
NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM) != 0) {
|
||||
dprintf("Malformed from address\n");
|
||||
strlcpy(result, "???", res_len);
|
||||
return;
|
||||
}
|
||||
|
||||
ip = inet_ntoa(f->sin_addr);
|
||||
dprintf("cvthname(%s)\n", ip);
|
||||
if (NoDNS) {
|
||||
strlcpy(result, ip, res_len);
|
||||
dprintf("cvthname(%s)\n", result);
|
||||
if (NoDNS)
|
||||
return;
|
||||
}
|
||||
|
||||
sigemptyset(&nmask);
|
||||
sigaddset(&nmask, SIGHUP);
|
||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||
|
||||
ret_len = priv_gethostbyaddr((char *)&f->sin_addr,
|
||||
sizeof(struct in_addr), f->sin_family, result, res_len);
|
||||
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
if (ret_len == 0) {
|
||||
dprintf("Host name for your address (%s) unknown\n", ip);
|
||||
strlcpy(result, ip, res_len);
|
||||
} else if ((p = strchr(result, '.')) && strcmp(p + 1, LocalDomain) == 0)
|
||||
*p = '\0';
|
||||
if (priv_getnameinfo(f, f->sa_len, result, res_len) != 0)
|
||||
dprintf("Host name for your address (%s) unknown\n", result);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: syslogd.h,v 1.10 2014/08/20 19:33:43 bluhm Exp $ */
|
||||
/* $OpenBSD: syslogd.h,v 1.11 2014/08/20 20:10:17 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org>
|
||||
@ -29,7 +29,7 @@ FILE *priv_open_config(void);
|
||||
void priv_config_parse_done(void);
|
||||
int priv_config_modified(void);
|
||||
int priv_getaddrinfo(char *, char *, struct sockaddr *, size_t);
|
||||
int priv_gethostbyaddr(char *, int, int, char *, size_t);
|
||||
int priv_getnameinfo(struct sockaddr *, socklen_t, char *, size_t);
|
||||
|
||||
/* Terminal message */
|
||||
char *ttymsg(struct iovec *, int, char *, int);
|
||||
|
Loading…
Reference in New Issue
Block a user