apparmor/parser/libapparmor_re/aare_rules.h
Ryan Lee 81950dae4e Fix memory leak in aare_rules UniquePermsCache
When the find fails but the insertion also fails, we leak the new node
that we generated. Delete the new node in this case to avoid leaking
memory.

Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
2024-10-28 12:23:17 +01:00

139 lines
3.9 KiB
C++

/*
* (C) 2006, 2007 Andreas Gruenbacher <agruen@suse.de>
* Copyright (c) 2003-2008 Novell, Inc. (All rights reserved)
* Copyright 2009-2012 Canonical Ltd.
*
* The libapparmor library is licensed under the terms of the GNU
* Lesser General Public License, version 2.1. Please see the file
* COPYING.LGPL.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* Wrapper around the dfa to convert aa rules into a dfa
*/
#ifndef __LIBAA_RE_RULES_H
#define __LIBAA_RE_RULES_H
#include <vector>
#include <stdint.h>
#include "../common_optarg.h"
#include "apparmor_re.h"
#include "chfa.h"
#include "expr-tree.h"
#include "../immunix.h"
#include "../perms.h"
#include "../rule.h"
class UniquePerm {
public:
int priority;
rule_mode_t mode;
bool exact_match;
uint32_t perms;
uint32_t audit;
bool operator<(UniquePerm const &rhs)const
{
if (priority < rhs.priority)
return priority < rhs.priority;
if (mode >= rhs.mode) {
if (exact_match == rhs.exact_match) {
if (perms == rhs.perms)
return audit < rhs.audit;
return perms < rhs.perms;
}
return exact_match;
}
return true; // mode < rhs.mode
}
};
class UniquePermsCache {
public:
typedef map<UniquePerm, Node*> UniquePermMap;
typedef UniquePermMap::iterator iterator;
UniquePermMap nodes;
UniquePermsCache(void) { };
~UniquePermsCache() { clear(); }
void clear()
{
for (iterator i = nodes.begin(); i != nodes.end(); i++) {
delete i->second;
}
nodes.clear();
}
Node *insert(int priority, rule_mode_t mode, uint32_t perms,
uint32_t audit, bool exact_match)
{
UniquePerm tmp = { priority, mode, exact_match, perms, audit };
iterator res = nodes.find(tmp);
if (res == nodes.end()) {
Node *node;
if (mode == RULE_DENY)
node = new DenyMatchFlag(priority, perms, audit);
else if (mode == RULE_PROMPT)
node = new PromptMatchFlag(priority, perms, audit);
else if (exact_match)
node = new ExactMatchFlag(priority, perms, audit);
else
node = new MatchFlag(priority, perms, audit);
pair<iterator, bool> val = nodes.insert(make_pair(tmp, node));
if (val.second == false) {
delete node;
return val.first->second;
}
return node;
}
return res->second;
}
};
typedef std::map<Node *, Node *> PermExprMap;
class aare_rules {
Node *root;
void add_to_rules(Node *tree, Node *perms);
UniquePermsCache unique_perms;
PermExprMap expr_map;
public:
int reverse;
int rule_count;
aare_rules(void): root(NULL), unique_perms(), expr_map(), reverse(0), rule_count(0) { };
aare_rules(int reverse): root(NULL), unique_perms(), expr_map(), reverse(reverse), rule_count(0) { };
~aare_rules();
bool add_rule(const char *rule, int priority, rule_mode_t mode,
perm32_t perms, perm32_t audit, optflags const &opts);
bool add_rule_vec(int priority, rule_mode_t mode, perm32_t perms,
perm32_t audit, int count, const char **rulev,
optflags const &opts, bool oob);
bool append_rule(const char *rule, bool oob, bool with_perm, optflags const &opts);
CHFA *create_chfa(int *min_match_len,
vector <aa_perms> &perms_table,
optflags const &opts, bool filedfa,
bool extended_perms, bool prompt);
void *create_dfablob(size_t *size, int *min_match_len,
vector <aa_perms> &perms_table,
optflags const &opts,
bool filedfa, bool extended_perms, bool prompt);
void *create_welded_dfablob(aare_rules *file_rules,
size_t *size, int *min_match_len,
size_t *new_start,
vector <aa_perms> &perms_table,
optflags const &opts,
bool extended_perms, bool prompt);
};
#endif /* __LIBAA_RE_RULES_H */