Skip to content

Commit 214fa9f

Browse files
authored
Rollup merge of #101644 - Timmmm:file_permissions_docs, r=thomcc
Document surprising and dangerous fs::Permissions behaviour on Unix This documents the very surprising behaviour that `set_readonly(false)` will make a file *world writable* on Unix. I would go so far as to say that this function should be deprecated on Unix, or maybe even entirely. But documenting the bad behaviour is a good first step. Fixes #74895
2 parents acc269d + 908bdea commit 214fa9f

File tree

1 file changed

+64
-3
lines changed

1 file changed

+64
-3
lines changed

library/std/src/fs.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,34 @@ impl FileTimes {
13651365
impl Permissions {
13661366
/// Returns `true` if these permissions describe a readonly (unwritable) file.
13671367
///
1368+
/// # Note
1369+
///
1370+
/// This function does not take Access Control Lists (ACLs) or Unix group
1371+
/// membership into account.
1372+
///
1373+
/// # Windows
1374+
///
1375+
/// On Windows this returns [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants).
1376+
/// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail
1377+
/// but the user may still have permission to change this flag. If
1378+
/// `FILE_ATTRIBUTE_READONLY` is *not* set then writes may still fail due
1379+
/// to lack of write permission.
1380+
/// The behavior of this attribute for directories depends on the Windows
1381+
/// version.
1382+
///
1383+
/// # Unix (including macOS)
1384+
///
1385+
/// On Unix-based platforms this checks if *any* of the owner, group or others
1386+
/// write permission bits are set. It does not check if the current
1387+
/// user is in the file's assigned group. It also does not check ACLs.
1388+
/// Therefore even if this returns true you may not be able to write to the
1389+
/// file, and vice versa. The [`PermissionsExt`] trait gives direct access
1390+
/// to the permission bits but also does not read ACLs. If you need to
1391+
/// accurately know whether or not a file is writable use the `access()`
1392+
/// function from libc.
1393+
///
1394+
/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
1395+
///
13681396
/// # Examples
13691397
///
13701398
/// ```no_run
@@ -1390,8 +1418,40 @@ impl Permissions {
13901418
/// using the resulting `Permission` will update file permissions to allow
13911419
/// writing.
13921420
///
1393-
/// This operation does **not** modify the filesystem. To modify the
1394-
/// filesystem use the [`set_permissions`] function.
1421+
/// This operation does **not** modify the files attributes. This only
1422+
/// changes the in-memory value of these attributes for this `Permissions`
1423+
/// instance. To modify the files attributes use the [`set_permissions`]
1424+
/// function which commits these attribute changes to the file.
1425+
///
1426+
/// # Note
1427+
///
1428+
/// `set_readonly(false)` makes the file *world-writable* on Unix.
1429+
/// You can use the [`PermissionsExt`] trait on Unix to avoid this issue.
1430+
///
1431+
/// It also does not take Access Control Lists (ACLs) or Unix group
1432+
/// membership into account.
1433+
///
1434+
/// # Windows
1435+
///
1436+
/// On Windows this sets or clears [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants).
1437+
/// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail
1438+
/// but the user may still have permission to change this flag. If
1439+
/// `FILE_ATTRIBUTE_READONLY` is *not* set then the write may still fail if
1440+
/// the user does not have permission to write to the file.
1441+
///
1442+
/// In Windows 7 and earlier this attribute prevents deleting empty
1443+
/// directories. It does not prevent modifying the directory contents.
1444+
/// On later versions of Windows this attribute is ignored for directories.
1445+
///
1446+
/// # Unix (including macOS)
1447+
///
1448+
/// On Unix-based platforms this sets or clears the write access bit for
1449+
/// the owner, group *and* others, equivalent to `chmod a+w <file>`
1450+
/// or `chmod a-w <file>` respectively. The latter will grant write access
1451+
/// to all users! You can use the [`PermissionsExt`] trait on Unix
1452+
/// to avoid this issue.
1453+
///
1454+
/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
13951455
///
13961456
/// # Examples
13971457
///
@@ -1405,7 +1465,8 @@ impl Permissions {
14051465
///
14061466
/// permissions.set_readonly(true);
14071467
///
1408-
/// // filesystem doesn't change
1468+
/// // filesystem doesn't change, only the in memory state of the
1469+
/// // readonly permission
14091470
/// assert_eq!(false, metadata.permissions().readonly());
14101471
///
14111472
/// // just this particular `permissions`.

0 commit comments

Comments
 (0)