diff options
author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2014-10-28 12:00:39 +0000 |
---|---|---|
committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2014-10-28 12:00:39 +0000 |
commit | 0e1152fcc2fe48dea2583ac89d30ba77b4ab78cc (patch) | |
tree | 63f2365a6dbce30caad91ca3b5ad545a2e4beb51 /sys/netinet/cc/cc.c | |
parent | fb7830888d63404404f597b4680dd8150fd5ae0c (diff) | |
download | src-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.c | 53 |
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); } /* |