summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-10-30 08:04:48 +0000
committerhselasky <hselasky@FreeBSD.org>2014-10-30 08:04:48 +0000
commit1d17f744c7fc351c6163d4e1a9862bef78a632d5 (patch)
treeb10daf90a34256f49336c4827661577d2b1339d3 /sys/netinet
parent2b4fb093044897c573e0f1cfe28d235e8c83db08 (diff)
downloadFreeBSD-src-1d17f744c7fc351c6163d4e1a9862bef78a632d5.zip
FreeBSD-src-1d17f744c7fc351c6163d4e1a9862bef78a632d5.tar.gz
MFC r273733, r273740 and r273773:
The SYSCTL data pointers can come from userspace and must not be directly accessed. Although this will work on some platforms, it can throw an exception if the pointer is invalid and then panic the kernel. Add a missing SYSCTL_IN() of "SCTP_BASE_STATS" structure. Sponsored by: Mellanox Technologies
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/cc/cc.c50
-rw-r--r--sys/netinet/sctp_sysctl.c23
-rw-r--r--sys/netinet/siftr.c53
3 files changed, 69 insertions, 57 deletions
diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c
index 19d84ab..9f18833 100644
--- a/sys/netinet/cc/cc.c
+++ b/sys/netinet/cc/cc.c
@@ -92,33 +92,33 @@ cc_default_algo(SYSCTL_HANDLER_ARGS)
{
char default_cc[TCP_CA_NAME_MAX];
struct cc_algo *funcs;
- int err, found;
-
- err = found = 0;
-
- if (req->newptr == NULL) {
- /* Just print the current default. */
- CC_LIST_RLOCK();
- strlcpy(default_cc, CC_DEFAULT()->name, TCP_CA_NAME_MAX);
- CC_LIST_RUNLOCK();
- err = sysctl_handle_string(oidp, default_cc, 0, req);
- } else {
- /* Find algo with specified name and set it to default. */
- CC_LIST_RLOCK();
- STAILQ_FOREACH(funcs, &cc_list, entries) {
- if (strncmp((char *)req->newptr, funcs->name,
- TCP_CA_NAME_MAX) == 0) {
- found = 1;
- V_default_cc_ptr = funcs;
- }
- }
- CC_LIST_RUNLOCK();
+ int error;
- if (!found)
- err = ESRCH;
- }
+ /* Get the current default: */
+ CC_LIST_RLOCK();
+ strlcpy(default_cc, CC_DEFAULT()->name, sizeof(default_cc));
+ CC_LIST_RUNLOCK();
- return (err);
+ error = sysctl_handle_string(oidp, default_cc, sizeof(default_cc), req);
+
+ /* Check for error or no change */
+ if (error != 0 || req->newptr == NULL)
+ goto done;
+
+ error = ESRCH;
+
+ /* Find algo with specified name and set it to default. */
+ CC_LIST_RLOCK();
+ STAILQ_FOREACH(funcs, &cc_list, entries) {
+ if (strncmp(default_cc, funcs->name, sizeof(default_cc)))
+ continue;
+ V_default_cc_ptr = funcs;
+ error = 0;
+ break;
+ }
+ CC_LIST_RUNLOCK();
+done:
+ return (error);
}
/*
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index 89e348a..1d97e34 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -636,17 +636,26 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
int error;
#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+ struct sctpstat sb_temp;
+ struct sctpstat *sarry;
+ struct sctpstat sb;
int cpu;
- struct sctpstat sb, *sarry;
-
#endif
if ((req->newptr != NULL) &&
(req->newlen != sizeof(struct sctpstat))) {
return (EINVAL);
}
+
#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
- memset(&sb, 0, sizeof(struct sctpstat));
+ memset(&sb, 0, sizeof(sb));
+ memset(&sb_temp, 0, sizeof(sb_temp));
+
+ if (req->newptr != NULL) {
+ error = SYSCTL_IN(req, &sb_temp, sizeof(sb_temp));
+ if (error != 0)
+ return (error);
+ }
for (cpu = 0; cpu < mp_maxid; cpu++) {
sarry = &SCTP_BASE_STATS[cpu];
if (sarry->sctps_discontinuitytime.tv_sec > sb.sctps_discontinuitytime.tv_sec) {
@@ -774,12 +783,14 @@ sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
sb.sctps_send_burst_avoid += sarry->sctps_send_burst_avoid;
sb.sctps_send_cwnd_avoid += sarry->sctps_send_cwnd_avoid;
sb.sctps_fwdtsn_map_over += sarry->sctps_fwdtsn_map_over;
- if (req->newptr != NULL) {
- memcpy(sarry, req->newptr, sizeof(struct sctpstat));
- }
+ if (req->newptr != NULL)
+ memcpy(sarry, &sb_temp, sizeof(struct sctpstat));
}
error = SYSCTL_OUT(req, &sb, sizeof(struct sctpstat));
#else
+ error = SYSCTL_IN(req, &SCTP_BASE_STATS, sizeof(struct sctpstat));
+ if (error)
+ return (error);
error = SYSCTL_OUT(req, &SCTP_BASE_STATS, sizeof(struct sctpstat));
#endif
return (error);
diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c
index 886be06..a484481 100644
--- a/sys/netinet/siftr.c
+++ b/sys/netinet/siftr.c
@@ -266,6 +266,7 @@ static unsigned int siftr_pkts_per_log = 1;
static unsigned int siftr_generate_hashes = 0;
/* static unsigned int siftr_binary_log = 0; */
static char siftr_logfile[PATH_MAX] = "/var/log/siftr.log";
+static char siftr_logfile_shadow[PATH_MAX] = "/var/log/siftr.log";
static u_long siftr_hashmask;
STAILQ_HEAD(pkthead, pkt_node) pkt_queue = STAILQ_HEAD_INITIALIZER(pkt_queue);
LIST_HEAD(listhead, flow_hash_node) *counter_hash;
@@ -297,7 +298,7 @@ SYSCTL_PROC(_net_inet_siftr, OID_AUTO, enabled, CTLTYPE_UINT|CTLFLAG_RW,
"switch siftr module operations on/off");
SYSCTL_PROC(_net_inet_siftr, OID_AUTO, logfile, CTLTYPE_STRING|CTLFLAG_RW,
- &siftr_logfile, sizeof(siftr_logfile), &siftr_sysctl_logfile_name_handler,
+ &siftr_logfile_shadow, sizeof(siftr_logfile_shadow), &siftr_sysctl_logfile_name_handler,
"A", "file to save siftr log messages to");
SYSCTL_UINT(_net_inet_siftr, OID_AUTO, ppl, CTLFLAG_RW,
@@ -1143,38 +1144,38 @@ siftr_sysctl_logfile_name_handler(SYSCTL_HANDLER_ARGS)
struct alq *new_alq;
int error;
- if (req->newptr == NULL)
- goto skip;
+ error = sysctl_handle_string(oidp, arg1, arg2, req);
- /* If old filename and new filename are different. */
- if (strncmp(siftr_logfile, (char *)req->newptr, PATH_MAX)) {
-
- error = alq_open(&new_alq, req->newptr, curthread->td_ucred,
- SIFTR_LOG_FILE_MODE, SIFTR_ALQ_BUFLEN, 0);
+ /* Check for error or same filename */
+ if (error != 0 || req->newptr == NULL ||
+ strncmp(siftr_logfile, arg1, arg2) == 0)
+ goto done;
- /* Bail if unable to create new alq. */
- if (error)
- return (1);
+ /* Filname changed */
+ error = alq_open(&new_alq, arg1, curthread->td_ucred,
+ SIFTR_LOG_FILE_MODE, SIFTR_ALQ_BUFLEN, 0);
+ if (error != 0)
+ goto done;
- /*
- * If disabled, siftr_alq == NULL so we simply close
- * the alq as we've proved it can be opened.
- * If enabled, close the existing alq and switch the old
- * for the new.
- */
- if (siftr_alq == NULL)
- alq_close(new_alq);
- else {
- alq_close(siftr_alq);
- siftr_alq = new_alq;
- }
+ /*
+ * If disabled, siftr_alq == NULL so we simply close
+ * the alq as we've proved it can be opened.
+ * If enabled, close the existing alq and switch the old
+ * for the new.
+ */
+ if (siftr_alq == NULL) {
+ alq_close(new_alq);
+ } else {
+ alq_close(siftr_alq);
+ siftr_alq = new_alq;
}
-skip:
- return (sysctl_handle_string(oidp, arg1, arg2, req));
+ /* Update filename upon success */
+ strlcpy(siftr_logfile, arg1, arg2);
+done:
+ return (error);
}
-
static int
siftr_manage_ops(uint8_t action)
{
OpenPOWER on IntegriCloud