Skip to content

Commit b4fcb99

Browse files
committed
Remove use of getcwd for resolving paths
Call fopen with name rather than resolved path to allow use of specialized symbolic links for pipes and sockets. E.g., /dev/stdin. Fixes NLnetLabs/nsd#380.
1 parent c823c63 commit b4fcb99

File tree

1 file changed

+13
-78
lines changed

1 file changed

+13
-78
lines changed

src/zone.c

+13-78
Original file line numberDiff line numberDiff line change
@@ -115,89 +115,28 @@ diagnostic_push()
115115
msvc_diagnostic_ignored(4996)
116116

117117
#if _WIN32
118-
nonnull_all
119-
static bool is_separator(int c)
120-
{
121-
return c == '\\' || c == '/';
122-
}
123-
124-
nonnull_all
125-
static bool is_rooted(const char *s)
126-
{
127-
if ((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= 'a' && s[0] <= 'z'))
128-
return s[1] == ':';
129-
return false;
130-
}
131-
132-
nonnull_all
133-
static bool is_relative(const char *s)
134-
{
135-
// rooted paths can be relative, e.g. C:foo
136-
if (is_rooted(s))
137-
return !is_separator((unsigned char)s[2]);
138-
if (is_separator((unsigned char)s[0]))
139-
return !(s[1] == '?' || is_separator((unsigned char)s[1]));
140-
return false;
141-
}
142-
143118
// The Win32 API offers PathIsRelative, but it requires linking with shlwapi.
144119
// Rewriting a relative path is not too complex, unlike correct conversion of
145120
// Windows paths in general (https://googleprojectzero.blogspot.com/2016/02/).
146121
// Rooted paths, relative or not, unc and extended paths are never resolved
147122
// relative to the includer.
148-
nonnull((2,3))
149-
static int32_t resolve_path(
150-
const char *includer, const char *include, char **path)
123+
nonnull_all
124+
static int32_t resolve_path(const char *include, char **path)
151125
{
152-
// support relative non-rooted paths only
153-
if (*includer && is_relative(include) && !is_rooted(include)) {
154-
assert(!is_relative(includer));
155-
char buffer[16];
156-
int length = snprintf(
157-
buffer, sizeof(buffer), "%s/%s", includer, include);
158-
if (length < 0)
159-
return ZONE_OUT_OF_MEMORY;
160-
char *absolute;
161-
if (!(absolute = malloc(length + 1)))
162-
return ZONE_OUT_OF_MEMORY;
163-
(void)snprintf(
164-
absolute, (size_t)length + 1, "%s/%s", includer, include);
165-
*path = _fullpath(NULL, absolute, 0);
166-
free(absolute);
167-
} else {
168-
*path = _fullpath(NULL, include, 0);
169-
}
170-
171-
if (*path)
126+
if ((*path = _fullpath(NULL, include, 0)))
172127
return 0;
173128
return (errno == ENOMEM) ? ZONE_OUT_OF_MEMORY : ZONE_NOT_A_FILE;
174129
}
175130
#else
176131
nonnull_all
177-
static int32_t resolve_path(
178-
const char *includer, const char *include, char **path)
132+
static int32_t resolve_path(const char *include, char **path)
179133
{
180134
char *resolved;
181135
char buffer[PATH_MAX + 1];
182136

183-
if (*includer && *include != '/') {
184-
assert(*includer == '/');
185-
int length = snprintf(
186-
buffer, sizeof(buffer), "%s/%s", includer, include);
187-
if (length < 0)
188-
return ZONE_OUT_OF_MEMORY;
189-
char *absolute;
190-
if (!(absolute = malloc((size_t)length + 1)))
191-
return ZONE_OUT_OF_MEMORY;
192-
(void)snprintf(
193-
absolute, (size_t)length + 1, "%s/%s", includer, include);
194-
resolved = realpath(absolute, buffer);
195-
free(absolute);
196-
} else {
197-
resolved = realpath(include, buffer);
198-
}
137+
resolved = realpath(include, buffer);
199138

200-
if (!resolved)
139+
if (!(resolved = realpath(include, buffer)))
201140
return (errno == ENOMEM) ? ZONE_OUT_OF_MEMORY : ZONE_NOT_A_FILE;
202141
assert(resolved == buffer);
203142
size_t length = strlen(buffer);
@@ -318,24 +257,20 @@ static int32_t open_file(
318257
file->path[0] = '-';
319258
file->path[1] = '\0';
320259
} else {
321-
/* The file is resolved relative to the working directory. */
322-
char workdir[PATH_MAX];
323-
#if _WIN32
324-
if(!_getcwd(workdir, sizeof(workdir)))
325-
return (void)close_file(parser, file), ZONE_NOT_A_FILE;
326-
#else
327-
if(!getcwd(workdir, sizeof(workdir)))
328-
return (void)close_file(parser, file), ZONE_NOT_A_FILE;
329-
#endif
330-
if ((code = resolve_path(workdir, file->name, &file->path)))
260+
// The file is resolved relative to the working directory. The absolute
261+
// path is used to protect against recusive includes. Not for opening the
262+
// file as file descriptors for pipes and sockets the entries will be
263+
// symoblic links whose content is the file type with the inode.
264+
// See NLnetLabs/nsd#380.
265+
if ((code = resolve_path(file->name, &file->path)))
331266
return (void)close_file(parser, file), code;
332267
}
333268

334269
if(strcmp(file->path, "-") == 0) {
335270
file->handle = stdin;
336271
return 0;
337272
} else {
338-
if ((file->handle = fopen(file->path, "rb")))
273+
if ((file->handle = fopen(file->name, "rb")))
339274
return 0;
340275
}
341276

0 commit comments

Comments
 (0)