diff options
author | David Carlier <devnexen@gmail.com> | 2019-12-06 11:12:16 +0000 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2020-01-13 17:38:48 -0800 |
commit | 81d6ddce19e40093d952bb9d0dcd8b00af09d476 (patch) | |
tree | 999547d6682d143a1671bf43a8b4018aafeb4b45 | |
parent | 6beabdff0ac3b487413f7e8bde3bb7a0c659b17e (diff) | |
download | memcached-81d6ddce19e40093d952bb9d0dcd8b00af09d476.tar.gz |
auth file, using alternative bcmp implementation
... instead to
check the token. less optimised than the usual memcmp especially
it goes through the whole buffers but more resilient against possible
attacks.
While at it, constifying a var which should have been.
-rw-r--r-- | authfile.c | 7 | ||||
-rw-r--r-- | extstore.c | 2 | ||||
-rw-r--r-- | util.c | 17 | ||||
-rw-r--r-- | util.h | 1 |
4 files changed, 24 insertions, 3 deletions
@@ -1,12 +1,15 @@ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <inttypes.h> #include "authfile.h" +#include "util.h" // TODO: frontend needs a refactor so this can avoid global objects. @@ -114,8 +117,8 @@ int authfile_check(const char *user, const char *pass) { for (int x = 0; x < entry_cnt; x++) { auth_t *e = &main_auth_entries[x]; if (ulen == e->ulen && plen == e->plen && - memcmp(user, e->user, e->ulen) == 0 && - memcmp(pass, e->pass, e->plen) == 0) { + safe_memcmp(user, e->user, e->ulen) && + safe_memcmp(pass, e->pass, e->plen)) { return 1; } } @@ -186,7 +186,7 @@ void extstore_get_page_data(void *ptr, struct extstore_stats *st) { } const char *extstore_err(enum extstore_res res) { - char *rv = "unknown error"; + const char *rv = "unknown error"; switch (res) { case EXTSTORE_INIT_BAD_WBUF_SIZE: rv = "page_size must be divisible by wbuf_size"; @@ -203,6 +203,23 @@ bool safe_strcpy(char *dst, const char *src, const size_t dstmax) { } } +bool safe_memcmp(const void *a, const void *b, size_t len) { + const volatile unsigned char *ua = (const volatile unsigned char *)a; + const volatile unsigned char *ub = (const volatile unsigned char *)b; + int delta = 0; + size_t x; + + for (x = 0; x < len; x++) { + delta |= ua[x] ^ ub[x]; + } + + if (delta == 0) { + return true; + } else { + return false; + } +} + void vperror(const char *fmt, ...) { int old_errno = errno; char buf[1024]; @@ -18,6 +18,7 @@ bool safe_strtoul(const char *str, uint32_t *out); bool safe_strtol(const char *str, int32_t *out); bool safe_strtod(const char *str, double *out); bool safe_strcpy(char *dst, const char *src, const size_t dstmax); +bool safe_memcmp(const void *a, const void *b, size_t len); #ifndef HAVE_HTONLL extern uint64_t htonll(uint64_t); |