|
22 | 22 | * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
23 | 23 | * Copyright 2016 Joyent, Inc.
|
24 | 24 | * Copyright (c) 2016 by Delphix. All rights reserved.
|
| 25 | + * Copyright 2022 Oxide Computer Company |
25 | 26 | */
|
26 | 27 |
|
27 | 28 | #include <sys/types.h>
|
|
67 | 68 | int priv_debug = 0;
|
68 | 69 | int priv_basic_test = -1;
|
69 | 70 |
|
| 71 | +/* |
| 72 | + * Unlinking or creating new hard links to directories was historically allowed |
| 73 | + * in some file systems; e.g., UFS allows root users to do it, at the cost of |
| 74 | + * almost certain file system corruption that will require fsck to fix. |
| 75 | + * |
| 76 | + * Most modern operating systems and file systems (e.g., ZFS) do not allow this |
| 77 | + * behaviour anymore, and we have elected to stamp it out entirely for |
| 78 | + * compatibility and safety reasons. An attempt to unlink a directory will |
| 79 | + * fail with EPERM, as described in the standard. During this transition, one |
| 80 | + * can turn the behaviour back on, at their own risk, with this tuneable: |
| 81 | + */ |
| 82 | +int priv_allow_linkdir = 0; |
| 83 | + |
70 | 84 | /*
|
71 | 85 | * This file contains the majority of the policy routines.
|
72 | 86 | * Since the policy routines are defined by function and not
|
@@ -895,6 +909,23 @@ secpolicy_fs_config(const cred_t *cr, const vfs_t *vfsp)
|
895 | 909 | int
|
896 | 910 | secpolicy_fs_linkdir(const cred_t *cr, const vfs_t *vfsp)
|
897 | 911 | {
|
| 912 | + if (priv_allow_linkdir == 0) { |
| 913 | + /* |
| 914 | + * By default, this policy check will now always return EPERM |
| 915 | + * unless overridden. |
| 916 | + * |
| 917 | + * We do so without triggering auditing or allowing privilege |
| 918 | + * debugging for two reasons: first, we intend eventually to |
| 919 | + * deprecate the PRIV_SYS_LINKDIR privilege entirely and remove |
| 920 | + * the use of this policy check from the file systems; second, |
| 921 | + * for privilege debugging in particular, because it would be |
| 922 | + * confusing to report an unlink() failure as the result of a |
| 923 | + * missing privilege when in fact we are simply no longer |
| 924 | + * allowing the operation at all. |
| 925 | + */ |
| 926 | + return (EPERM); |
| 927 | + } |
| 928 | + |
898 | 929 | return (PRIV_POLICY(cr, PRIV_SYS_LINKDIR, B_FALSE, EPERM, NULL));
|
899 | 930 | }
|
900 | 931 |
|
|
0 commit comments