@@ -198,6 +198,9 @@ When set to "0", hardlink creation behavior is unrestricted.
When set to "1" hardlinks cannot be created by users if they do not
already own the source file, or do not have read/write access to it.
+When set to "2" hardlinks cannot be created by users if they do not
+already own the source file.
+
This protection is based on the restrictions in Openwall and grsecurity.
==============================================================
@@ -1005,10 +1005,12 @@ static int may_linkat(struct path *link)
inode = link->dentry->d_inode;
- /* Source inode owner (or CAP_FOWNER) can hardlink all they like,
- * otherwise, it must be a safe source.
- */
- if (inode_owner_or_capable(inode) || safe_hardlink_source(inode))
+ /* Source inode owner (or CAP_FOWNER) can hardlink all they like. */
+ if (inode_owner_or_capable(inode))
+ return 0;
+
+ /* Otherwise, mode 1 allows a reasonable source. */
+ if (sysctl_protected_hardlinks < 2 && safe_hardlink_source(inode))
return 0;
audit_log_link_denied("linkat", link);
@@ -1778,7 +1778,7 @@ static struct ctl_table fs_table[] = {
.mode = 0600,
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
- .extra2 = &one,
+ .extra2 = &two,
},
{
.procname = "suid_dumpable",