43

I believe that the FAT32 file system does not support file permissions, however when I do ls -l on a FAT32 partition, ls -l shows that the files have permissions:

-rw-r--r-- 1 john john 11 Mar 20 15:43 file1.txt
-rw-r--r-- 1 john john 5 Mar 20 15:49 file2.txt

Why is ls -l displaying the permissions of files?

  • Good question! Welcome – 0xSheepdog Mar 28 '19 at 22:43
75

The filesystem as stored on disk doesn't store all file permissions, but the filesystem driver has to provide them to the operating system since they are an integral part of the Unix filesystem concept and the system call interfaces have no way of presenting that the permissions are missing.

Also consider what would happen if a file didn't have any permission bits at all? Would it be the same as 0777, i.e. access to all; or the same as 0000, i.e. no access to anyone? But both of those are file permissions, so why not show them? Or do something more useful and have a way to set some sensible permissions.

So, the driver fakes some permissions, mostly same ones for all files. The permissions along with the files' owner and group are configurable at mount time. These are described under "Mount options for fat" in the mount(8) man page:

Mount options for fat
(Note: fat is not a separate filesystem, but a common part of the msdos, umsdos and vfat filesystems.)

uid=value and gid=value
Set the owner and group of all files. (Default: the UID and GID of the current process.)

umask=value
Set the umask (the bitmask of the permissions that are not present). The default is the umask of the current process. The value is given in octal.

dmask=value
Set the umask applied to directories only. The default is the umask of the current process. The value is given in octal.

fmask=value
Set the umask applied to regular files only. The default is the umask of the current process. The value is given in octal.

Note that the one useful permission the FAT filesystems store is the read-only -bit, and if you run chmod ugo-w file, the read permissions on it will disappear.

That's also probably the reason that the above options take their values as permissions to masks away, so fmask=0133 would result in all files having all the x permissions removed and w removed from the group and others. The files would then have the permissions 0644/rw-r--r-- or 0444/r--r--r--, depending on if the read-only bit is cleared or set.

Also, the defaults are inherited from the process calling mount(), so if you call mount from the command line, the shell's umask will apply.

| improve this answer | |
  • 7
    And the reason it does fake the permissions is that otherwise ls, and any other program that looked at file permissions (even just your code trying to read a file) would have to have the logic to handle all the different file system organizations built in. – jamesqf Mar 20 '19 at 16:50
  • 5
    @jamesqf, yes, and even the system call interfaces don't have the option of "not having permissions", since the permissions have always been there. (That was what I was thinking when I wrote they're an "integral part".) Therefore, the permissions always shall be there, too, and things like ACLs are made so as to keep them meaningful. – ilkkachu Mar 20 '19 at 16:59
  • 2
    I've usually seen mode 777 for all files in FAT filesystems (FAT16 with an old driver, at least). – forest Mar 21 '19 at 20:13
  • 2
    @forest that depends on umask mount option, for which the default value is umask of mount process (see the man page linked to in this answer). – Ruslan Mar 22 '19 at 14:21
  • But FAT does store some permissions/attributes (read-only, hidden, system, etc), even if they do not map exactly to the Unix ones. chmod ugo-w on a file will turn the read-only attribute on. Using the fmask=0133 option as in your example will not result in all files having the 0644 permission. What FAT absolutely does not store is a uid and a gid for each file. Please clarify; the answer as it stands is highly misleading. – mosvy Mar 23 '19 at 9:24
24

But the files do have permissions. User john has RW access, while some random user only has read access. These permissions didn’t come from the filesystem itself but rather from mount options (-o uid/gid/umask), which doesn’t make them any less real.

You could have multiple vfat partitions mounted with different options and you could use ls to determine what those options were. You could even use mount --bind to have a single directory contain files from different vfat partitions, and ls would correctly show what permissions have been specified for each file.

| improve this answer | |
16

ls doesn't know about FAT32, it only knows about the Virtual Filesystem (VFS) interface exposed by the kernel with POSIX open / readdir / stat system calls.

Linux doesn't support the concept of files that don't have user/group/other permission bits, struct stat simply contains a mode_t st_mode; member (and uid, gid members) that the kernel must fill out when ls -l makes stat(2) system calls.

There's no special code that means "not available" or "not applicable" for any of those fields, so the kernel's vfat driver must make something up. FAT16/FAT32 does have a read-only flag, but otherwise the owner/group come from mount options, and so does a umask.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.