Subject: sed -i disrespects read-only

From: Leonid Mironov <[email-masked]>
Date: Wed, 30 Jun 2021 08:01:13 +0200

Hello,

sed disrespects read-only file attributes when editing in place.

$ ls -l testfile*
-r--r--r-- 1 lvm lvm 50 Jun 30 08:32 testfile
$ sed 's/test/bug/g' -i~ testfile
$ diff testfile testfile~
2c2
< this is a bug
---
> this is a test
$ sed --version
sed (GNU sed) 4.4
Copyright © 2017 Free Software Foundation, Inc.
Licence GPLv3+: GNU GPL version 3 or later <https://www.gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Jay Fenlason, Tom Lord, Ken Pizzini,
and Paolo Bonzini.
GNU sed home page: <http://www.gnu.org/software/sed/>.
General help using GNU software: <http://www.gnu.org/gethelp/>.
E-mail bug reports to: <[email-masked]>.

$ uname -a
Linux server 5.4.0-74-generic #83~18.04.1-Ubuntu SMP Tue May 11 16:01:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Not the latest version, but buiding latest git sources fails with

CC       sed/sed_sed-execute.o
sed/execute.c: In function 'open_next_file':
sed/execute.c:575:7: error: unknown type name 'security_context_t'; did you mean 'security_class_t'?
security_context_t old_fscreatecon;
^~~~~~~~~~~~~~~~~~
security_class_t
sed/execute.c:596:11: error: unknown type name 'security_context_t'; did you mean 'security_class_t'?
security_context_t con;
^~~~~~~~~~~~~~~~~~
security_class_t
sed/execute.c:597:49: error: passing argument 2 of 'lgetfilecon' from incompatible pointer type [-Werror=incompatible-pointer-types]
if (lgetfilecon (input->in_file_name, &con) != -1)
^
In file included from sed/execute.c:33:0:
./lib/selinux/selinux.h:104:1: note: expected 'char **' but argument is of type 'int *'
lgetfilecon (char const *file _GL_UNUSED_PARAMETER,
^~~~~~~~~~~
sed/execute.c:601:51: error: passing argument 1 of 'getfscreatecon' from incompatible pointer type [-Werror=incompatible-pointer-types]
reset_fscreatecon = getfscreatecon (&old_fscreatecon) >= 0;
^
In file included from sed/execute.c:33:0:
./lib/selinux/selinux.h:89:1: note: expected 'char **' but argument is of type 'int *'
getfscreatecon (char **con _GL_UNUSED_PARAMETER)
^~~~~~~~~~~~~~
sed/execute.c:602:35: error: passing argument 1 of 'setfscreatecon' makes pointer from integer without a cast [-Werror=int-conversion]
if (setfscreatecon (con) < 0)
^~~
In file included from sed/execute.c:33:0:
./lib/selinux/selinux.h:92:1: note: expected 'const char *' but argument is of type 'int'
setfscreatecon (char const *con _GL_UNUSED_PARAMETER)
^~~~~~~~~~~~~~
In file included from ./lib/gettext.h:26:0,
from ./basicdefs.h:26,
from sed/sed.h:18,
from sed/execute.c:20:
sed/execute.c:603:36: error: format '%s' expects argument of type 'char *', but argument 4 has type 'int' [-Werror=format=]
fprintf (stderr, _("%s: warning: failed to set default" \
^
sed/execute.c:603:34: note: in expansion of macro '_'
fprintf (stderr, _("%s: warning: failed to set default" \
^
sed/execute.c:604:64: note: format string is defined here
" file creation context to %s: %s"),
~^
%d
sed/execute.c:606:24: error: passing argument 1 of 'freecon' makes pointer from integer without a cast [-Werror=int-conversion]
freecon (con);
^~~
In file included from sed/execute.c:33:0:
./lib/selinux/selinux.h:86:1: note: expected 'char *' but argument is of type 'int'
freecon (char *con _GL_UNUSED_PARAMETER) {}
^~~~~~~
sed/execute.c:625:27: error: passing argument 1 of 'setfscreatecon' makes pointer from integer without a cast [-Werror=int-conversion]
setfscreatecon (old_fscreatecon);
^~~~~~~~~~~~~~~
In file included from sed/execute.c:33:0:
./lib/selinux/selinux.h:92:1: note: expected 'const char *' but argument is of type 'int'
setfscreatecon (char const *con _GL_UNUSED_PARAMETER)
^~~~~~~~~~~~~~
sed/execute.c:626:20: error: passing argument 1 of 'freecon' makes pointer from integer without a cast [-Werror=int-conversion]
freecon (old_fscreatecon);
^~~~~~~~~~~~~~~
In file included from sed/execute.c:33:0:
./lib/selinux/selinux.h:86:1: note: expected 'char *' but argument is of type 'int'
freecon (char *con _GL_UNUSED_PARAMETER) {}
^~~~~~~
cc1: all warnings being treated as errors
Makefile:2913: recipe for target 'sed/sed_sed-execute.o' failed
make[2]: *** [sed/sed_sed-execute.o] Error 1
make[2]: Leaving directory '/tmp/2/sed'
Makefile:3193: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/tmp/2/sed'
Makefile:2375: recipe for target 'all' failed
make: *** [all] Error 2