Bug 15004 - btrfs_fget_compression: /proc open of /proc/self/fd/48 failed: Permission denied
Summary: btrfs_fget_compression: /proc open of /proc/self/fd/48 failed: Permission denied
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: VFS Modules (show other bugs)
Version: 4.15.5
Hardware: All Linux
: P5 normal (vote)
Target Milestone: ---
Assignee: Jeremy Allison
QA Contact: Samba QA Contact
Depends on:
Reported: 2022-03-08 21:02 UTC by Noel Maximilian Kuntze
Modified: 2022-04-08 17:37 UTC (History)
1 user (show)

See Also:

Debug level 10 logs (21.44 KB, text/plain)
2022-03-10 21:45 UTC, Noel Maximilian Kuntze
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Noel Maximilian Kuntze 2022-03-08 21:02:41 UTC
Version 4.15.5, btrfs with compression. vfs_btrfs module.
OS: Alpine Linux 

These logs occur every couple of minutes. They only occur on one server but not on another. In what circumstances could this problem occur? I presume the fd in that file would be owned by the UID of the process, so access should work just fine?

The errors occur when a client tries to access a file. The file can be read just fine by the client.

Ideally those errors would not occur, or if they were benign, not be logged at error level.

2022-02-26T12:34:37.053231+01:00 FS1 daemon daemon.err smbd[21349]: [2022/02/26 12:34:37.053178,  0] ../../source3/modules/vfs_btrfs.c:493(btrfs_fget_compression)
2022-02-26T12:34:37.053321+01:00 FS1 daemon daemon.err smbd[21349]:   btrfs_fget_compression: /proc open of /proc/self/fd/48 failed: Permission denied
2022-02-26T12:34:37.053503+01:00 FS1 daemon daemon.err smbd[21349]: [2022/02/26 12:34:37.053482,  0] ../../source3/modules/vfs_btrfs.c:493(btrfs_fget_compression)
2022-02-26T12:34:37.053539+01:00 FS1 daemon daemon.err smbd[21349]:   btrfs_fget_compression: /proc open of /proc/self/fd/48 failed: Permission denied
2022-02-26T12:34:37.053773+01:00 FS1 daemon daemon.err smbd[21349]: [2022/02/26 12:34:37.053754,  0] ../../source3/modules/vfs_btrfs.c:493(btrfs_fget_compression)
2022-02-26T12:34:37.053822+01:00 FS1 daemon daemon.err smbd[21349]:   btrfs_fget_compression: /proc open of /proc/self/fd/48 failed: Permission denied
Comment 1 Noel Maximilian Kuntze 2022-03-08 21:54:22 UTC
Additional information:

The problem seems to only occur with compressed file types like zip, tar, and some pdfs.

Opening MSI and exe files does not cause such errors to be logged.
Comment 2 Jeremy Allison 2022-03-09 21:25:33 UTC
This happens when smbd has an O_PATH (pathref) file descriptor open, but does't have rights to open the /proc/self/fd/<filenumber> with O_RDONLY.

