summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyson Andre <tysonandre775@hotmail.com>2021-07-22 10:17:17 -0400
committerdormando <dormando@rydia.net>2021-07-25 14:54:42 -0700
commitddee3e27a031be22f5f28c160be18fd3cb9bc63d (patch)
treec58b9b22603b1e4b4ab19644ac8956bd2914201d
parent56a0ba62baab4f9acb8606a8754815a4cacf24b7 (diff)
downloadmemcached-ddee3e27a031be22f5f28c160be18fd3cb9bc63d.tar.gz
Fix minor severity heap buffer overflow reading `--auth-file`1.6.10
Fixes #805 Allocate an extra byte for reading the last entry when there is no `\n` at the end of the file. Also, check if the user contains null bytes when reading the last entry. Unrelatedly, add handling in case the auth file size changes while it is being read.
-rw-r--r--authfile.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/authfile.c b/authfile.c
index 5f001d1..b6407e5 100644
--- a/authfile.c
+++ b/authfile.c
@@ -41,23 +41,29 @@ enum authfile_ret authfile_load(const char *file) {
return AUTHFILE_STATFAIL;
}
- auth_data = calloc(1, sb.st_size);
+ auth_data = calloc(1, sb.st_size + 1);
char *auth_cur = auth_data;
+ char *auth_end = auth_data + sb.st_size;
auth_t *entry_cur = auth_entries;
int used = 0;
- while ((fgets(auth_cur, MAX_ENTRY_LEN, pwfile)) != NULL) {
+ while ((fgets(auth_cur, auth_end - auth_cur < MAX_ENTRY_LEN ? auth_end - auth_cur : MAX_ENTRY_LEN, pwfile)) != NULL) {
int x;
int found = 0;
for (x = 0; x < MAX_ENTRY_LEN; x++) {
- if (!found && auth_cur[x] == ':') {
- entry_cur->user = auth_cur;
- entry_cur->ulen = x;
- entry_cur->pass = &auth_cur[x+1];
- found = 1;
- } else if (found) {
+ if (!found) {
+ if (auth_cur[x] == '\0') {
+ // The username is malformed - this is either the end of the file or a null byte.
+ break;
+ } else if (auth_cur[x] == ':') {
+ entry_cur->user = auth_cur;
+ entry_cur->ulen = x;
+ entry_cur->pass = &auth_cur[x+1];
+ found = 1;
+ }
+ } else {
// Find end of password.
if (auth_cur[x] == '\n' ||
auth_cur[x] == '\r' ||