summaryrefslogtreecommitdiff
path: root/security/apparmor/include/file.h
blob: 5be620af33ba0a2ba86f6d0d0dce7462cf3fc538 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * AppArmor security module
 *
 * This file contains AppArmor file mediation function definitions.
 *
 * Copyright (C) 1998-2008 Novell/SUSE
 * Copyright 2009-2010 Canonical Ltd.
 */

#ifndef __AA_FILE_H
#define __AA_FILE_H

#include <linux/spinlock.h>

#include "domain.h"
#include "match.h"
#include "perms.h"

struct aa_policydb;
struct aa_profile;
struct path;

#define mask_mode_t(X) (X & (MAY_EXEC | MAY_WRITE | MAY_READ | MAY_APPEND))

#define AA_AUDIT_FILE_MASK	(MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
				 AA_MAY_CREATE | AA_MAY_DELETE |	\
				 AA_MAY_GETATTR | AA_MAY_SETATTR | \
				 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
				 AA_EXEC_MMAP | AA_MAY_LINK)

static inline struct aa_file_ctx *file_ctx(struct file *file)
{
	return file->f_security + apparmor_blob_sizes.lbs_file;
}

/* struct aa_file_ctx - the AppArmor context the file was opened in
 * @lock: lock to update the ctx
 * @label: label currently cached on the ctx
 * @perms: the permission the file was opened with
 */
struct aa_file_ctx {
	spinlock_t lock;
	struct aa_label __rcu *label;
	u32 allow;
};

/**
 * aa_alloc_file_ctx - allocate file_ctx
 * @label: initial label of task creating the file
 * @gfp: gfp flags for allocation
 *
 * Returns: file_ctx or NULL on failure
 */
static inline struct aa_file_ctx *aa_alloc_file_ctx(struct aa_label *label,
						    gfp_t gfp)
{
	struct aa_file_ctx *ctx;

	ctx = kzalloc(sizeof(struct aa_file_ctx), gfp);
	if (ctx) {
		spin_lock_init(&ctx->lock);
		rcu_assign_pointer(ctx->label, aa_get_label(label));
	}
	return ctx;
}

/**
 * aa_free_file_ctx - free a file_ctx
 * @ctx: file_ctx to free  (MAYBE_NULL)
 */
static inline void aa_free_file_ctx(struct aa_file_ctx *ctx)
{
	if (ctx) {
		aa_put_label(rcu_access_pointer(ctx->label));
		kfree_sensitive(ctx);
	}
}

static inline struct aa_label *aa_get_file_label(struct aa_file_ctx *ctx)
{
	return aa_get_label_rcu(&ctx->label);
}

/*
 * The xindex is broken into 3 parts
 * - index - an index into either the exec name table or the variable table
 * - exec type - which determines how the executable name and index are used
 * - flags - which modify how the destination name is applied
 */
#define AA_X_INDEX_MASK		AA_INDEX_MASK

#define AA_X_TYPE_MASK		0x0c000000
#define AA_X_NONE		AA_INDEX_NONE
#define AA_X_NAME		0x04000000 /* use executable name px */
#define AA_X_TABLE		0x08000000 /* use a specified name ->n# */

#define AA_X_UNSAFE		0x10000000
#define AA_X_CHILD		0x20000000
#define AA_X_INHERIT		0x40000000
#define AA_X_UNCONFINED		0x80000000

/* need to make conditional which ones are being set */
struct path_cond {
	kuid_t uid;
	umode_t mode;
};

#define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)

int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
		  const char *op, u32 request, const char *name,
		  const char *target, struct aa_label *tlabel, kuid_t ouid,
		  const char *info, int error);

struct aa_perms *aa_lookup_fperms(struct aa_policydb *file_rules,
				  aa_state_t state, struct path_cond *cond);
aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start,
			const char *name, struct path_cond *cond,
			struct aa_perms *perms);

int aa_path_perm(const char *op, struct aa_label *label,
		 const struct path *path, int flags, u32 request,
		 struct path_cond *cond);

int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
		 const struct path *new_dir, struct dentry *new_dentry);

int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
		 u32 request, bool in_atomic);

void aa_inherit_files(const struct cred *cred, struct files_struct *files);


/**
 * aa_map_file_perms - map file flags to AppArmor permissions
 * @file: open file to map flags to AppArmor permissions
 *
 * Returns: apparmor permission set for the file
 */
static inline u32 aa_map_file_to_perms(struct file *file)
{
	int flags = file->f_flags;
	u32 perms = 0;

	if (file->f_mode & FMODE_WRITE)
		perms |= MAY_WRITE;
	if (file->f_mode & FMODE_READ)
		perms |= MAY_READ;

	if ((flags & O_APPEND) && (perms & MAY_WRITE))
		perms = (perms & ~MAY_WRITE) | MAY_APPEND;
	/* trunc implies write permission */
	if (flags & O_TRUNC)
		perms |= MAY_WRITE;
	if (flags & O_CREAT)
		perms |= AA_MAY_CREATE;

	return perms;
}

#endif /* __AA_FILE_H */