Bug 1835761

Summary: [BZ] 'sed' in-place edits on FUSE filesystems create files with all-zero modebits
Product: Red Hat Enterprise Linux 8 Reporter: Parikshit Khedekar <pkhedeka>
Component: sedAssignee: Jakub Martisko <jamartis>
Status: CLOSED ERRATA QA Contact: Radka Brychtova <rskvaril>
Severity: high Docs Contact:
Priority: urgent    
Version: 8.0CC: rskvaril
Target Milestone: rc   
Target Release: 8.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1836317 (view as bug list) Environment:
Last Closed: 2020-11-04 01:54:55 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1836317    

Description Parikshit Khedekar 2020-05-14 13:12:04 UTC
Description of problem:

'sed' in-place edits on FUSE filesystems create files with all-zero mode bits (running sed-4.5-1):

This is an upstream bug that got fixed with GNU sed-4.8, and apparently affects all FUSE filesystems. Local filesystems are not affected.

This is the bug fix reference: http://git.savannah.gnu.org/gitweb/?p=sed.git;a=commitdiff;h=f69b085d3e7011ad6fa1dcf1473879a961fa1605;hp=a9cb52bcf39f0ee307301ac73c11acb24372b9d8


Version-Release number of selected component (if applicable):

sed-4.5-1 and below

How reproducible:

```
/tmp$ echo echo > /eos/(...)/tmp/inplaceedit/testfile
/tmp$ ls -l /eos/(...)/tmp/inplaceedit/testfile
-rw-r--r--. 1 myuser c3 5 May 13 07:58 /eos/(...)/tmp/inplaceedit/testfile
/tmp$ sed -i -e s/echo/sed/ /eos/(...)/tmp/inplaceedit/testfile
/tmp$ ls -l /eos/(...)/tmp/inplaceedit/testfile
----------. 1 myuser c3 4 May 13 07:58 /eos/(...)/tmp/inplaceedit/testfile
```

Actual results:

File with all-zero mode bits

Expected results:

Shouldn't happen.

Additional info:

ftp://ftp.gnu.org/gnu/sed

With the latest sed from upstream it is as,

cat /sed/utils.c

-------------------------------------------------------------------
FILE *
ck_mkstemp (char **p_filename, const char *tmpdir,
            const char *base, const char *mode)
{
  char *template = xmalloc (strlen (tmpdir) + strlen (base) + 8);
  sprintf (template, "%s/%sXXXXXX", tmpdir, base);

   /* The ownership might change, so omit some permissions at first
      so unauthorized users cannot nip in before the file is ready.
      mkstemp forces O_BINARY on cygwin, so use mkostemp instead.  */
  mode_t save_umask = umask (0077);   <<-------------------------------UMASK 
  int fd = mkostemp (template, 0);
  umask (save_umask);
  if (fd == -1)
    panic (_("couldn't open temporary file %s: %s"), template,
           strerror (errno));
#if O_BINARY
  if (binary_mode && (set_binary_mode ( fd, O_BINARY) == -1))
      panic (_("failed to set binary mode on '%s'"), template);
#endif

  *p_filename = template;
  FILE *fp = fdopen (fd, mode);
  register_open_file (fp, template);
  return fp;
}
-------------------------------------------------------------------

With the  sed-4.8-1.fc33 from Fedora

FILE *
ck_mkstemp (char **p_filename, const char *tmpdir,
            const char *base, const char *mode)
{
  char *template = xmalloc (strlen (tmpdir) + strlen (base) + 8);
  sprintf (template, "%s/%sXXXXXX", tmpdir, base);

   /* The ownership might change, so omit some permissions at first
      so unauthorized users cannot nip in before the file is ready.
      mkstemp forces O_BINARY on cygwin, so use mkostemp instead.  */
  mode_t save_umask = umask (0077);  <<------------------------------UMASK
  int fd = mkostemp (template, 0);
  umask (save_umask);
  if (fd == -1)
    panic (_("couldn't open temporary file %s: %s"), template,
           strerror (errno));
#if O_BINARY
  if (binary_mode && (set_binary_mode ( fd, O_BINARY) == -1))
      panic (_("failed to set binary mode on '%s'"), template);
#endif

  *p_filename = template;
  FILE *fp = fdopen (fd, mode);
  register_open_file (fp, template);
  return fp;
}

-------------------------------------------------------------------

Sed with RHEL  sed-4.5-1.el8.x86_64.rpm 


FILE *
ck_mkstemp (char **p_filename, const char *tmpdir,
            const char *base, const char *mode)
{
  char *template = xmalloc (strlen (tmpdir) + strlen (base) + 8);
  sprintf (template, "%s/%sXXXXXX", tmpdir, base);

   /* The ownership might change, so omit some permissions at first
      so unauthorized users cannot nip in before the file is ready.
      mkstemp forces O_BINARY on cygwin, so use mkostemp instead.  */
  mode_t save_umask = umask (0700); <<----------------------------UMASK
  int fd = mkostemp (template, 0);
  umask (save_umask);
  if (fd == -1)
    panic(_("couldn't open temporary file %s: %s"), template, strerror(errno));

  *p_filename = template;
  FILE *fp = fdopen (fd, mode);
  register_open_file (fp, template);
  return fp;
}

/* Panic on failing fwrite */
void
ck_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
  clearerr(stream);
  if (size && fwrite(ptr, size, nmemb, stream) != nmemb)
    panic(ngettext("couldn't write %llu item to %s: %s",
                   "couldn't write %llu items to %s: %s", nmemb),
          (unsigned long long) nmemb, utils_fp_name(stream),
          strerror(errno));
}

Comment 12 errata-xmlrpc 2020-11-04 01:54:55 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (sed bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2020:4517