Bug 15305 - POSIX problem: pathconf/fpathconf modifies errno for XFS filesystems on Linux
Summary: POSIX problem: pathconf/fpathconf modifies errno for XFS filesystems on Linux
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Siddhesh Poyarekar
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-03-26 18:03 UTC by Jeff Licquia
Modified: 2014-06-13 18:38 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
test program to demonstrate the problem (298 bytes, text/x-csrc)
2013-03-26 18:03 UTC, Jeff Licquia
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jeff Licquia 2013-03-26 18:03:39 UTC
Created attachment 6950 [details]
test program to demonstrate the problem

When pointed at a file on a XFS filesystem under Linux, pathconf(path, _PC_CHOWN_RESTRICTED) attempts to open /proc/sys/fs/xfs/restrict_chown to determine what it should do.  This open fails (because the path is not supported on recent kernels), which modifies errno.

From http://pubs.opengroup.org/onlinepubs/009695399/functions/pathconf.html:

"Otherwise, pathconf() or fpathconf() shall return the current variable value for the file or directory without changing errno."

(describing non-error situations)

I've attached a test program, which takes a path to test as its argument.  Here's the behavior I see on Fedora 18, with ext4 as the regular filesystem and an XFS loopback filesystem on ./mountpoint:

[licquia@lflap5 lsb-bug-3763]$ ./test-pathconf-errno /etc
pathconf returned 1
errno not changed
[licquia@lflap5 lsb-bug-3763]$ ./test-pathconf-errno ./mountpoint
pathconf returned 1
errno changed!
 pre = 0
 post = 2

The behavior is identical with git HEAD using LD_PRELOAD.
Comment 1 Carlos O'Donell 2013-03-28 15:02:15 UTC
Jeff,

Thanks for submitting this. 

Take care that you're quoting POSIX 2004, and the most recent standard is 2008. In this case the 2008 standard is still the same.

I agree that there is a problem here and we'll try to fix this for 2.18.

Siddhesh Poyarekar noted that the XFS proc file we check in glibc is now really out of date e.g.
...
    case XFS_SUPER_MAGIC:
      /* Read the value from /proc/sys/fs/xfs/restrict_chown.  If we cannot
         read it default to assume the restriction is in place.  */
      fd = open_not_cancel_2 ("/proc/sys/fs/xfs/restrict_chown", O_RDONLY);
      if (fd != -1)
        {
          char buf[2];
          if (TEMP_FAILURE_RETRY (read_not_cancel (fd, buf, 2)) == 2
              && buf[0] >= '0' && buf[0] <= '1')
            retval = buf[0] - '0';

          close_not_cancel_no_status (fd);
        }
      break;
...
The open_not_cancel_2 fails and that sets errno when it shouldn't.

I don't think we've ever had a good test for this.
Comment 2 Siddhesh Poyarekar 2013-04-03 06:49:32 UTC
Fixed in master.

commit d755bba40f880c01ced8740a26fecc85534454b9
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Wed Apr 3 10:56:45 2013 +0530

    Preserve errno across _PC_CHOWN_RESTRICTED call on XFS
    
    Fix BZ #15305.
    
    On kernel versions earlier than 2.6.29, the Linux kernel exported a
    sysctl called restrict_chown for xfs, which could be used to allow
    chown to users other than the owner.  2.6.29 removed this support,
    causing the open_not_cancel_2 to fail and thus modify errno.  The fix
    is to save and restore errno so that the caller sees it as unmodified.
    
    Additionally, since the code to check the sysctl is not useful on
    newer kernels, we add an ifdef so that in future the code block gets
    rmeoved completely.