Ticket #4590 (accepted defect)

Opened 7 days ago

Last modified 29 minutes ago

Extended attributes - Cannot get attributes of source directory - Invalid argument (22)

Reported by: andyrozman Owned by: andrew_b
Priority: major Milestone: 4.8.33
Component: mc-core Version: master
Keywords: Cc:
Blocked By: Blocking:
Branch state: on review Votes for changeset:

Description

Version: 4.8.32-12-g9e06a50eb
OS: Ubuntu 24.04.1 LTS

Sometimes when I am copying files I get red screen "Cannot get attributes of source directory - Invalid argument (22)".

In most cases I can use "Skip/Skip? All" function and files are still moved or copied...

This is failing when I am trying to copy files on veracrypt encrypted volume (I have full permission on drive, even started with umask=000, which gives full permissions). Copying of folders in this case fails... If I enter the directory and copy files, I still get upper message, but I can still copy the files.

I started receiving this errors since I did my own build of mc few weeks ago (before that I used version supplied with Ubuntu 22.04 LTS). After I upgraded Ubuntu to 24.04 last weekend, this error started preventing copying folders.

It would be nice if this could be fixed. I rely on mc for most of operations.

I tried to copy files with different software and copying there works without problems...

Attachments

Screenshot 2024-09-24 at 07.32.26.png (164.9 KB) - added by zaytsev 4 days ago.

Change History

comment:1 Changed 7 days ago by zaytsev

I think this is the result of #4532 - after this change mc tries to preserve extended ext2 attributes, but in your case the fgetflags call fails, causing this error.

What filesystem is on the volume? Does this always happen for every directory, or only sometimes?

If attributes are not supported, the file system should return ENOTSUP, but in your case it returns EINVAL. Sounds to me like a bug somewhere between Veracrypt and the kernel (or a "design" change). I think we already had something like this for CIFS (#3987). The fix there was to retry if EINTR was returned.

Andrew, what do you think?

comment:2 Changed 7 days ago by andyrozman

So on veracrypt container there is ext2 FS (it might be ext3 or 4). I think that problem is that volume in in veracrypt container/volume and that that underlaying volume doesn't support your calls.

So I can try to do chmod on directory, and command goes through, but in the end attribute is the same as it was before...

Would it be possible to add whitelist into mc, so that when making operations on whitelisted volume, it wouldn't try preserving attributes?

It happens always, and copying files is possible (while using Skip option), but copying folders is not possible. Using retry option doesn't make anything, just prevents copying... This is if I am doing operation on drive (so copy from and to same drive)

But it works if I copy from different drive (normal ext4), it shows error message, but with "Skip all" it copies files and folders.

comment:3 Changed 6 days ago by zaytsev

I think that problem is that volume in in veracrypt container/volume and that that underlaying volume doesn't support your calls.

As I explained, if this is the case, then it should return ENOTSUP, but it doesn't.

So I can try to do chmod on directory, and command goes through, but in the end attribute is the same as it was before...

The chmod command is useless here, you can set flags with chattr / lsattr. For example, you can try F as a directory flag. If lsattr fails on directories with EINVAL, which is what I suspect, you should report the bug to Veracrypt.

Would it be possible to add whitelist into mc

So how do we know that it's a broken volume that doesn't return ENOTSUP on unsupported operations, instead of some other problem causing EINVAL?

It happens always ...

I don't understand your explanation:

1) Does only the "Cannot get attributes of source directory" message appear, or not? (For files?)
2) Does copying directories between non-Veracrypt extX work? (Yes?)
3) Does copying directories from Veracrypt work? (No?)
4) Does copying directories to Veracrypt work? (No, different message?)

comment:4 Changed 6 days ago by andrew_b

Can we handle EINVAL and ENOSYS in addition to ENOTSUP: not to preserve ext2 attributes without error messages?

comment:5 Changed 6 days ago by zaytsev

Looking at the VeraCrypt source code, it never returns ENOTSUP / EOPNOTSUPP:

https://veracrypt.fr/code/VeraCrypt/tree/src/Driver/Fuse/FuseService.cpp#n369

In fact, it doesn't have any support for extended attributes (no custom ioctl implementation), and the error comes from libfuse default ioctl implementation. My understanding is that if no handler is implemented, then ENOSYS is returned by the FS-level handler:

https://github.com/libfuse/libfuse/blob/master/lib/fuse.c#L2267

It should then be converted to ENOTTY by the kernel:

https://github.com/torvalds/linux/blob/master/fs/fuse/ioctl.c#L12

This is used by fgetflags, which returns EOPNOTSUPP in many cases, but when it gets to ioctl, it returns its result (so if the kernel got EINVAL, it will return it).

