Page MenuHomeFreeBSD

D51514.diff
No OneTemporary

D51514.diff

diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
--- a/lib/libc/db/hash/hash.c
+++ b/lib/libc/db/hash/hash.c
@@ -99,11 +99,6 @@
DB *dbp;
int bpages, hdrsize, new_table, nsegs, save_errno;
- if ((flags & O_ACCMODE) == O_WRONLY) {
- errno = EINVAL;
- return (NULL);
- }
-
if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
return (NULL);
hashp->fp = -1;
@@ -115,6 +110,10 @@
* we can check accesses.
*/
hashp->flags = flags;
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ flags &= ~O_WRONLY;
+ flags |= O_RDWR;
+ }
if (file) {
if ((hashp->fp = _open(file, flags | O_CLOEXEC, mode)) == -1)
@@ -180,7 +179,7 @@
__buf_init(hashp, DEF_BUFSIZE);
hashp->new_file = new_table;
- hashp->save_file = file && (hashp->flags & O_RDWR);
+ hashp->save_file = file && (flags & O_RDWR);
hashp->cbucket = -1;
if (!(dbp = (DB *)malloc(sizeof(DB)))) {
save_errno = errno;
@@ -524,6 +523,10 @@
hashp->error = errno = EINVAL;
return (ERROR);
}
+ if ((hashp->flags & O_ACCMODE) == O_WRONLY) {
+ hashp->error = errno = EPERM;
+ return (ERROR);
+ }
return (hash_access(hashp, HASH_GET, (DBT *)key, data));
}
diff --git a/lib/libc/db/man/dbm.3 b/lib/libc/db/man/dbm.3
--- a/lib/libc/db/man/dbm.3
+++ b/lib/libc/db/man/dbm.3
@@ -13,7 +13,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 2, 2022
+.Dd July 25, 2025
.Dt DBM 3
.Os
.Sh NAME
@@ -99,9 +99,6 @@
.Li 0660
is a typical value for
.Fa mode .
-.Dv O_WRONLY
-is not allowed in
-.Fa flags .
The pointer returned by
.Fn dbm_open
identifies the database and is the
diff --git a/lib/libc/db/man/dbopen.3 b/lib/libc/db/man/dbopen.3
--- a/lib/libc/db/man/dbopen.3
+++ b/lib/libc/db/man/dbopen.3
@@ -76,13 +76,10 @@
.Xr open 2
routine, however, only the
.Dv O_CREAT , O_EXCL , O_EXLOCK , O_NOFOLLOW , O_NONBLOCK ,
-.Dv O_RDONLY , O_RDWR , O_SHLOCK , O_SYNC
+.Dv O_RDONLY , O_RDWR , O_SHLOCK , O_SYNC, O_WRONLY,
and
.Dv O_TRUNC
flags are meaningful.
-(Note, opening a database file
-.Dv O_WRONLY
-is not possible.)
.\"Three additional options may be specified by
.\".Em or Ns 'ing
.\"them into the
diff --git a/lib/libc/tests/db/Makefile b/lib/libc/tests/db/Makefile
--- a/lib/libc/tests/db/Makefile
+++ b/lib/libc/tests/db/Makefile
@@ -8,6 +8,7 @@
${PACKAGE}FILES+= README
ATF_TESTS_C+= dbm_open_test
+ATF_TESTS_C+= dbm_perm_test
NETBSD_ATF_TESTS_C+= db_hash_seq_test
NETBSD_ATF_TESTS_SH+= db_test
diff --git a/lib/libc/tests/db/dbm_open_test.c b/lib/libc/tests/db/dbm_open_test.c
--- a/lib/libc/tests/db/dbm_open_test.c
+++ b/lib/libc/tests/db/dbm_open_test.c
@@ -4,14 +4,15 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
-#include <sys/mman.h>
-
#include <fcntl.h>
#include <ndbm.h>
#include <stdio.h>
#include <atf-c.h>
+static const char *path = "tmp";
+static const char *dbname = "tmp.db";
+
ATF_TC(dbm_open_missing_test);
ATF_TC_HEAD(dbm_open_missing_test, tc)
{
@@ -21,23 +22,31 @@
ATF_TC_BODY(dbm_open_missing_test, tc)
{
- const char *path = "tmp";
- const char *dbname = "tmp.db";
/*
* POSIX.1 specifies that a missing database file should
* always get created if O_CREAT is present, except when
* O_EXCL is specified as well.
*/
- ATF_CHECK(dbm_open(path, O_RDONLY, _PROT_ALL) == NULL);
+ ATF_CHECK(dbm_open(path, O_RDONLY, 0755) == NULL);
+ ATF_REQUIRE(!atf_utils_file_exists(dbname));
+ ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT, 0755) != NULL);
+ ATF_REQUIRE(atf_utils_file_exists(dbname));
+ ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT | O_EXCL, 0755) == NULL);
+}
+
+ATF_TC_WITHOUT_HEAD(dbm_open_wronly_test);
+ATF_TC_BODY(dbm_open_wronly_test, tc)
+{
+ ATF_CHECK(dbm_open(path, O_WRONLY, 0755) == NULL);
ATF_REQUIRE(!atf_utils_file_exists(dbname));
- ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT, _PROT_ALL) != NULL);
+ ATF_CHECK(dbm_open(path, O_WRONLY | O_CREAT, 0755) != NULL);
ATF_REQUIRE(atf_utils_file_exists(dbname));
- ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT | O_EXCL, _PROT_ALL) == NULL);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, dbm_open_missing_test);
+ ATF_TP_ADD_TC(tp, dbm_open_wronly_test);
return (atf_no_error());
}
diff --git a/lib/libc/tests/db/dbm_perm_test.c b/lib/libc/tests/db/dbm_perm_test.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/db/dbm_perm_test.c
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2025 Klara, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <ndbm.h>
+#include <stdio.h>
+
+#include <atf-c.h>
+
+static const char *path = "tmp";
+static const char *dbname = "tmp.db";
+
+static void
+create_db(void)
+{
+ DB *db;
+ datum data, key;
+
+ data.dptr = "bar";
+ data.dsize = strlen("bar");
+ key.dptr = "foo";
+ key.dsize = strlen("foo");
+
+ db = dbm_open(path, O_RDWR | O_CREAT, 0755);
+ ATF_CHECK(db != NULL);
+ ATF_REQUIRE(atf_utils_file_exists(dbname));
+ ATF_REQUIRE(dbm_store(db, key, data, DBM_INSERT) != -1);
+ dbm_close(db);
+}
+
+ATF_TC_WITHOUT_HEAD(dbm_rdonly_test);
+ATF_TC_BODY(dbm_rdonly_test, tc)
+{
+ DB *db;
+ datum data, key;
+
+ bzero(&data, sizeof(data));
+ key.dptr = "foo";
+ key.dsize = strlen("foo");
+ create_db();
+
+ db = dbm_open(path, O_RDONLY, 0755);
+ data = dbm_fetch(db, key);
+ ATF_REQUIRE(data.dptr != NULL);
+ ATF_REQUIRE(strncmp((const char*)data.dptr, "bar", data.dsize) == 0);
+ ATF_REQUIRE(dbm_store(db, key, data, DBM_REPLACE) == -1);
+ ATF_REQUIRE(errno == EPERM);
+}
+
+ATF_TC_WITHOUT_HEAD(dbm_wronly_test);
+ATF_TC_BODY(dbm_wronly_test, tc)
+{
+ DB *db;
+ datum data, key;
+
+ key.dptr = "foo";
+ key.dsize = strlen("foo");
+ data.dptr = "baz";
+ data.dsize = strlen("baz");
+ create_db();
+
+ db = dbm_open(path, O_WRONLY, 0755);
+ data = dbm_fetch(db, key);
+ ATF_REQUIRE(data.dptr == NULL);
+ ATF_REQUIRE(errno == EPERM);
+ ATF_REQUIRE(dbm_store(db, key, data, DBM_REPLACE) != -1);
+}
+
+ATF_TC_WITHOUT_HEAD(dbm_rdwr_test);
+ATF_TC_BODY(dbm_rdwr_test, tc)
+{
+ DB *db;
+ datum data, key;
+
+ key.dptr = "foo";
+ key.dsize = strlen("foo");
+ create_db();
+
+ db = dbm_open(path, O_RDWR, 0755);
+ data = dbm_fetch(db, key);
+ ATF_REQUIRE(data.dptr != NULL);
+ data.dptr = "baz";
+ data.dsize = strlen("baz");
+ ATF_REQUIRE(dbm_store(db, key, data, DBM_REPLACE) != -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, dbm_rdonly_test);
+ ATF_TP_ADD_TC(tp, dbm_wronly_test);
+ ATF_TP_ADD_TC(tp, dbm_rdwr_test);
+
+ return (atf_no_error());
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 17, 2:31 AM (15 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31634595
Default Alt Text
D51514.diff (6 KB)

Event Timeline