It's coming from here:

        fd = open(p, O_RDONLY);
        if (fd == -1) {
                DBG_ERR("/proc open of %s failed: %s\n", p, strerror(errno));
                return map_nt_error_from_unix(errno);

when we're trying to upgrade an fd opened with fd = open(pathname, O_PATH); and we don't have the permissions to do so.

As not being able to return compression status isn't treated as a fatal error in the upper levels, probably the best thing to do is change the DBG_ERR level to DBG_WARNING or DBG_NOTICE.

Ralph, do you agree ?
Comment 3 Noel Maximilian Kuntze 2022-03-09 23:28:41 UTC
Naturally the FD of a process should be owned by its UID, no? If that is true, then generally that open() should work. So the question is why doesn't it then?
Comment 4 Jeremy Allison 2022-03-10 00:27:08 UTC
No, opening the /proc/self/fd/<fd-number> depends on the underlying permissions of the file it's opened on. Remember, we have an fd open with O_PATH, which requires no read or write permissions, only rx on the containing directory.

So we try and upgrade to O_RDONLY (which allows reading of the contents of the file) and we don't have read permission on the underlying file the fd points to.
Comment 5 Noel Maximilian Kuntze 2022-03-10 00:40:04 UTC
And yet reading the file over the CIFS share works. So how does that work if the file is actually not readable by samba?
Comment 6 Jeremy Allison 2022-03-10 00:54:33 UTC
(In reply to Noel Maximilian Kuntze from comment #5)

Don't know :-). You'd have to post a debug level 10 see see exactly what is going on here.
Comment 7 Ralph Böhme 2022-03-10 06:08:00 UTC
Maybe a kernel bug? Can you update to a newer kernel and try again?
Comment 8 Noel Maximilian Kuntze 2022-03-10 21:45:24 UTC
Created attachment 17201 [details]
Debug level 10 logs
Comment 9 Noel Maximilian Kuntze 2022-03-10 21:45:56 UTC
I got some debug level 10 logs for you there. Please let me know if they suffice, and if you need any other, or more logs.

Thank you for your help thus far!
Comment 10 Noel Maximilian Kuntze 2022-03-10 21:48:57 UTC
Kernel version is 5.15.12 btw.
Comment 11 Noel Maximilian Kuntze 2022-03-16 23:52:33 UTC
The problem persists with kernel version 5.15.26.
Comment 12 Noel Maximilian Kuntze 2022-04-07 17:48:16 UTC
@Ralph How do you want to proceed?
Comment 13 Ralph Böhme 2022-04-07 17:56:47 UTC
(In reply to Noel Maximilian Kuntze from comment #12)
When I have time. I'm swamped with other stuff, sorry.
Comment 14 Jeremy Allison 2022-04-07 18:15:54 UTC
OK, I took a quick look at this and it's coming from:


477         if (!fsp->fsp_flags.is_pathref) {
478                 ret = ioctl(fsp_fd, FS_IOC_GETFLAGS, &flags);
479                 if (ret < 0) {
480                         DBG_WARNING("FS_IOC_GETFLAGS failed: %s, fd %lld\n",
481                                     strerror(errno), (long long)fd);
482                         return map_nt_error_from_unix(errno);
483                 }
484                 if (flags & FS_COMPR_FL) {
485                         *_compression_fmt = COMPRESSION_FORMAT_LZNT1;
486                 } else {
487                         *_compression_fmt = COMPRESSION_FORMAT_NONE;
488                 }
489                 return NT_STATUS_OK;
490         }
492         if (!fsp->fsp_flags.have_proc_fds) {
493                 return NT_STATUS_NOT_IMPLEMENTED;
494         }
496         p = sys_proc_fd_path(fsp_fd, buf, sizeof(buf));
497         if (p == NULL) {
498                 return NT_STATUS_NO_MEMORY;
499         }
501         fd = open(p, O_RDONLY);
502         if (fd == -1) {
503                 DBG_ERR("/proc open of %s failed: %s\n", p, strerror(errno));
504                 return map_nt_error_from_unix(errno);
505         }
507         ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);

The current file is a pathref file descriptor open with O_PATH, and we're now trying to upgrade that into a real file descriptor open with O_RDONLY in order to do the ioctl() call to get the inode flags. ioctl requires a non-pathref fd.

What I suggest is changing the DBG_ERR() in line 503 to read:

503                 DBG_ERR("%s /proc open of %s failed: %s\n",
504                         fsp_str_dbg(fsp),
505                         p, strerror(errno));

Note the addition of fsp_str_dbg(fsp). That will give you the relative path from the root of the share of the file that is giving problems. Then take a look at the permissions of this file and see if indeed it should allow a re-open with O_RDONLY.
Comment 15 Björn Jacke 2022-04-08 07:55:20 UTC
If finally we could get MR 1832 in, then we could implement get/set compression easily a filesystem independent and this could be removed from special vfs objects like btrfs. I was working on that already but without the statx implementation getting in, this can't move on.
Comment 16 Jeremy Allison 2022-04-08 17:36:41 UTC
(In reply to Björn Jacke from comment #15)

That's a separate issue Björn. Let's figure out the exact btrfs problem here first.