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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy