summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rpc.statd
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-07-11 17:11:42 +0000
committeralfred <alfred@FreeBSD.org>2002-07-11 17:11:42 +0000
commit9bbf00859f67b38524d8d38de2f0d384dfad8925 (patch)
treee8592d87fd9961d1e4a41dacd8e891e6dc075567 /usr.sbin/rpc.statd
parentd860561907f155e08d4d425c514be0103387b479 (diff)
downloadFreeBSD-src-9bbf00859f67b38524d8d38de2f0d384dfad8925.zip
FreeBSD-src-9bbf00859f67b38524d8d38de2f0d384dfad8925.tar.gz
Do not allow unsafe characters in monitored hostnames.
This is modified version of the fix posted in the PR, I've taken Wollman's advice and used strvis(3) to properly show invalid hostnames. PR: bin/39815
Diffstat (limited to 'usr.sbin/rpc.statd')
-rw-r--r--usr.sbin/rpc.statd/procs.c132
-rw-r--r--usr.sbin/rpc.statd/statd.h1
2 files changed, 95 insertions, 38 deletions
diff --git a/usr.sbin/rpc.statd/procs.c b/usr.sbin/rpc.statd/procs.c
index b508f33..bd58b1d 100644
--- a/usr.sbin/rpc.statd/procs.c
+++ b/usr.sbin/rpc.statd/procs.c
@@ -43,11 +43,51 @@ static const char rcsid[] =
#include <unistd.h>
#include <rpc/rpc.h>
#include <syslog.h>
+#include <vis.h>
#include <netdb.h> /* for gethostbyname() */
#include "statd.h"
-/* sm_stat_1 --------------------------------------------------------------- */
+/* sm_check_hostname -------------------------------------------------------- */
+/*
+ * Purpose: Check `mon_name' member of sm_name struct to ensure that the array
+ * consists only of printable characters.
+ *
+ * Returns: TRUE if hostname is good. FALSE if hostname contains binary or
+ * otherwise non-printable characters.
+ *
+ * Notes: Will syslog(3) to warn of corrupt hostname.
+ */
+
+int sm_check_hostname(struct svc_req *req, char *arg)
+{
+ int len, dstlen, ret;
+ struct sockaddr_in *claddr;
+ char *dst;
+
+ len = strlen(arg);
+ dstlen = (4 * len) + 1;
+ dst = malloc(dstlen);
+ claddr = svc_getcaller(req->rq_xprt);
+ ret = 1;
+
+ if (claddr == NULL || dst == NULL)
+ {
+ ret = 0;
+ }
+ else if (strvis(dst, arg, VIS_WHITE) != len)
+ {
+ syslog(LOG_ERR,
+ "sm_stat: client %s hostname %s contained invalid characters.",
+ inet_ntoa(claddr->sin_addr),
+ dst);
+ ret = 0;
+ }
+ free(dst);
+ return (ret);
+}
+
+/* sm_stat_1 --------------------------------------------------------------- */
/*
Purpose: RPC call to enquire if a host can be monitored
Returns: TRUE for any hostname that can be looked up to give
@@ -57,16 +97,25 @@ static const char rcsid[] =
struct sm_stat_res *sm_stat_1_svc(sm_name *arg, struct svc_req *req)
{
static sm_stat_res res;
+ static int err;
- if (debug) syslog(LOG_DEBUG, "stat called for host %s", arg->mon_name);
-
- if (gethostbyname(arg->mon_name)) res.res_stat = stat_succ;
- else
- {
- syslog(LOG_ERR, "invalid hostname to sm_stat: %s", arg->mon_name);
+ err = 1;
+ if ((err = sm_check_hostname(req, arg->mon_name)) == 0)
+ {
res.res_stat = stat_fail;
}
-
+ if (err != 0)
+ {
+ if (debug)
+ syslog(LOG_DEBUG, "stat called for host %s", arg->mon_name);
+ if (gethostbyname(arg->mon_name))
+ res.res_stat = stat_succ;
+ else
+ {
+ syslog(LOG_ERR, "invalid hostname to sm_stat: %s", arg->mon_name);
+ res.res_stat = stat_fail;
+ }
+ }
res.state = status_info->ourState;
return (&res);
}
@@ -84,49 +133,56 @@ struct sm_stat_res *sm_mon_1_svc(mon *arg, struct svc_req *req)
{
static sm_stat_res res;
HostInfo *hp;
+ static int err;
MonList *lp;
- if (debug)
+ if ((err = sm_check_hostname(req, arg->mon_id.mon_name)) == 0)
{
- syslog(LOG_DEBUG, "monitor request for host %s", arg->mon_id.mon_name);
- syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d",
- arg->mon_id.mon_name, arg->mon_id.my_id.my_name,
- arg->mon_id.my_id.my_prog, arg->mon_id.my_id.my_vers,
- arg->mon_id.my_id.my_proc);
+ res.res_stat = stat_fail;
}
- res.res_stat = stat_fail; /* Assume fail until set otherwise */
- res.state = status_info->ourState;
-
- /* Find existing host entry, or create one if not found */
- /* If find_host() fails, it will have logged the error already. */
- if (!gethostbyname(arg->mon_id.mon_name))
+ if (err != 0)
{
- syslog(LOG_ERR, "Invalid hostname to sm_mon: %s", arg->mon_id.mon_name);
- }
- else if ((hp = find_host(arg->mon_id.mon_name, TRUE)))
- {
- lp = (MonList *)malloc(sizeof(MonList));
- if (!lp)
+ if (debug)
{
- syslog(LOG_ERR, "Out of memory");
+ syslog(LOG_DEBUG, "monitor request for host %s", arg->mon_id.mon_name);
+ syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d",
+ arg->mon_id.mon_name, arg->mon_id.my_id.my_name,
+ arg->mon_id.my_id.my_prog, arg->mon_id.my_id.my_vers,
+ arg->mon_id.my_id.my_proc);
}
- else
+ res.res_stat = stat_fail; /* Assume fail until set otherwise */
+ res.state = status_info->ourState;
+
+ /* Find existing host entry, or create one if not found */
+ /* If find_host() fails, it will have logged the error already. */
+ if (!gethostbyname(arg->mon_id.mon_name))
+ {
+ syslog(LOG_ERR, "Invalid hostname to sm_mon: %s", arg->mon_id.mon_name);
+ }
+ else if ((hp = find_host(arg->mon_id.mon_name, TRUE)))
{
- strncpy(lp->notifyHost, arg->mon_id.my_id.my_name, SM_MAXSTRLEN);
- lp->notifyProg = arg->mon_id.my_id.my_prog;
- lp->notifyVers = arg->mon_id.my_id.my_vers;
- lp->notifyProc = arg->mon_id.my_id.my_proc;
- memcpy(lp->notifyData, arg->priv, sizeof(lp->notifyData));
+ lp = (MonList *)malloc(sizeof(MonList));
+ if (!lp)
+ {
+ syslog(LOG_ERR, "Out of memory");
+ }
+ else
+ {
+ strncpy(lp->notifyHost, arg->mon_id.my_id.my_name, SM_MAXSTRLEN);
+ lp->notifyProg = arg->mon_id.my_id.my_prog;
+ lp->notifyVers = arg->mon_id.my_id.my_vers;
+ lp->notifyProc = arg->mon_id.my_id.my_proc;
+ memcpy(lp->notifyData, arg->priv, sizeof(lp->notifyData));
- lp->next = hp->monList;
- hp->monList = lp;
- sync_file();
+ lp->next = hp->monList;
+ hp->monList = lp;
+ sync_file();
- res.res_stat = stat_succ; /* Report success */
+ res.res_stat = stat_succ; /* Report success */
+ }
}
}
-
return (&res);
}
diff --git a/usr.sbin/rpc.statd/statd.h b/usr.sbin/rpc.statd/statd.h
index 7bf7b1d..b3c5d41 100644
--- a/usr.sbin/rpc.statd/statd.h
+++ b/usr.sbin/rpc.statd/statd.h
@@ -108,3 +108,4 @@ extern HostInfo *find_host(char * /*hostname*/, int /*create*/);
extern void init_file(char * /*filename*/);
extern void notify_hosts(void);
extern void sync_file(void);
+extern int sm_check_hostname(struct svc_req *req, char *arg);
OpenPOWER on IntegriCloud