int gr_handle_hardlink(const struct dentry *dentry, const struct vfsmount *mnt, struct inode *inode, const int mode, const char *to) { #ifdef CONFIG_GRKERNSEC_LINK const struct cred *cred = current_cred(); if (grsec_enable_link && cred->fsuid != inode->i_uid && (!S_ISREG(mode) || (mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) || (inode_permission(inode, MAY_READ | MAY_WRITE))) && !capable(CAP_FOWNER) && cred->uid) { gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to); return -EPERM; } #endif return 0; }
int gr_handle_hardlink(const struct dentry *dentry, const struct vfsmount *mnt, const struct filename *to) { #ifdef CONFIG_GRKERNSEC_LINK struct inode *inode = d_backing_inode(dentry); const struct cred *cred = current_cred(); if (grsec_enable_link && !uid_eq(cred->fsuid, inode->i_uid) && (!d_is_reg(dentry) || is_privileged_binary(dentry) || (inode_permission(inode, MAY_READ | MAY_WRITE))) && !capable(CAP_FOWNER) && gr_is_global_nonroot(cred->uid)) { gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to->name); return -EPERM; } #endif return 0; }