https://github.com/tytso/e2fsprogs/blob/master/lib/e2p/fgetflags.c

This works for me on Fedora 40:

zaytsev@fedora:~/src/libfuse/example/test$ lsattr
lsattr: Operation not supported While reading flags on ./hello
lsattr: Operation not supported While reading flags on ./testdir

zaytsev@fedora:~/src/libfuse/example/test$ uname -a
Linux fedora 6.10.10-200.fc40.aarch64 #1 SMP PREEMPT_DYNAMIC Thu Sep 12 18:52:07 UTC 2024 aarch64 GNU/Linux

I don't know why it doesn't work for the reporter. There was a bugfix in libfuse3 error propagation, but I also tried 2.9.9 with hello-fs and it works.

https://github.com/libfuse/libfuse/issues/640
https://github.com/libfuse/libfuse/commit/5128cee2dd0e54b74e9ea75dfc8cf70a866ee120

comment:6 Changed 6 days ago by zaytsev

Can we handle EINVAL and ENOSYS in addition to ENOTSUP: not to preserve ext2 attributes without error messages?

It should not be possible to get ENOSYS from FS - and the reporter gets EINVAL, so it would not help. What I think we should definitely do is use EOPNOTSUPP or check both.

(ENOTSUP and EOPNOTSUPP have the same value on Linux, but according to POSIX.1 these error values should be different).

Regarding EINVAL, it would be good to first understand why this happens. Do you have any idea?

Maybe the reporter can put the lsattr output in his test VeraCrypt directory. Then we can see what it says for files and directories. I can also install Ubuntu 24.04 in a VM to see if I can reproduce it.

comment:7 Changed 6 days ago by andrew_b

comment:8 Changed 6 days ago by zaytsev

Right, this is the same code I referenced. As you can see they use EOPNOTSUPP everywhere and there is no EINVAL anywhere. So it can only come from the ioctl call. But I don't understand how this can happen.

comment:9 Changed 6 days ago by zaytsev

zaytsev@ubuntu-24-04:~/src/libfuse/example/test$ lsattr
lsattr: Operation not supported While reading flags on ./hello
lsattr: Operation not supported While reading flags on ./testdir

zaytsev@ubuntu-24-04:~/src/fuse-2.9.9/example/test$ lsattr
lsattr: Operation not supported While reading flags on ./hello
lsattr: Operation not supported While reading flags on ./testdir

Can there be some other reason why EINVAL is returned, some race condition between function calls? VeraCrypt only has AMD64 builds for Ubuntu :( I can't install it on ARM64.

comment:10 Changed 6 days ago by andyrozman

So I tried lsattr in one of folders:

lsattr: Invalid argument While reading flags on ./chord4.iml
lsattr: Invalid argument While reading flags on ./chord4.log
lsattr: Invalid argument While reading flags on ./chord4.log.1
lsattr: Invalid argument While reading flags on ./chord4.log.2
lsattr: Invalid argument While reading flags on ./chord4.log.3
lsattr: Invalid argument While reading flags on ./chord4.log.4
lsattr: Invalid argument While reading flags on ./chord4.log.5
lsattr: Invalid argument While reading flags on ./chordProperties
lsattr: Invalid argument While reading flags on ./data
lsattr: Invalid argument While reading flags on ./doc
lsattr: Invalid argument While reading flags on ./etc
lsattr: Invalid argument While reading flags on ./issues
lsattr: Invalid argument While reading flags on ./LICENSE
lsattr: Invalid argument While reading flags on ./pom.xml
lsattr: Invalid argument While reading flags on ./README.md
lsattr: Invalid argument While reading flags on ./src
lsattr: Invalid argument While reading flags on ./target

It is same for all the others.

Like I said machine is Ubuntu 24.04.1 LTS, which was upgraded from 22.04.1 (previous week). This worked on old machine with old mc (don't know what version it was). Problem started happening when I built my own mc version (newest from master), I think that was few weeks ago. I didn't use my encrypted drive then a lot, I mean I did copy some files from it to different drive (which brought red banner,but action suceded with use of Skip), but I wasn't copying files and folders on the same drive (which is operation that is no longer possible).

Operations:
copy file ENC -> ENC works - (shows warning - can be skipped)
copy dirs ENC -> ENC DOESN'T work - (shows warning - can't be skipped)
copy file ENC -> O:EXT4 works - (warning - can be skipped)
copy dirs ENC -> O:EXT4 DOESN'T work - (warning - can't be skipped)
copy file O:EXT4 -> O:EXT4 works
copy dirs O:EXT4 -> O:EXT4 works

So it seems I can't copy any directories from or to encrypted drive (with mc).

So I searched for libfuse (locate libfuse) and this is what it found.

