summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2013-02-08 20:36:31 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2013-02-08 20:36:31 (GMT)
commitd91625d1392bfccdc500b151444030a05a639675 (patch)
treeb1c5fcf07e6587e48955b479d807c4b72d103066
parent692fa69934553e34a7166fd919b90309bc4ecb23 (diff)
downloadhdf5-d91625d1392bfccdc500b151444030a05a639675.zip
hdf5-d91625d1392bfccdc500b151444030a05a639675.tar.gz
hdf5-d91625d1392bfccdc500b151444030a05a639675.tar.bz2
[svn-r23238] Description:
Bring changes from Coverity branch to trunk: r20528: Purpose: Fix coverity issue 1372 Description: Rewrite file open secition of H5FD_stdio_open to avoid TOCTUO condition. No longer calls access, and uses a tentative open in "rb" or "rb+" mode to check for existence of the file. r20609: Use HDstrncpy and HDstrncat. --gh r20611: Use HDstrncpy. --gh Tested on: Mac OSX/64 10.8.2 (amazon) w/debug, C++ & FORTRAN (h5committest not required, already tested on branch)
-rw-r--r--src/H5FDstdio.c35
-rw-r--r--src/H5Gname.c2
-rw-r--r--src/H5Gtest.c2
3 files changed, 24 insertions, 15 deletions
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index 43bf6b9..4e484c2 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -365,26 +365,35 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
if (ADDR_OVERFLOW(maxaddr))
H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL)
- /* Attempt to open/create the file */
- if (access(name, F_OK) < 0) {
- if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) {
+ /* Tentatively open file in read-only mode, to check for existence */
+ if(flags & H5F_ACC_RDWR)
+ f = fopen(name, "rb+");
+ else
+ f = fopen(name, "rb");
+
+ if(!f) {
+ /* File doesn't exist */
+ if(flags & H5F_ACC_CREAT) {
+ assert(flags & H5F_ACC_RDWR);
f = fopen(name, "wb+");
write_access = 1; /* Note the write access */
}
else
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL)
- } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) {
+ } else if(flags & H5F_ACC_EXCL) {
+ /* File exists, but EXCL is passed. Fail. */
+ assert(flags & H5F_ACC_CREAT);
+ fclose(f);
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FILEEXISTS, "file exists but CREAT and EXCL were specified", NULL)
- } else if (flags & H5F_ACC_RDWR) {
- if (flags & H5F_ACC_TRUNC)
- f = fopen(name, "wb+");
- else
- f = fopen(name, "rb+");
+ } else if(flags & H5F_ACC_RDWR) {
+ if(flags & H5F_ACC_TRUNC)
+ f = freopen(name, "wb+", f);
write_access = 1; /* Note the write access */
- } else {
- f = fopen(name, "rb");
- }
- if (!f)
+ } /* end if */
+ /* Note there is no need to reopen if neither TRUNC nor EXCL are specified,
+ * as the tentative open will work */
+
+ if(!f)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "fopen failed", NULL)
/* Build the return value */
diff --git a/src/H5Gname.c b/src/H5Gname.c
index 6619c86..72da498 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -764,7 +764,7 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
/* Create the new path */
if(path_prefix2_len > 0) {
- HDstrncpy(new_path, path_prefix2, path_prefix2_len);
+ HDstrncpy(new_path, path_prefix2, path_prefix2_len + 1);
HDstrncpy(new_path + path_prefix2_len, dst_suffix, dst_suffix_len + 1);
} /* end if */
else
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
index b39b4ff..2b5d32a 100644
--- a/src/H5Gtest.c
+++ b/src/H5Gtest.c
@@ -568,7 +568,7 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign
/* Set the user path, if given */
if(user_path)
- HDstrcpy(user_path, H5RS_get_str(obj_path->user_path_r));
+ HDstrncpy(user_path, H5RS_get_str(obj_path->user_path_r), (size_t)(len + 1));
/* Set the length of the path */
*user_path_len = (size_t)len;