^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AppArmor security module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file contains AppArmor file mediation function definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1998-2008 Novell/SUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright 2009-2010 Canonical Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #ifndef __AA_FILE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define __AA_FILE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "domain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "match.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "perms.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct aa_profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define mask_mode_t(X) (X & (MAY_EXEC | MAY_WRITE | MAY_READ | MAY_APPEND))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) AA_MAY_CREATE | AA_MAY_DELETE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) AA_MAY_GETATTR | AA_MAY_SETATTR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) AA_EXEC_MMAP | AA_MAY_LINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static inline struct aa_file_ctx *file_ctx(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return file->f_security + apparmor_blob_sizes.lbs_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* struct aa_file_ctx - the AppArmor context the file was opened in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @lock: lock to update the ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @label: label currently cached on the ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @perms: the permission the file was opened with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct aa_file_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct aa_label __rcu *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u32 allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * aa_alloc_file_ctx - allocate file_ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @label: initial label of task creating the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @gfp: gfp flags for allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Returns: file_ctx or NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static inline struct aa_file_ctx *aa_alloc_file_ctx(struct aa_label *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct aa_file_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ctx = kzalloc(sizeof(struct aa_file_ctx), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) spin_lock_init(&ctx->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) rcu_assign_pointer(ctx->label, aa_get_label(label));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * aa_free_file_ctx - free a file_ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @ctx: file_ctx to free (MAYBE_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static inline void aa_free_file_ctx(struct aa_file_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) aa_put_label(rcu_access_pointer(ctx->label));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) kfree_sensitive(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static inline struct aa_label *aa_get_file_label(struct aa_file_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return aa_get_label_rcu(&ctx->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * The xindex is broken into 3 parts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * - index - an index into either the exec name table or the variable table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * - exec type - which determines how the executable name and index are used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * - flags - which modify how the destination name is applied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define AA_X_INDEX_MASK 0x03ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define AA_X_TYPE_MASK 0x0c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define AA_X_TYPE_SHIFT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define AA_X_NONE 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define AA_X_NAME 0x0400 /* use executable name px */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define AA_X_TABLE 0x0800 /* use a specified name ->n# */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define AA_X_UNSAFE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define AA_X_CHILD 0x2000 /* make >AA_X_NONE apply to children */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define AA_X_INHERIT 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define AA_X_UNCONFINED 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* need to make conditional which ones are being set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct path_cond {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) umode_t mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* FIXME: split perms from dfa and match this to description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * also add delegation info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static inline u16 dfa_map_xindex(u16 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u16 old_index = (mask >> 10) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u16 index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (mask & 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) index |= AA_X_UNSAFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (mask & 0x200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) index |= AA_X_INHERIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (mask & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) index |= AA_X_UNCONFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (old_index == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) index |= AA_X_UNCONFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) } else if (old_index == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) index |= AA_X_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } else if (old_index == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) index |= AA_X_NAME | AA_X_CHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) } else if (old_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) index |= AA_X_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) index |= old_index - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * map old dfa inline permissions to new format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define dfa_user_allow(dfa, state) (((ACCEPT_TABLE(dfa)[state]) & 0x7f) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ((ACCEPT_TABLE(dfa)[state]) & 0x80000000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define dfa_user_audit(dfa, state) ((ACCEPT_TABLE2(dfa)[state]) & 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define dfa_user_quiet(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 7) & 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define dfa_user_xindex(dfa, state) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (dfa_map_xindex(ACCEPT_TABLE(dfa)[state] & 0x3fff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define dfa_other_allow(dfa, state) ((((ACCEPT_TABLE(dfa)[state]) >> 14) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 0x7f) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ((ACCEPT_TABLE(dfa)[state]) & 0x80000000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define dfa_other_audit(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 14) & 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define dfa_other_quiet(dfa, state) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ((((ACCEPT_TABLE2(dfa)[state]) >> 7) >> 14) & 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define dfa_other_xindex(dfa, state) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const char *op, u32 request, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) const char *target, struct aa_label *tlabel, kuid_t ouid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) const char *info, int error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * struct aa_file_rules - components used for file rule permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * @dfa: dfa to match path names and conditionals against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * @perms: permission table indexed by the matched state accept entry of @dfa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @trans: transition table for indexed by named x transitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * File permission are determined by matching a path against @dfa and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * then using the value of the accept entry for the matching state as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * an index into @perms. If a named exec transition is required it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * looked up in the transition table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct aa_file_rules {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned int start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct aa_dfa *dfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* struct perms perms; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct aa_domain trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* TODO: add delegate table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct path_cond *cond);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) const char *name, struct path_cond *cond,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct aa_perms *perms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int __aa_path_perm(const char *op, struct aa_profile *profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) const char *name, u32 request, struct path_cond *cond,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int flags, struct aa_perms *perms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int aa_path_perm(const char *op, struct aa_label *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) const struct path *path, int flags, u32 request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct path_cond *cond);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) const struct path *new_dir, struct dentry *new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u32 request, bool in_atomic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) void aa_inherit_files(const struct cred *cred, struct files_struct *files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static inline void aa_free_file_rules(struct aa_file_rules *rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) aa_put_dfa(rules->dfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) aa_free_domain_entries(&rules->trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * aa_map_file_perms - map file flags to AppArmor permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @file: open file to map flags to AppArmor permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Returns: apparmor permission set for the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static inline u32 aa_map_file_to_perms(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int flags = file->f_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u32 perms = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (file->f_mode & FMODE_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) perms |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (file->f_mode & FMODE_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) perms |= MAY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if ((flags & O_APPEND) && (perms & MAY_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) perms = (perms & ~MAY_WRITE) | MAY_APPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* trunc implies write permission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (flags & O_TRUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) perms |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (flags & O_CREAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) perms |= AA_MAY_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #endif /* __AA_FILE_H */