summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgilles <gilles@openbsd.org>2014-09-29 08:41:55 +0000
committergilles <gilles@openbsd.org>2014-09-29 08:41:55 +0000
commitd0aa205828f59c306b7b58a2678fcfcdedefc63b (patch)
treeb99542fd1498a57a1636dab34ca1efdaf32c0818
parentsync (diff)
downloadwireguard-openbsd-d0aa205828f59c306b7b58a2678fcfcdedefc63b.tar.xz
wireguard-openbsd-d0aa205828f59c306b7b58a2678fcfcdedefc63b.zip
during a small refactor, we broke table_passwd.
lookup function rely on a parsing function to have a struct passwd members point to the appropriate position in a buffer... but instead of passing the buffer, the parsing function uses its own internal buffer which will no longer be valid upon return. turns out to work by luck in my tests, not so much when Daniel Adolfsson tried to use it. spotted by Daniel Adolfsson <daniel@priv.nu>
-rw-r--r--usr.sbin/smtpd/table_passwd.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/usr.sbin/smtpd/table_passwd.c b/usr.sbin/smtpd/table_passwd.c
index 85b2fe9fa7e..b290054cd4c 100644
--- a/usr.sbin/smtpd/table_passwd.c
+++ b/usr.sbin/smtpd/table_passwd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table_passwd.c,v 1.7 2014/07/08 13:49:09 eric Exp $ */
+/* $OpenBSD: table_passwd.c,v 1.8 2014/09/29 08:41:55 gilles Exp $ */
/*
* Copyright (c) 2013 Gilles Chehade <gilles@poolp.org>
@@ -33,7 +33,7 @@ static int table_passwd_update(void);
static int table_passwd_check(int, struct dict *, const char *);
static int table_passwd_lookup(int, struct dict *, const char *, char *, size_t);
static int table_passwd_fetch(int, struct dict *, char *, size_t);
-static int parse_passwd_entry(struct passwd *, const char *);
+static int parse_passwd_entry(struct passwd *, char *);
static char *config;
static struct dict *passwd;
@@ -82,6 +82,7 @@ table_passwd_update(void)
{
FILE *fp;
char *buf, *lbuf = NULL;
+ char tmp[LINE_MAX];
size_t len;
char *line;
struct passwd pw;
@@ -109,7 +110,12 @@ table_passwd_update(void)
lbuf[len] = '\0';
buf = lbuf;
}
- if (! parse_passwd_entry(&pw, buf)) {
+
+ if (strlcpy(tmp, buf, sizeof tmp) >= sizeof tmp) {
+ log_warnx("warn: table-passwd: line too long");
+ goto err;
+ }
+ if (! parse_passwd_entry(&pw, tmp)) {
log_warnx("warn: table-passwd: invalid entry");
goto err;
}
@@ -154,12 +160,14 @@ table_passwd_lookup(int service, struct dict *params, const char *key, char *dst
int r;
struct passwd pw;
char *line;
+ char tmp[LINE_MAX];
line = dict_get(passwd, key);
if (line == NULL)
return 0;
- if (! parse_passwd_entry(&pw, line)) {
+ (void)strlcpy(tmp, line, sizeof tmp);
+ if (! parse_passwd_entry(&pw, tmp)) {
log_warnx("warn: table-passwd: invalid entry");
return -1;
}
@@ -197,14 +205,11 @@ table_passwd_fetch(int service, struct dict *params, char *dst, size_t sz)
}
static int
-parse_passwd_entry(struct passwd *pw, const char *line)
+parse_passwd_entry(struct passwd *pw, char *buf)
{
const char *errstr;
char *p, *q;
- char buf[LINE_MAX];
- if (strlcpy(buf, line, sizeof buf) >= sizeof buf)
- return 0;
p = buf;
/* username */