Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9e218af

Browse files
author
Neil Conway
committed
Fix a read of uninitialized memory in next_token() of hba.c, spotted via
valgrind: a buffer passed to strncmp() had to be NUL-terminated. Original report and patch from Dennis Bjorkland, some cleanup by Andrew Dunstan, and finally some editorializing from Neil Conway.
1 parent 4c29e21 commit 9e218af

File tree

2 files changed

+89
-89
lines changed

2 files changed

+89
-89
lines changed

src/backend/libpq/hba.c

Lines changed: 88 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.119 2003/12/25 03:44:04 momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.120 2004/02/02 16:58:30 neilc Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -37,12 +37,23 @@
3737
#include "storage/fd.h"
3838

3939

40-
#define IDENT_USERNAME_MAX 512
4140
/* Max size of username ident server can return */
41+
#define IDENT_USERNAME_MAX 512
42+
43+
/* Standard TCP port number for Ident service. Assigned by IANA */
44+
#define IDENT_PORT 113
45+
46+
/* Name of the config file */
47+
#define CONF_FILE "pg_hba.conf"
48+
49+
/* Name of the usermap file */
50+
#define USERMAP_FILE "pg_ident.conf"
4251

4352
/* This is used to separate values in multi-valued column strings */
4453
#define MULTI_VALUE_SEP "\001"
4554

55+
#define MAX_TOKEN 256
56+
4657
/*
4758
* These variables hold the pre-parsed contents of the hba and ident
4859
* configuration files. Each is a list of sublists, one sublist for
@@ -80,19 +91,19 @@ pg_isblank(const char c)
8091

8192

8293
/*
83-
* Grab one token out of fp. Tokens are strings of non-blank
84-
* characters bounded by blank characters, beginning of line, and
85-
* end of line. Blank means space or tab. Return the token as
86-
* *buf. Leave file positioned to character immediately after the
87-
* token or EOF, whichever comes first. If no more tokens on line,
88-
* return null string as *buf and position file to beginning of
89-
* next line or EOF, whichever comes first. Allow spaces in quoted
90-
* strings. Terminate on unquoted commas. Handle comments. Treat
91-
* unquoted keywords that might be user names or database names
92-
* specially, by appending a newline to them.
94+
* Grab one token out of fp. Tokens are strings of non-blank
95+
* characters bounded by blank characters, beginning of line, and
96+
* end of line. Blank means space or tab. Return the token as
97+
* *buf. Leave file positioned at the character immediately after the
98+
* token or EOF, whichever comes first. If no more tokens on line,
99+
* return empty string as *buf and position the file to the beginning
100+
* of the next line or EOF, whichever comes first. Allow spaces in
101+
* quoted strings. Terminate on unquoted commas. Handle
102+
* comments. Treat unquoted keywords that might be user names or
103+
* database names specially, by appending a newline to them.
93104
*/
94-
void
95-
next_token(FILE *fp, char *buf, const int bufsz)
105+
static void
106+
next_token(FILE *fp, char *buf, int bufsz)
96107
{
97108
int c;
98109
char *start_buf = buf;
@@ -101,88 +112,89 @@ next_token(FILE *fp, char *buf, const int bufsz)
101112
bool was_quote = false;
102113
bool saw_quote = false;
103114

115+
Assert(end_buf > start_buf);
116+
104117
/* Move over initial whitespace and commas */
105118
while ((c = getc(fp)) != EOF && (pg_isblank(c) || c == ','))
106119
;
107120

108-
if (c != EOF && c != '\n')
121+
if (c == EOF || c == '\n')
109122
{
110-
/*
111-
* Build a token in buf of next characters up to EOF, EOL,
112-
* unquoted comma, or unquoted whitespace.
113-
*/
114-
while (c != EOF && c != '\n' &&
115-
(!pg_isblank(c) || in_quote == true))
116-
{
117-
/* skip comments to EOL */
118-
if (c == '#' && !in_quote)
119-
{
120-
while ((c = getc(fp)) != EOF && c != '\n')
121-
;
122-
/* If only comment, consume EOL too; return EOL */
123-
if (c != EOF && buf == start_buf)
124-
c = getc(fp);
125-
break;
126-
}
123+
*buf = '\0';
124+
return;
125+
}
127126

128-
if (buf >= end_buf)
129-
{
130-
ereport(LOG,
131-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
132-
errmsg("authentication file token too long, skipping: \"%s\"",
133-
buf)));
134-
/* Discard remainder of line */
135-
while ((c = getc(fp)) != EOF && c != '\n')
136-
;
137-
buf[0] = '\0';
138-
break;
139-
}
127+
/*
128+
* Build a token in buf of next characters up to EOF, EOL,
129+
* unquoted comma, or unquoted whitespace.
130+
*/
131+
while (c != EOF && c != '\n' &&
132+
(!pg_isblank(c) || in_quote == true))
133+
{
134+
/* skip comments to EOL */
135+
if (c == '#' && !in_quote)
136+
{
137+
while ((c = getc(fp)) != EOF && c != '\n')
138+
;
139+
/* If only comment, consume EOL too; return EOL */
140+
if (c != EOF && buf == start_buf)
141+
c = getc(fp);
142+
break;
143+
}
140144

141-
if (c != '"' || (c == '"' && was_quote))
142-
*buf++ = c;
145+
if (buf >= end_buf)
146+
{
147+
ereport(LOG,
148+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
149+
errmsg("authentication file token too long, skipping: \"%s\"",
150+
buf)));
151+
/* Discard remainder of line */
152+
while ((c = getc(fp)) != EOF && c != '\n')
153+
;
154+
buf[0] = '\0';
155+
break;
156+
}
143157

144-
/* We pass back the comma so the caller knows there is more */
145-
if ((pg_isblank(c) || c == ',') && !in_quote)
146-
break;
158+
if (c != '"' || (c == '"' && was_quote))
159+
*buf++ = c;
147160

148-
/* Literal double-quote is two double-quotes */
149-
if (in_quote && c == '"')
150-
was_quote = !was_quote;
151-
else
152-
was_quote = false;
161+
/* We pass back the comma so the caller knows there is more */
162+
if ((pg_isblank(c) || c == ',') && !in_quote)
163+
break;
153164

154-
if (c == '"')
155-
{
156-
in_quote = !in_quote;
157-
saw_quote = true;
158-
}
165+
/* Literal double-quote is two double-quotes */
166+
if (in_quote && c == '"')
167+
was_quote = !was_quote;
168+
else
169+
was_quote = false;
159170

160-
c = getc(fp);
171+
if (c == '"')
172+
{
173+
in_quote = !in_quote;
174+
saw_quote = true;
161175
}
162176

163-
/*
164-
* Put back the char right after the token (critical in case it is
165-
* EOL, since we need to detect end-of-line at next call).
166-
*/
167-
if (c != EOF)
168-
ungetc(c, fp);
177+
c = getc(fp);
169178
}
170179

