aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-03-12 17:52:00 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2016-03-12 17:56:25 +0200
commit6007d801392d50e908b810c9658ad8bcd1f7d631 (patch)
tree8b590bf190f5cc0723b8393c32c1647e5f24f643
parentc90ba2a863a446b51b9ee960cead69a4b2884045 (diff)
downloadvmod-variable-4.0.tar.gz
vmod-variable-4.0.tar.bz2
Fix NULL dereferencing.4.0
The bug was triggered by invoking symtab_remove with the name that has not yet been entered into the symtab. Reported by Julian Sternberg. * src/variable.c (symtab_remove): Return ENOENT if no matching entry was found.
-rw-r--r--src/variable.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/variable.c b/src/variable.c
index e6bad1a..6b23c00 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -1,27 +1,27 @@
-/* This file is part of vmod-tbf
- Copyright (C) 2013-2015 Sergey Poznyakoff
+/* This file is part of vmod-variable
+ Copyright (C) 2013-2016 Sergey Poznyakoff
- Vmod-tbf is free software; you can redistribute it and/or modify
+ Vmod-variable is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- Vmod-tbf is distributed in the hope that it will be useful,
+ Vmod-variable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
+ along with vmod-variable. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdlib.h>
#include <stdarg.h>
#include <syslog.h>
#include <ctype.h>
#include <pcre.h>
#include "vrt.h"
#include "vcc_if.h"
#include "pthread.h"
#if VARNISHVERSION == 3
# include "bin/varnishd/cache.h"
@@ -172,24 +172,27 @@ symtab_remove(struct symtab *st, const char *name)
unsigned int pos, i, j, r;
struct variable *entry;
pos = hash_string(name, hash_size[st->hash_num]);
for (i = pos; (entry = st->tab[i]);) {
if (strcmp(entry->name, name) == 0)
break;
if (++i >= hash_size[st->hash_num])
i = 0;
if (i == pos)
return ENOENT;
}
+
+ if (!entry)
+ return ENOENT;
var_free(entry);
for (;;) {
st->tab[i] = NULL;
j = i;
do {
if (++i >= hash_size[st->hash_num])
i = 0;
if (!st->tab[i])
return 0;
@@ -383,24 +386,25 @@ vmod_global_unset(VARIABLE_CTX ctx, VCL_STRING name)
static struct symtab *
get_symtab(VARIABLE_CTX ctx)
{
struct symtab *st;
int fd = ctx->req->sp->fd;
assert(fd >= 0);
AZ(pthread_mutex_lock(&symtab_mtx));
if (symtabc <= fd) {
size_t n = fd + 1;
symtabv = realloc(symtabv, n * sizeof(symtabv[0]));
+ AN(symtabv);
while (symtabc < n)
symtabv[symtabc++] = NULL;
}
if (!symtabv[fd])
symtabv[fd] = symtab_create();
st = symtabv[fd];
if (st->vxid != ctx->req->sp->vxid)
symtab_clear(st);
st->vxid = ctx->req->sp->vxid;
AZ(pthread_mutex_unlock(&symtab_mtx));
return st;
}

Return to:

Send suggestions and report system problems to the System administrator.