>Number: 60648
>Category: pkg
>Synopsis: editors/emacs20: LP64 Lisp_Object truncation breaks Japanese input, plus two unbackported CVEs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Aug 26 17:05:00 +0000 2026
>Originator: Showta Ishizaki
>Release: NetBSD 11.0, pkgsrc CVS as of 2026-08-27
>Organization:
>Environment:
System: NetBSD 11.0 amd64
Architecture: x86_64
Machine: amd64
>Description:
On any LP64 platform, emacs20 cannot set up a CJK language
environment:
$ emacs -batch -q --eval '(set-language-environment "Japanese")'
Wrong type argument: stringp, 8510432
Chinese-GB and Korean fail the same way. Greek, Latin-1 and
English are fine. Because it happens in set-language-environment,
an init file that does
(set-language-environment "Japanese")
(load-library "anthy")
dies before the input method is ever reached, so emacs20 is
unusable for Japanese input on amd64. On i386 none of this
happens.
The value printed is not really an integer. Under gdb the object
handed to CHECK_STRING is 0x81dbb8, and at that address there is a
perfectly good struct Lisp_String:
(gdb) x/6gx $rsi
0x81dbb8: 0x0000000000000051 0xffffffffffffffff
0x81dbc8: 0x0000000000000000 0x6d6f682f7273752f
(gdb) x/s $rsi+24
0x81dbd0: "/usr/home/techne/zakinko/w/..."
size 0x51, size_byte -1, and the expanded file name in the data
field. What is missing is the type tag. A Lisp_String on this
build should be (3 << 60) | address; the value has the address
only, so XTYPE reads it as Lisp_Int.
The backtrace says where:
#0 wrong_type_argument ()
#1 Ffind_file_name_handler ()
#2 openp ()
#3 Fload ()
and the disassembly says why:
0x4b36f3 <openp+1176>: call <code_convert_string_norecord>
0x4b36f8 <openp+1181>: movslq %eax,%r8
The return value is being sign-extended from 32 bits.
code_convert_string_norecord returns a Lisp_Object, but nothing
declares it. It is only ever reached through the ENCODE_FILE and
DECODE_FILE macros in src/coding.h, and coding.h declares
code_convert_region, decode_coding, encode_coding,
setup_coding_system and the rest -- but not this one. So every
caller compiles it as an implicit int, and on LP64 the top 32 bits,
tag included, are thrown away.
Six files use those macros: callproc.c, dired.c, fileio.c,
filelock.c, lread.c and process.c. Most of them survive by luck.
They pass the result straight to XSTRING, and XPNTR masks the tag
off again, so a truncated-but-positive pointer still yields the
right address. openp is the one that does not: it passes the value
to Ffind_file_name_handler, whose CHECK_STRING looks at the type.
openp does not use ENCODE_FILE in stock Emacs 20.7. It gets it
from emacs-20.7-mule-4.1b.patch, which this package applies:
filename = ENCODE_FILE (filename);
The effect is broad. Once Vdefault_file_name_coding_system is
non-nil, every relative load fails -- (load "subr") included:
$ emacs -batch -q --eval '(progn
(setq default-file-name-coding-system (quote japanese-iso-8bit))
(load "subr"))'
Wrong type argument: stringp, 8510424
An absolute path works, because openp only calls
Ffind_file_name_handler when the name is not already absolute.
set-language-environment sets that variable through
prefer-coding-system, which is why the failure follows the language
rather than the coding system: "Japanese", "Chinese-GB" and
"Korean" have a `features' entry and load one more file, and that
load is the one that dies. "Greek" and "Latin-1" load nothing
further and come through unharmed.
src/lisp.h has the same omission four more times. These are also
Lisp_Object-returning functions called with no declaration in
scope:
Fcurrent_message keyboard.c:2360
Fcurrent_time frame.c:1476, window.c:1968
Fset_buffer_multibyte coding.c:4992, buffer.c:3981
Fwindow_end xdisp.c:2259
Two of them matter. keyboard.c:2360 is
Vinput_method_previous_message = echo_area_message
= Fcurrent_message ();
which sits in read_char and is reached whenever
input-method-function is set -- that is, exactly when a Japanese
input method is in use. window.c:1968 stores a truncated list into
the buffer's display_time. The other two survive today: one caller
discards the result and the other feeds it to XINT, which masks the
tag off. All four are the same mistake and all four are declared
here.
The fix is not invented. Emacs 21 declares all five, and these are
its lines, in its places:
src/ChangeLog
2000-06-05 Dave Love <[email protected]>
* coding.h: Declare code_convert_string_norecord.
Emacs 20.7 was released on 2000-06-13, eight days later, from a
branch that never got it. lisp.h's section layout is close enough
between 20.7 and 21.1 that the four EXFUN lines go in the same
places as well.
Unrelated to the LP64 bug above, this package also carries two
CVEs that were fixed upstream but never reached the emacs-20
branch (the oldest branch on the mirror is emacs-23), plus a
gets() cleanup.
CVE-2022-45939 / CVE-2022-48337 -- etags/ctags paste file names
into shell commands run through system(3) without quoting. Both
call sites are live in 20.7: the -u update loop walks
argbuffer[] by current_arg, and "sort %s -o %s" over the -o
output file is reached directly.
ctags -u -o 'tags;touch /tmp/pwned' file.c
ran the injected command before the fix and does nothing after
it; a normal "-o out.tags" still works. (20.7's etags has no
decompressor, so it lacks the third, popen, site that later
versions have.) Backport of upstream 01a4035c8 "Fix etags local
command injection vulnerability" (Bug#59817) and 8a098f651 "Fix
quoting of file names in 'ctags'"; the upstream
escape_shell_arg_string() is brought to the old K&R source as
shell_quote().
CVE-2017-1000383 -- copy-file creates the destination with
creat(...,0666) and only chmods it afterwards, so a copy of a
private file is briefly world-readable and a backup inherits the
source's setuid/setgid bits. A 04755 source produced a 04755
backup before the fix and a 0755 one after. Modern Emacs closes
this with with-file-modes ?\700 in backup-buffer-copy (files.el)
and O_CREAT|O_EXCL plus ~06000 in Fcopy_file; this does the same
at the C level: create 0600 and mask the chmod with 01777.
patch-src_xrdb.c replaces gets() with fgets() in the [TESTRM]
test driver, backporting upstream e90a457c46ca. gets() is not
compiled into the shipped binary (no gets symbol in it), so this
changes nothing that runs; it is here to match upstream and to
keep the source compiling with newer toolchains.
>How-To-Repeat:
On amd64 (or any other LP64 platform):
cd /usr/pkgsrc/editors/emacs20
make install
emacs -batch -q --eval '(set-language-environment "Japanese")'
Wrong type argument: stringp, 8510432
Or, more directly:
emacs -batch -q --eval '(progn
(setq default-file-name-coding-system (quote japanese-iso-8bit))
(load "subr"))'
Both succeed on i386.
For the etags injection, on any platform:
printf 'int main(void){return 0;}\n' > file.c
ctags -u -o 'tags;touch /tmp/pwned' file.c
test -f /tmp/pwned && echo vulnerable
For copy-file, with backup-by-copying:
printf secret > src; chmod 4755 src; umask 077
emacs -batch -q --eval '(copy-file "src" "dst" t)'
ls -l dst # setuid, world-readable backup before the fix
>Fix:
Seven files. The LP64 fix is two patches: patch-src_coding.h is
new and declares code_convert_string_norecord; patch-bj gains four
EXFUN lines, five lines of declaration in total. The three
CVE/cleanup patches are new: patch-CVE-2022-45939,
patch-CVE-2017-1000383 and patch-src_xrdb.c. PKGREVISION goes
to 27.
Built and run on NetBSD 11.0/amd64. With the patch,
emacs20-20.7nb27 sets up all six language environments that were
tried:
without the patch with the patch
Japanese Wrong type argument ok
Chinese-GB Wrong type argument ok
Korean Wrong type argument ok
Greek ok ok
Latin-1 ok ok
English ok ok
and inputmethod/anthy-elisp then converts: driving anthy.el from
batch, "nihongo" becomes 日本語 and the buffer written out in
EUC-JP contains it. Without the patch the same script dies in
set-language-environment.
With the CVE patches the two exploits above are closed and
ordinary etags and copy-file use is unchanged.
On i386 the patch changes nothing, and that is worth showing
rather than asserting. ILP32 makes int and Lisp_Object the same
width, so the value never leaves %eax:
i386 mov %eax,-0x10c(%ebp)
amd64 movslq %eax,%r8
Building emacs20-20.7nb27 on NetBSD 10.1/i386 and comparing it
with the official emacs20-20.7nb26 binary package, the generated
code is identical at every site the patch touches:
openp 264 instructions
Ffind_file_name_handler 91
read_char 1862
Fset_window_buffer 151
Fset_buffer_multibyte 279
The unpatched i386 package also sets up all six language
environments, so the bug simply does not exist there.
Index: editors/emacs20/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/editors/emacs20/Makefile,v
retrieving revision 1.67
diff -u -r1.67 Makefile
--- editors/emacs20/Makefile
+++ editors/emacs20/Makefile
@@ -2,7 +2,7 @@
DISTNAME= emacs-20.7
PKGNAME= ${DISTNAME:S/emacs/emacs20/}
-PKGREVISION= 26
+PKGREVISION= 27
CATEGORIES= editors
MASTER_SITES= http://ftp.gnu.org/pub/old-gnu/emacs/
MASTER_SITES+= ftp://ftp.gnu.org/pub/old-gnu/emacs
Index: editors/emacs20/distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/editors/emacs20/distinfo,v
retrieving revision 1.42
diff -u -r1.42 distinfo
--- editors/emacs20/distinfo
+++ editors/emacs20/distinfo
@@ -15,6 +15,8 @@
BLAKE2s (emacs20-xim-20000713.diff) = 22ddc9c54b5c3535bf9788af7c00dd3eea65fcbb2360aeed54feb5d800672b3c
SHA512 (emacs20-xim-20000713.diff) = d6d3fb483db830ddcf07f6325901fb7faca1e112129f27036328eb4a6a53851a53318a31830a751525b9e0898256c6c9bfe5c3c333401d44a6dcbad44ba3c7a8
Size (emacs20-xim-20000713.diff) = 21296 bytes
+SHA1 (patch-CVE-2017-1000383) = 943dfbef56b7347ae25a0cc59b15ac2849d3961e
+SHA1 (patch-CVE-2022-45939) = f9850749a0414e1d88902257e5ca46e40a105a50
SHA1 (patch-aa) = 3b3fd76c058a0a46e0458338ce4c2327a238fb3d
SHA1 (patch-ab) = 16c236c232649cc89ed89131a793e201bccef5f0
SHA1 (patch-ac) = abf5971279a8d875504be4c17b8d36cb8cc24885
@@ -40,7 +42,7 @@
SHA1 (patch-bg) = b98608214ea7c1c48905029728ddd7424bc12391
SHA1 (patch-bh) = f59b14cc43d5977a5d80d5d1ab4e246df394d86a
SHA1 (patch-bi) = c0e237bd46de0f9ef137997e59231f119d5f791e
-SHA1 (patch-bj) = 6dba88723ee632b67fcf6a2dd2918e69034837e2
+SHA1 (patch-bj) = 30dfffe2fa4a66bc01919f332d5c2c86979e69d3
SHA1 (patch-bl) = f2cd03713d7cdb6cb41119569031249d7d708b13
SHA1 (patch-bm) = 2f00f63120a90477c6f5c63ac6ca23fc508b9e54
SHA1 (patch-bp) = 7b9ad94ac9d09fbb2173fdd3efd04faa0a668a91
@@ -54,4 +56,6 @@
SHA1 (patch-ce) = df4d2a5639a72d2c719662496f17db35686f4ac2
SHA1 (patch-cf) = 1b5b83eb02872414fd7ca29c344c0560feaf1b7e
SHA1 (patch-cg) = b2bd4cbff399922e44ad54459255ffb1d61e1bd4
+SHA1 (patch-src_coding.h) = 25e759b5484fdf21076807fb47ebfacb6906d97c
SHA1 (patch-src_m_aarch64.h) = 861757ce6568303ea55cb9c9f290abc6100d3dc2
+SHA1 (patch-src_xrdb.c) = 34b87fca7d84f286a283a6defea62954eafca2d0
Index: editors/emacs20/patches/patch-bj
===================================================================
RCS file: /cvsroot/pkgsrc/editors/emacs20/patches/patch-bj,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 patch-bj
--- editors/emacs20/patches/patch-bj
+++ editors/emacs20/patches/patch-bj
@@ -1,5 +1,24 @@
$NetBSD: patch-bj,v 1.1.1.1 2003/04/11 00:31:45 uebayasi Exp $
+Make Lisp_Object 64 bits wide on LP64, and declare four Lisp functions
+that return one.
+
+Nothing declares them, so the implicit int return truncates the value to
+32 bits and the type tag (bits 60-62) goes with it. Two of the four are
+reached in practice:
+
+ keyboard.c:2360 Vinput_method_previous_message = echo_area_message
+ = Fcurrent_message ();
+ window.c:1968 XBUFFER (buffer)->display_time = Fcurrent_time ();
+
+The first is on the input method path, taken whenever
+input-method-function is set, which is what Japanese input runs into.
+Fset_buffer_multibyte and Fwindow_end survive today, one because its
+caller discards the result and the other because XINT masks the tag off
+again, but they are the same mistake.
+
+Emacs 21 declares all four; these are its lines, in its places.
+
--- ./src/lisp.h.orig Sun Jan 3 08:31:23 1999
+++ ./src/lisp.h Tue Sep 26 09:48:10 2000
@@ -123,25 +123,25 @@
@@ -102,3 +121,35 @@
extern Lisp_Object make_number ();
+@@ -1997,6 +1997,7 @@
+ extern void syms_of_eval P_ ((void));
+
+ /* Defined in editfns.c */
++EXFUN (Fcurrent_message, 0);
+ EXFUN (Fgoto_char, 1);
+ EXFUN (Fpoint_min_marker, 0);
+ EXFUN (Fpoint_max_marker, 0);
+@@ -2035,6 +2036,7 @@
+ EXFUN (Fwiden, 0);
+ EXFUN (Fuser_login_name, 1);
+ EXFUN (Fsystem_name, 0);
++EXFUN (Fcurrent_time, 0);
+ extern int clip_to_bounds P_ ((int, int, int));
+ extern Lisp_Object make_buffer_string P_ ((int, int, int));
+ extern Lisp_Object make_buffer_string_both P_ ((int, int, int, int, int));
+@@ -2043,6 +2045,7 @@
+
+ /* defined in buffer.c */
+ extern void nsberror P_ ((Lisp_Object));
++EXFUN (Fset_buffer_multibyte, 1);
+ EXFUN (Foverlay_start, 1);
+ EXFUN (Foverlay_end, 1);
+ extern void adjust_overlays_for_insert P_ ((int, int));
+@@ -2256,6 +2259,7 @@
+
+ /* defined in window.c */
+ extern Lisp_Object Qwindowp, Qwindow_live_p;
++EXFUN (Fwindow_end, 2);
+ EXFUN (Fselected_window, 0);
+ EXFUN (Fnext_window, 3);
+ EXFUN (Fdelete_window, 1);
Index: editors/emacs20/patches/patch-src_coding.h
===================================================================
RCS file: editors/emacs20/patches/patch-src_coding.h
diff -N editors/emacs20/patches/patch-src_coding.h
--- /dev/null
+++ editors/emacs20/patches/patch-src_coding.h
@@ -0,0 +1,37 @@
+$NetBSD$
+
+Declare code_convert_string_norecord, which returns a Lisp_Object.
+
+ENCODE_FILE and DECODE_FILE call it and nothing declares it, so on LP64
+the implicit int return truncates the 64-bit Lisp_Object to 32 bits and
+the type tag (bits 60-62) is lost. Most callers hand the result straight
+to XSTRING, which masks the tag off anyway, so they survive; the one in
+openp does not.
+
+openp gets ENCODE_FILE from the Mule 4.1b distribution patch:
+
+ filename = ENCODE_FILE (filename);
+
+and then passes filename to Ffind_file_name_handler, whose CHECK_STRING
+sees an untagged pointer as an integer:
+
+ Wrong type argument: stringp, 8510432
+
+So every relative load fails as soon as a non-nil file name coding system
+is in force. set-language-environment sets one through
+prefer-coding-system, which is why "Japanese", "Chinese-GB" and "Korean"
+die while "Greek" and "Latin-1", which pull in no extra features, do not.
+
+Emacs 21 declares it; this is its line, in its place.
+
+--- src/coding.h.orig 2026-08-26 04:33:33.562475397 +0000
++++ src/coding.h
+@@ -563,6 +563,8 @@
+ extern char *get_conversion_buffer P_ ((int));
+ extern int setup_coding_system P_ ((Lisp_Object, struct coding_system *));
+ extern void setup_raw_text_coding_system P_ ((struct coding_system *));
++extern Lisp_Object code_convert_string_norecord P_ ((Lisp_Object, Lisp_Object,
++ int));
+ extern Lisp_Object Qcoding_system, Qeol_type, Qcoding_category_index;
+ extern Lisp_Object Qraw_text, Qemacs_mule;
+ extern Lisp_Object Qbuffer_file_coding_system;
Index: editors/emacs20/patches/patch-CVE-2022-45939
===================================================================
RCS file: editors/emacs20/patches/patch-CVE-2022-45939
diff -N editors/emacs20/patches/patch-CVE-2022-45939
--- /dev/null
+++ editors/emacs20/patches/patch-CVE-2022-45939
+$NetBSD$
+
+CVE-2022-45939 and CVE-2022-48337: etags/ctags paste strings into shell
+commands and hand them to system(3) without quoting. Backport of
+
+ From 01a4035c869b91c153af9a9132c87adb7669ea1c Mon Sep 17 00:00:00 2001
+ From: lu4nx <[email protected]>
+ Date: Tue, 6 Dec 2022
+ Subject: Fix etags local command injection vulnerability (Bug#59817)
+
+ From 8a098f6517157ebe2364f08008b44ab49c2d1115 Mon Sep 17 00:00:00 2001
+ From: Eli Zaretskii <[email protected]>
+ Date: Fri, 1 Jul 2022
+ Subject: Fix quoting of file names in 'ctags'
+
+Upstream added escape_shell_arg_string() and quotes every file name it
+passes to the shell. 20.7 predates that by twenty years; this brings the
+same fix to the old K&R source, as shell_quote().
+
+Both call sites are live here. The per-file update loop walks argbuffer[]
+by current_arg (not optind..argc, which is what makes the same loop dead in
+mule), and the "sort %s -o %s" over the -o output file is reached directly.
+On NetBSD 11.0/amd64:
+
+ ctags -u -o 'tags;touch /tmp/pwned' file.c
+
+ran the injected command before the fix and does nothing after it; a normal
+"-o out.tags" still works. (20.7's etags has no decompressor, so it lacks
+the third, popen, site that 21.4 has.)
+
+--- lib-src/etags.c.orig
++++ lib-src/etags.c
+@@ -221,6 +221,7 @@
+ void error ();
+ void suggest_asking_for_help ();
+ void fatal (), pfatal ();
++char *shell_quote ();
+ void find_entries ();
+ void free_tree ();
+ void getit ();
+@@ -763,6 +764,41 @@
+ #endif /* VMS */
+
+
++/* Return a copy of STR wrapped in single quotes so that a shell passes it
++ through unchanged. An embedded single quote is closed, escaped and
++ reopened.
++
++ Without this a string reaches the shell as written, and one that contains
++ shell metacharacters runs whatever it likes. CVE-2022-45939 and
++ CVE-2022-48337. */
++
++char *
++shell_quote (str)
++ char *str;
++{
++ char *p, *q, *out;
++ int n = 0;
++
++ for (p = str; *p != '\0'; p++)
++ n += (*p == '\'') ? 4 : 1;
++ out = xnew (n + 3, char);
++ q = out;
++ *q++ = '\'';
++ for (p = str; *p != '\0'; p++)
++ if (*p == '\'')
++ {
++ *q++ = '\'';
++ *q++ = '\\';
++ *q++ = '\'';
++ *q++ = '\'';
++ }
++ else
++ *q++ = *p;
++ *q++ = '\'';
++ *q = '\0';
++ return out;
++}
++
+ int
+ main (argc, argv)
+ int argc;
+@@ -1028,16 +1064,25 @@
+
+ if (update)
+ {
+- char cmd[BUFSIZ];
+ for (i = 0; i < current_arg; ++i)
+ {
++ char *pattern, *qpattern, *qtagfile, *cmd;
++
+ if (argbuffer[i].arg_type != at_filename)
+ continue;
+- sprintf (cmd,
+- "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
+- tagfile, argbuffer[i].what, tagfile);
++ pattern = xnew (strlen (argbuffer[i].what) + 3, char);
++ sprintf (pattern, "\t%s\t", argbuffer[i].what);
++ qpattern = shell_quote (pattern);
++ qtagfile = shell_quote (tagfile);
++ cmd = xnew (2 * strlen (qtagfile) + strlen (qpattern) + 32, char);
++ sprintf (cmd, "mv %s OTAGS;fgrep -v %s OTAGS >%s;rm OTAGS",
++ qtagfile, qpattern, qtagfile);
+ if (system (cmd) != GOOD)
+ fatal ("failed to execute shell command", (char *)NULL);
++ free (pattern);
++ free (qpattern);
++ free (qtagfile);
++ free (cmd);
+ }
+ append_to_tagfile = TRUE;
+ }
+@@ -1050,9 +1095,15 @@
+
+ if (update)
+ {
+- char cmd[BUFSIZ];
+- sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
+- exit (system (cmd));
++ char *qtagfile = shell_quote (tagfile);
++ char *cmd = xnew (2 * strlen (qtagfile) + 16, char);
++ int rc;
++
++ sprintf (cmd, "sort %s -o %s", qtagfile, qtagfile);
++ rc = system (cmd);
++ free (qtagfile);
++ free (cmd);
++ exit (rc);
+ }
+ return GOOD;
+ }
Index: editors/emacs20/patches/patch-CVE-2017-1000383
===================================================================
RCS file: editors/emacs20/patches/patch-CVE-2017-1000383
diff -N editors/emacs20/patches/patch-CVE-2017-1000383
--- /dev/null
+++ editors/emacs20/patches/patch-CVE-2017-1000383
+$NetBSD$
+
+CVE-2017-1000383: copy-file, which backup-buffer uses to make backups when
+backup-by-copying is in effect, creates the destination with creat(...,0666)
+and only chmods it to the wanted mode afterwards. A copy of a private file
+is briefly world-readable, and a backup inherits the source's setuid/setgid
+bits.
+
+Upstream closes this in two places that 20.7/21.4 predate: lisp/files.el's
+backup-buffer-copy wraps the copy in (with-file-modes ?\700 ...) -- the
+with-file-modes macro is
+
+ From d63d883a97e32aa5f0983b6577f7cbef8b6c3a3d Mon Sep 17 00:00:00 2001
+ Date: Wed, 14 May 2014
+ Subject: Add with-file-modes macro, and use it
+
+-- and modern src/fileio.c creates the copy with O_CREAT|O_EXCL and strips
+the setuid/setgid bits (preserved_permissions &= ~06000). This backport
+does the same at the C level for the old source: create 0600 so the file is
+never group/other-readable while it is being written, and mask the trailing
+chmod with 01777 (keeping the sticky and rwx bits, dropping setuid/setgid --
+the same effect as #o1777 in backup-buffer-copy).
+
+Reproduced on NetBSD 11.0/amd64 with emacs -batch and backup-by-copying: a
+04755 source produced a 04755 (setuid) backup before the fix and a 0755 one
+after. This is the same change already carried in zakinko/mule.
+
+--- src/fileio.c.orig
++++ src/fileio.c
+@@ -2345,7 +2345,11 @@
+ /* System's default file type was set to binary by _fmode in emacs.c. */
+ ofd = creat (XSTRING (encoded_newname)->data, S_IREAD | S_IWRITE);
+ #else /* not MSDOS */
+- ofd = creat (XSTRING (encoded_newname)->data, 0666);
++ /* Create the copy owner-readable/writable only. The final chmod below
++ widens it to the intended mode once the data is in place; creating it
++ 0666 (masked only by umask) meant a copy of a private file was briefly
++ world-readable while it was being written. CVE-2017-1000383. */
++ ofd = creat (XSTRING (encoded_newname)->data, 0600);
+ #endif /* not MSDOS */
+ #endif /* VMS */
+ if (ofd < 0)
+@@ -2378,7 +2382,11 @@
+ Fcons (newname, Qnil)));
+ }
+ #ifndef MSDOS
+- chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
++ /* Mask off the setuid and setgid bits: a copy -- above all a backup
++ file -- must never inherit them from the original. 01777 keeps the
++ sticky bit and the rwx bits, matching what a modern Emacs does with
++ #o1777. CVE-2017-1000383. */
++ chmod (XSTRING (encoded_newname)->data, st.st_mode & 01777);
+ #else /* MSDOS */
+ #if defined (__DJGPP__) && __DJGPP__ > 1
+ /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
Index: editors/emacs20/patches/patch-src_xrdb.c
===================================================================
RCS file: editors/emacs20/patches/patch-src_xrdb.c
diff -N editors/emacs20/patches/patch-src_xrdb.c
--- /dev/null
+++ editors/emacs20/patches/patch-src_xrdb.c
+$NetBSD$
+
+Replace gets() in the [TESTRM] test driver with fgets(), backporting
+
+ From e90a457c46ca4c6a231a422b9b30f5e0d0f9d1c1 Mon Sep 17 00:00:00 2001
+ From: Eli Zaretskii <[email protected]>
+ Date: Thu, 8 Sep 2022
+ Subject: * src/xrdb.c (main) [TESTRM]: Replace gets with fgets.
+
+gets() has no bound and cannot be used safely; it was removed from C11.
+The call is inside the TESTRM stand-alone driver, which is not compiled
+into Emacs (the built binary has no gets symbol), so this changes no
+shipped code -- it is here to match upstream and to keep the source
+clean, since gets() is a hard error with newer toolchains.
+
+--- src/xrdb.c.orig
++++ src/xrdb.c
+@@ -718,14 +718,14 @@
+ char query_class[90];
+
+ printf ("Name: ");
+- gets (query_name);
++ fgets (query_name, 90, stdin);
+
+ if (strlen (query_name))
+ {
+ char *value;
+
+ printf ("Class: ");
+- gets (query_class);
++ fgets (query_class, 90, stdin);
+
+ value = x_get_string_resource (xdb, query_name, query_class);
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.