180+
/*
181+
* Put back the char right after the token (critical in case it is
182+
* EOL, since we need to detect end-of-line at next call).
183+
*/
184+
if (c != EOF)
185+
ungetc(c, fp);
186+
187+
*buf = '\0';
171188

172-
if ( !saw_quote &&
173-
(
174-
strncmp(start_buf,"all",3) == 0 ||
175-
strncmp(start_buf,"sameuser",8) == 0 ||
176-
strncmp(start_buf,"samegroup",9) == 0
177-
)
178-
)
189+
if (!saw_quote &&
190+
(strcmp(start_buf, "all") == 0 ||
191+
strcmp(start_buf, "sameuser") == 0 ||
192+
strcmp(start_buf, "samegroup") == 0))
179193
{
180194
/* append newline to a magical keyword */
181195
*buf++ = '\n';
196+
*buf = '\0';
182197
}
183-
184-
*buf = '\0';
185-
186198
}
187199

188200
/*

src/include/libpq/hba.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Interface to hba.c
55
*
66
*
7-
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.34 2003/11/29 22:41:03 pgsql Exp $
7+
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.35 2004/02/02 16:58:30 neilc Exp $
88
*
99
*-------------------------------------------------------------------------
1010
*/
@@ -17,15 +17,6 @@
1717

1818
#include "nodes/pg_list.h"
1919

20-
#define CONF_FILE "pg_hba.conf"
21-
/* Name of the config file */
22-
23-
#define USERMAP_FILE "pg_ident.conf"
24-
/* Name of the usermap file */
25-
26-
#define IDENT_PORT 113
27-
/* Standard TCP port number for Ident service. Assigned by IANA */
28-
2920
typedef enum UserAuth
3021
{
3122
uaReject,
@@ -43,9 +34,6 @@ typedef enum UserAuth
4334

4435
typedef struct Port hbaPort;
4536

46-
#define MAX_TOKEN 256
47-
48-
extern void next_token(FILE *fp, char *buf, const int bufsz);
4937
extern List **get_user_line(const char *user);
5038
extern void load_hba(void);
5139
extern void load_ident(void);

0 commit comments

Comments
 (0)