int gr_acl_handle_rename(struct dentry *new_dentry, struct dentry *parent_dentry, const struct vfsmount *parent_mnt, struct dentry *old_dentry, struct inode *old_parent_inode, struct vfsmount *old_mnt, const struct filename *newname, unsigned int flags) { __u32 comp1, comp2; int error = 0; if (unlikely(!gr_acl_is_enabled())) return 0; if (flags & RENAME_EXCHANGE) { comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE | GR_AUDIT_READ | GR_AUDIT_WRITE | GR_SUPPRESS, parent_mnt); comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | GR_AUDIT_READ | GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); } else if (d_is_negative(new_dentry)) { comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt, GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS); comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | GR_DELETE | GR_AUDIT_DELETE | GR_AUDIT_READ | GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); } else { comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE | GR_CREATE | GR_DELETE | GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_READ | GR_AUDIT_WRITE | GR_SUPPRESS, parent_mnt); comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | GR_AUDIT_READ | GR_DELETE | GR_AUDIT_DELETE | GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); } if (RENAME_CHECK_SUCCESS(comp1, comp2) && ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS))) gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name); else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS) && !(comp2 & GR_SUPPRESS)) { gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name); error = -EACCES; } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2))) error = -EACCES; return error; }
static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt) { __u32 mode; mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt); return mode; } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt); return 0; } else if (unlikely((mode & (reqmode)) != (reqmode))) return 0; return (reqmode); }
__u32 gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, const int fmode) { __u32 reqmode = GR_FIND; __u32 mode; if (unlikely(!dentry->d_inode)) return reqmode; if (unlikely(fmode & O_APPEND)) reqmode |= GR_APPEND; else if (unlikely(fmode & FMODE_WRITE)) reqmode |= GR_WRITE; if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) reqmode |= GR_READ; if ((fmode & FMODE_GREXEC) && (fmode & FMODE_EXEC)) reqmode &= ~GR_READ; mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : reqmode & GR_APPEND ? " appending" : ""); return reqmode; } else if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) { gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : reqmode & GR_APPEND ? " appending" : ""); return 0; } else if (unlikely((mode & reqmode) != reqmode)) return 0; return reqmode; }
__u32 gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, int acc_mode) { __u32 reqmode = GR_FIND; __u32 mode; if (unlikely(d_is_negative(dentry))) return reqmode; if (acc_mode & MAY_APPEND) reqmode |= GR_APPEND; else if (acc_mode & MAY_WRITE) reqmode |= GR_WRITE; if ((acc_mode & MAY_READ) && !d_is_dir(dentry)) reqmode |= GR_READ; mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : reqmode & GR_APPEND ? " appending" : ""); return reqmode; } else if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) { gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : reqmode & GR_APPEND ? " appending" : ""); return 0; } else if (unlikely((mode & reqmode) != reqmode)) return 0; return reqmode; }
__u32 gr_acl_handle_hidden_file(const struct dentry * dentry, const struct vfsmount * mnt) { __u32 mode; if (unlikely(!dentry->d_inode)) return GR_FIND; mode = gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt); if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) { gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); return mode; } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) { gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); return 0; } else if (unlikely(!(mode & GR_FIND))) return 0; return GR_FIND; }
__u32 gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt, const int fmode) { __u32 mode, reqmode = GR_FIND; if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode)) reqmode |= GR_EXEC; if (fmode & S_IWOTH) reqmode |= GR_WRITE; if (fmode & S_IROTH) reqmode |= GR_READ; mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : "", reqmode & GR_EXEC ? " executing" : ""); return reqmode; } else if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) { gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : "", reqmode & GR_EXEC ? " executing" : ""); return 0; } else if (unlikely((mode & reqmode) != reqmode)) return 0; return reqmode; }