Module Name:    src
Committed By:   kre
Date:           Thu Jul 11 05:41:24 UTC 2024

Modified Files:
        src/lib/libedit: history.c

Log Message:
Don't fchmod(fileno(fp), ...) in history_save_fp().

There are two reasons for this, first, the permissions of the history
file should be able to be set by the user, not forced to 0600 every
time the history file is overwritten (or appended to).

And more importantly, the fp used for fileno(fp) might have come
from fmemopen() or funopen() (etc) - none of which put a file
descriptor in the "fd" field (ie: fileno(fp) == -1).

To compensate for that, when a history file is opened (in history_save())
set the default permissions then - if the file is actually created.
As fopen() cannot do that (it simply uses 0666&~umask) create the
(normal type) of fp using (approximately) fdopen(open(...), ...)
where the open supplies the 0600 default permissions that are
desired here (which might still be restricted even more by the
umask).   Callers using history(...,H_SAVE_FP,...) or
history(...,H_NSAVE_FP,...) now need to look after any permission
setting required themselves (but as the doc says absolutely
nothing about that, one way or the other, what happens in this
area has always been unspecified, and still is)

One "feature" of the fchmod() method is lost here - apart from forcing
the 0600 permissions (which isn't really desirable) that fchmod()
would also have failed if the current (effective) uid is not the owner of
the history file (or root).    If that is required, a test for it could
be added later - the effect would be as it has always been, the file
named must have been writable (or its directory writable if the file
did not exist) the open would occur (potentially truncating the file)
after which the fchmod() would be attempted, possibly failing, and if
so, never writing anything.   Any new uid test would work the same way.

OK christos@


To generate a diff of this commit:
cvs rdiff -u -r1.63 -r1.64 src/lib/libedit/history.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libedit/history.c
diff -u src/lib/libedit/history.c:1.63 src/lib/libedit/history.c:1.64
--- src/lib/libedit/history.c:1.63	Tue Oct  8 19:17:57 2019
+++ src/lib/libedit/history.c	Thu Jul 11 05:41:24 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: history.c,v 1.63 2019/10/08 19:17:57 christos Exp $	*/
+/*	$NetBSD: history.c,v 1.64 2024/07/11 05:41:24 kre Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)history.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: history.c,v 1.63 2019/10/08 19:17:57 christos Exp $");
+__RCSID("$NetBSD: history.c,v 1.64 2024/07/11 05:41:24 kre Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -45,6 +45,7 @@ __RCSID("$NetBSD: history.c,v 1.63 2019/
  * hist.c: TYPE(History) access functions
  */
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -842,8 +843,6 @@ history_save_fp(TYPE(History) *h, size_t
 	static ct_buffer_t conv;
 #endif
 
-	if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
-		goto done;
 	if (ftell(fp) == 0 && fputs(hist_cookie, fp) == EOF)
 		goto done;
 	ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
@@ -891,7 +890,11 @@ history_save(TYPE(History) *h, const cha
     FILE *fp;
     int i;
 
-    if ((fp = fopen(fname, "w")) == NULL)
+    if ((i = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
+		S_IRUSR|S_IWUSR)) == -1)
+	return -1;
+
+    if ((fp = fdopen(i, "w")) == NULL)
 	return -1;
 
     i = history_save_fp(h, (size_t)-1, fp);

Reply via email to