/usr/lib/x86_64-linux-gnu/libfuse.so.2
/usr/lib/x86_64-linux-gnu/libfuse.so.2.9.9
/usr/lib/x86_64-linux-gnu/libfuse3.so.3
/usr/lib/x86_64-linux-gnu/libfuse3.so.3.14.0

Last edited 6 days ago by zaytsev (previous) (diff)

comment:11 Changed 6 days ago by zaytsev

Thanks, that helps!

So the problem is indeed that the encrypted file system returns EINVAL instead of EOPNOTSUPP. I'm still a bit wary of just blacklisting EINVAL and would like to understand why this happens and who is at fault.

Can you show mount flags?

It would also be good to know if lsattr works on other fuse systems on your machine, such as dav2fs or sshfs. If they work, then it's really pointing to !Veracrypt... and maybe we should involve VeraCrypt? developer.

Last edited 6 days ago by zaytsev (previous) (diff)

comment:12 Changed 6 days ago by andyrozman

I have only NTFS with fuse fs, and its showing similar problem.

➜  windows lsattr
lsattr: Invalid argument While reading flags on ./DumpStack.log.tmp
lsattr: Invalid argument While reading flags on ./$GetCurrent
lsattr: Invalid argument While reading flags on ./$Recycle.Bin
lsattr: Invalid argument While reading flags on ./$Windows.~WS
lsattr: Invalid argument While reading flags on ./$WinREAgent
lsattr: Invalid argument While reading flags on ./cygwin64
lsattr: Operation not supported While reading flags on ./Documents and Settings
lsattr: Invalid argument While reading flags on ./hiberfil.sys
lsattr: Invalid argument While reading flags on ./Intel
lsattr: Invalid argument While reading flags on ./pagefile.sys
lsattr: Invalid argument While reading flags on ./PerfLogs
lsattr: Invalid argument While reading flags on ./Program Files
lsattr: Invalid argument While reading flags on ./Program Files (x86)
lsattr: Invalid argument While reading flags on ./ProgramData
lsattr: Invalid argument While reading flags on ./Recovery
lsattr: Invalid argument While reading flags on ./RootPhone
lsattr: Invalid argument While reading flags on ./swapfile.sys
lsattr: Invalid argument While reading flags on ./SWSetup
lsattr: Invalid argument While reading flags on ./System Volume Information
lsattr: Invalid argument While reading flags on ./system.sav
lsattr: Invalid argument While reading flags on ./Temp
lsattr: Invalid argument While reading flags on ./Users
lsattr: Invalid argument While reading flags on ./Windows

And there is same problem... I can copy files and directories to NTFS-fuse, but I can copy only files from NTFS-fuse.

But I noticed that my external drives (that are NTFS) are connecting with NTFS-3g and everything works ok there (no warnings).

So my assumption would be that it has something to do with fuseblk not with veracrypt itself.

Or maybe my fuse is missconfigured or something. I do have two libfuses there libfuse.so.2.9.9 and libfuse3.so.3.14.0.

As for mount flags, till now I haven't used any... Before I reported this problem I changed my flags, just in case that could be the problem (but it seems it wasn't), but I use just standard ones (--fs-options="uid=1000,gid=1000,umask=000"), I tried first with umask=022, but same result...

Last edited 6 days ago by zaytsev (previous) (diff)

comment:13 Changed 6 days ago by zaytsev

  • Cc veracrypt@… added
  • Summary changed from Cannot get attributes of source directory - Invalid argument (22) to VeraCrypt - Cannot get attributes of source directory - Invalid argument (22)

Dear VeraCrypt developers,

Our user reports that he has problems copying files from VeraCrypt volumes. We identified the problem as fgetflags on files & directories return EINVAL instead of EOPNOTSUPP.

The user confirms that the NTFS-3g driver is working correctly on his system. I also checked hello-filesystems with fuse3 and fuse2.9.9, and when using the high-level interface and no ioctl implementation is provided, the kernel returns ENOTTY, which is then correctly converted to EOPNOTSUPP.

I suspected that EINVAL was incorrectly returned by VeraCrypt to the fuse driver instead of ENOSYS, but I couldn't find any evidence of this in the code.

The problem really seems to be with VeraCrypt. We would appreciate your help.

comment:14 Changed 6 days ago by ossi

i wonder whether this isn't due to some security stuff like selinux or apparmor being misconfigured and not letting the syscalls through properly. we've repeatedly seen this in qt.

comment:15 Changed 6 days ago by andyrozman

Don't use selinux, but I do have apparmor installed.

I checked in log, and there are no apparmor messages there (usually I see something there) that would be tied to this.

So I checked and it seems that my version of veracrypt is still using the old libfuse: libfuse.so.2 (libfuse.so.2.9.9).

