Skip to content

Commit 897068e

Browse files
tjarlamaJeffroMF
authored andcommitted
fs: clobber req->path on uv_fs_mkstemp() error
Contents of template variable passed for posix call mkstemp on error code EINVAL is unknown. On AIX platform, template will get clobbered on EINVAL and any attempt to read template might result in error. In libuv, req->path is passed directly to the mkstemp call and behavior of this string on error is platform dependent. To avoid portability issues, it's better to have a common behavior on all platform. For both unix and windows platform libuv will rewrite path with an empty string on all error cases. Fixes: libuv#2913 Refs: nodejs/node#33549 Refs: libuv#2933 PR-URL: libuv#2938 Reviewed-By: Jameson Nash <vtjnash@gmail.com>
1 parent 1de2f0d commit 897068e

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

src/unix/fs.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
306306
if (path_length < pattern_size ||
307307
strcmp(path + path_length - pattern_size, pattern)) {
308308
errno = EINVAL;
309-
return -1;
309+
r = -1;
310+
goto clobber;
310311
}
311312

312313
uv_once(&once, uv__mkostemp_initonce);
@@ -321,7 +322,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
321322
/* If mkostemp() returns EINVAL, it means the kernel doesn't
322323
support O_CLOEXEC, so we just fallback to mkstemp() below. */
323324
if (errno != EINVAL)
324-
return r;
325+
goto clobber;
325326

326327
/* We set the static variable so that next calls don't even
327328
try to use mkostemp. */
@@ -347,6 +348,9 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
347348
if (req->cb != NULL)
348349
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
349350

351+
clobber:
352+
if (r < 0)
353+
path[0] = '\0';
350354
return r;
351355
}
352356

src/win/fs.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,19 +1241,21 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
12411241
unsigned int tries, i;
12421242
size_t len;
12431243
uint64_t v;
1244-
1244+
char* path;
1245+
1246+
path = req->path;
12451247
len = wcslen(req->file.pathw);
12461248
ep = req->file.pathw + len;
12471249
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
12481250
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
1249-
return;
1251+
goto clobber;
12501252
}
12511253

12521254
tries = TMP_MAX;
12531255
do {
12541256
if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) {
12551257
SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE);
1256-
break;
1258+
goto clobber;
12571259
}
12581260

12591261
cp = ep - num_x;
@@ -1264,16 +1266,17 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
12641266

12651267
if (func(req)) {
12661268
if (req->result >= 0) {
1267-
len = strlen(req->path);
1268-
wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
1269+
len = strlen(path);
1270+
wcstombs(path + len - num_x, ep - num_x, num_x);
12691271
}
1270-
break;
1272+
return;
12711273
}
12721274
} while (--tries);
12731275

1274-
if (tries == 0) {
1275-
SET_REQ_WIN32_ERROR(req, GetLastError());
1276-
}
1276+
SET_REQ_WIN32_ERROR(req, GetLastError());
1277+
1278+
clobber:
1279+
path[0] = '\0';
12771280
}
12781281

12791282

test/test-fs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,10 @@ TEST_IMPL(fs_mkstemp) {
12901290
ASSERT(strcmp(mkstemp_req1.path, mkstemp_req2.path) != 0);
12911291

12921292
/* invalid template returns EINVAL */
1293-
ASSERT(uv_fs_mkstemp(NULL, &mkstemp_req3, "test_file", NULL) == UV_EINVAL);
1293+
ASSERT_EQ(UV_EINVAL, uv_fs_mkstemp(NULL, &mkstemp_req3, "test_file", NULL));
1294+
1295+
/* Make sure that path is empty string */
1296+
ASSERT_EQ(0, strlen(mkstemp_req3.path));
12941297

12951298
/* We can write to the opened file */
12961299
iov = uv_buf_init(test_buf, sizeof(test_buf));

0 commit comments

Comments
 (0)