aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/cc/cc.c
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2014-10-28 12:00:39 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2014-10-28 12:00:39 +0000
commit0e1152fcc2fe48dea2583ac89d30ba77b4ab78cc (patch)
tree63f2365a6dbce30caad91ca3b5ad545a2e4beb51 /sys/netinet/cc/cc.c
parentfb7830888d63404404f597b4680dd8150fd5ae0c (diff)
downloadsrc-0e1152fcc2fe48dea2583ac89d30ba77b4ab78cc.tar.gz
src-0e1152fcc2fe48dea2583ac89d30ba77b4ab78cc.zip
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. MFC after: 3 days Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=273773
Diffstat (limited to 'sys/netinet/cc/cc.c')
-rw-r--r--sys/netinet/cc/cc.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c
index c04e83e8ab42..9f188332806e 100644
--- a/sys/netinet/cc/cc.c
+++ b/sys/netinet/cc/cc.c
@@ -92,36 +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) {
- /* NOTE: "newptr" is not zero terminated */
- if (req->newlen != strnlen(funcs->name,
- TCP_CA_NAME_MAX - 1))
- continue;
- if (bcmp(req->newptr, funcs->name, req->newlen))
- continue;
- 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);
}
/*