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_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt) { __u32 mode; mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt); return mode; } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt); return 0; } else if (unlikely((mode & (reqmode)) != (reqmode))) return 0; return (reqmode); }
__u32 gr_acl_handle_creat(const struct dentry * dentry, const struct dentry * p_dentry, const struct vfsmount * p_mnt, int open_flags, int acc_mode, const int imode) { __u32 reqmode = GR_WRITE | GR_CREATE; __u32 mode; if (acc_mode & MAY_APPEND) reqmode |= GR_APPEND; // if a directory was required or the directory already exists, then // don't count this open as a read if ((acc_mode & MAY_READ) && !((open_flags & O_DIRECTORY) || d_is_dir(dentry))) reqmode |= GR_READ; if ((open_flags & O_CREAT) && ((imode & S_ISUID) || ((imode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)))) reqmode |= GR_SETID; mode = gr_check_create(dentry, p_dentry, p_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_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_CREATE_ACL_MSG, dentry, p_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_creat(const struct dentry * dentry, const struct dentry * p_dentry, const struct vfsmount * p_mnt, const int fmode, const int imode) { __u32 reqmode = GR_WRITE | GR_CREATE; __u32 mode; if (unlikely(fmode & O_APPEND)) reqmode |= GR_APPEND; if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) reqmode |= GR_READ; if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID)))) reqmode |= GR_SETID; mode = gr_check_create(dentry, p_dentry, p_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_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_CREATE_ACL_MSG, dentry, p_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_symlink(const struct dentry * new_dentry, const struct dentry * parent_dentry, const struct vfsmount * parent_mnt, const char *from) { __u32 needmode = GR_WRITE | GR_CREATE; __u32 mode; mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, GR_CREATE | GR_AUDIT_CREATE | GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS); if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) { gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); return mode; } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); return 0; } else if (unlikely((mode & needmode) != needmode)) return 0; return (GR_WRITE | GR_CREATE); }