Maybe new libfuse works better, but that will be only helpful if new version of veracrypt uses it (my version of veracrypt is 2 years old, because that was the last version that supported true-crypt volume (most of my volumes are vera-crypt ones, but I still have one that is old).

I will let you guys know if this works, but it will take me few days to do this.

comment:16 Changed 5 days ago by andyrozman

I tried to install new version of veracrypt (my old one is 1.24.4, which is about 4y old), but it seems that my volumes are not compatible (no idea why, waiting for response from their support team), everything looks like it should work but it doesn't. I did check that new version of veracrypt is still using the old libfuse library...

Is there a way that I could change my version of mc that this checks wouldn't be made? I mean in shell I can copy any directory to my veracrypt drive without the problem... Only mc is preventing copy and shows this errors? Since this worked in my previous version of mc there should be a way that it could work now.

Couldn't we add handling of "Invalid argument While reading flags on" to be the same as "Operation not supported While reading flags on".

Last edited 5 days ago by andyrozman (previous) (diff)

comment:17 Changed 5 days ago by zaytsev

Couldn't we add handling of "Invalid argument While reading flags on" to be the same as "Operation not supported While reading flags on".

I'm leaning towards this solution because it seems there are more broken fuse users out there - or maybe, as ossi suggests, something is changing the syscall return value.

What I didn't like about this idea is that there could be other reasons why EINVAL is returned and the attributes are not transferred without the user noticing. But apparently there is very little risk of this happening.

Is there a way that I could change my version of mc that this checks wouldn't be made?

You can uncheck "preserve attributes", but afaik you'll also lose timestamps that way. Otherwise, you can edit the source or wait for the patch. Or use the previous version.

comment:18 Changed 5 days ago by andyrozman

Then I will wait for the patch... Thanks for fixing this.

Using old version stopped working because of some other issues with zsh and mc, which is why I built new version of mc in the first place (before I upgraded to Ubuntu 24.04 which had newer version by default).

comment:19 Changed 4 days ago by zaytsev

Just to support my point that ENOTSUP != EOPNOTSUP - I can now reproduce the same error on Solaris, where EOPNOTSUP is 122.

It also seems that our skip logic is broken:

  1. I copy 1 file
  2. I get an error message
  3. When I press "Skip", the file is copied.

Now when I repeat the same with a directory, the directory is not copied.

Changed 4 days ago by zaytsev

comment:20 follow-up: ↓ 21 Changed 4 days ago by zaytsev

  • Cc veracrypt@… removed
  • Milestone changed from Future Releases to 4.8.33

I may have an idea where EINVAL comes from.

Unfortunately, my understanding of how VeraCrypt, fuse and native filesystems interact is still incomplete. I only fully understand how the basic fuse filesystems (sshfs) work. But apparently VeraCrypt exposes a block device via fuse, which is then mounted using the "normal" filesystem drivers. So the error codes we get are not necessarily coming from VeraCrypt or fuse, but may be returned by the filesystem drivers.

I looked in the kernel to see what drivers return, and EOPNOTSUPP and ENOTTY (which we don't need to deal with explicitly because it's converted to EOPNOTSUPP by fgetflags), but they also seem to return EINVAL with a similar meaning (btrfs). I still can't reproduce it on my machine. andyrozman, can you show the mount options as I asked (type mount)? I tried noacl, but that option has been removed in recent kernels.

Andrew, my suggestion is to change ENOTSUP to EOPNOTSUPP to fix Solaris & Co. and also blacklist EINVAL. Not sure about the skip logic. Could you please have a look? I'm trying to wrap up my Illumos stuff.

comment:21 in reply to: ↑ 20 Changed 9 hours ago by andrew_b

Replying to zaytsev:

Andrew, my suggestion is to change ENOTSUP to EOPNOTSUPP to fix Solaris & Co.

There is not a unanimity of ENOTSUP, EOPNOTSUPP and ENOSYS usage in the world. I'd propose to check them all.

and also blacklist EINVAL.

Where?

comment:22 Changed 5 hours ago by zaytsev

I agree to ignore ENOTSUP, EOPNOTSUPP, ENOSYS and EINVAL. Not nice, but apparently that's life.

comment:23 Changed 5 hours ago by zaytsev

  • Summary changed from VeraCrypt - Cannot get attributes of source directory - Invalid argument (22) to Extended attributes - Cannot get attributes of source directory - Invalid argument (22)

comment:24 Changed 29 minutes ago by andrew_b

  • Status changed from new to accepted
  • Owner set to andrew_b
  • Branch state changed from no branch to on review

Branch: 4590_ext2attr_errno
Initial changeset:d7f2e2515db7bfa6bb78e5f4c89f1801faacc0a9

Note: See TracTickets for help on using tickets.