mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 18:17:09 +00:00
parser: Move policy cache functionality into policy_cache.c
Signed-off-by: John Johansen <john.johansen@canonical.com> [tyhicks: Fixed build failures] [tyhicks: Fixed bug where a warning was being printed when it shouldn't] [tyhicks: Forward ported to trunk] Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
This commit is contained in:
parent
4970d40e0d
commit
2a082ee543
@ -427,7 +427,7 @@ extern void free_aliases(void);
|
|||||||
extern int profile_merge_rules(Profile *prof);
|
extern int profile_merge_rules(Profile *prof);
|
||||||
|
|
||||||
/* parser_interface.c */
|
/* parser_interface.c */
|
||||||
extern int load_profile(int option, Profile *prof);
|
extern int load_profile(int option, Profile *prof, int cache_fd);
|
||||||
extern void sd_serialize_profile(std::ostringstream &buf, Profile *prof,
|
extern void sd_serialize_profile(std::ostringstream &buf, Profile *prof,
|
||||||
int flatten);
|
int flatten);
|
||||||
extern int sd_load_buffer(int option, char *buffer, int size);
|
extern int sd_load_buffer(int option, char *buffer, int size);
|
||||||
@ -448,9 +448,9 @@ extern int process_profile_policydb(Profile *prof);
|
|||||||
extern int post_merge_rules(void);
|
extern int post_merge_rules(void);
|
||||||
extern int merge_hat_rules(Profile *prof);
|
extern int merge_hat_rules(Profile *prof);
|
||||||
extern Profile *merge_policy(Profile *a, Profile *b);
|
extern Profile *merge_policy(Profile *a, Profile *b);
|
||||||
extern int load_policy(int option);
|
extern int load_policy(int option, int cache_fd);
|
||||||
extern int load_hats(std::ostringstream &buf, Profile *prof);
|
extern int load_hats(std::ostringstream &buf, Profile *prof);
|
||||||
extern int load_flattened_hats(Profile *prof, int option);
|
extern int load_flattened_hats(Profile *prof, int option, int cache_fd);
|
||||||
extern void dump_policy_hats(Profile *prof);
|
extern void dump_policy_hats(Profile *prof);
|
||||||
extern void dump_policy_names(void);
|
extern void dump_policy_names(void);
|
||||||
void dump_policy(void);
|
void dump_policy(void);
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#define SD_STR_LEN (sizeof(u16))
|
#define SD_STR_LEN (sizeof(u16))
|
||||||
|
|
||||||
|
|
||||||
int __sd_serialize_profile(int option, Profile *prof);
|
int __sd_serialize_profile(int option, Profile *prof, int cache_fd);
|
||||||
|
|
||||||
static void print_error(int error)
|
static void print_error(int error)
|
||||||
{
|
{
|
||||||
@ -83,13 +83,13 @@ static void print_error(int error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_profile(int option, Profile *prof)
|
int load_profile(int option, Profile *prof, int cache_fd)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
PDEBUG("Serializing policy for %s.\n", prof->name);
|
PDEBUG("Serializing policy for %s.\n", prof->name);
|
||||||
retval = __sd_serialize_profile(option, prof);
|
retval = __sd_serialize_profile(option, prof, cache_fd);
|
||||||
|
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
error = retval; /* yeah, we'll just report the last error */
|
error = retval; /* yeah, we'll just report the last error */
|
||||||
@ -475,8 +475,7 @@ void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile)
|
|||||||
sd_serialize_profile(buf, profile, profile->parent ? 1 : 0);
|
sd_serialize_profile(buf, profile, profile->parent ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cache_fd = -1;
|
int __sd_serialize_profile(int option, Profile *prof, int cache_fd)
|
||||||
int __sd_serialize_profile(int option, Profile *prof)
|
|
||||||
{
|
{
|
||||||
autoclose int fd = -1;
|
autoclose int fd = -1;
|
||||||
int error = -ENOMEM, size, wsize;
|
int error = -ENOMEM, size, wsize;
|
||||||
@ -555,7 +554,7 @@ int __sd_serialize_profile(int option, Profile *prof)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!prof->hat_table.empty() && option != OPTION_REMOVE) {
|
if (!prof->hat_table.empty() && option != OPTION_REMOVE) {
|
||||||
if (load_flattened_hats(prof, option) == 0)
|
if (load_flattened_hats(prof, option, cache_fd) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,10 +695,10 @@ int test_for_dir_mode(const char *basename, const char *linkdir)
|
|||||||
|
|
||||||
int process_profile(int option, const char *profilename)
|
int process_profile(int option, const char *profilename)
|
||||||
{
|
{
|
||||||
struct stat stat_bin;
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
autofree char *cachename = NULL;
|
autofree const char *cachename = NULL;
|
||||||
autofree char *cachetemp = NULL;
|
autofree const char *cachetmpname = NULL;
|
||||||
|
autoclose int cachetmp = -1;
|
||||||
const char *basename = NULL;
|
const char *basename = NULL;
|
||||||
|
|
||||||
/* per-profile states */
|
/* per-profile states */
|
||||||
@ -737,24 +737,8 @@ int process_profile(int option, const char *profilename)
|
|||||||
|
|
||||||
/* setup cachename and tstamp */
|
/* setup cachename and tstamp */
|
||||||
if (!force_complain && !skip_cache) {
|
if (!force_complain && !skip_cache) {
|
||||||
if (asprintf(&cachename, "%s/%s", cacheloc, basename)<0) {
|
cachename = cache_filename(cacheloc, basename);
|
||||||
PERROR(_("Memory allocation error."));
|
valid_read_cache(cachename);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (!skip_read_cache) {
|
|
||||||
if (stat(cachename, &stat_bin) == 0 &&
|
|
||||||
stat_bin.st_size > 0) {
|
|
||||||
if (valid_cached_file_version(cachename))
|
|
||||||
set_mru_tstamp(stat_bin.st_ctim);
|
|
||||||
else if (!cond_clear_cache)
|
|
||||||
write_cache = 0;
|
|
||||||
} else {
|
|
||||||
if (!cond_clear_cache)
|
|
||||||
write_cache = 0;
|
|
||||||
if (debug_cache)
|
|
||||||
pwarn("%s: Invalid or missing cache file '%s' (%s)\n", progname, cachename, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -773,36 +757,20 @@ int process_profile(int option, const char *profilename)
|
|||||||
* TODO: Add support for caching profiles in an alternate namespace
|
* TODO: Add support for caching profiles in an alternate namespace
|
||||||
* TODO: Add support for embedded namespace defines if they aren't
|
* TODO: Add support for embedded namespace defines if they aren't
|
||||||
* removed from the language.
|
* removed from the language.
|
||||||
|
* TODO: test profile->ns NOT profile_ns (must be after parse)
|
||||||
*/
|
*/
|
||||||
if (profile_ns)
|
if (profile_ns)
|
||||||
skip_cache = 1;
|
skip_cache = 1;
|
||||||
|
|
||||||
/* Do secondary test to see if cached binary profile is good,
|
|
||||||
* instead of checking against a presupplied list of files
|
|
||||||
* use the timestamps from the files that were parsed.
|
|
||||||
* Parsing the profile is slower that doing primary cache check
|
|
||||||
* its still faster than doing full compilation
|
|
||||||
*/
|
|
||||||
if (cachename) {
|
if (cachename) {
|
||||||
/* Load a binary cache if it exists and is newest */
|
/* Load a binary cache if it exists and is newest */
|
||||||
if (!mru_skip_cache) {
|
if (cache_hit(cachename)) {
|
||||||
if (show_cache)
|
|
||||||
PERROR("Cache hit: %s\n", cachename);
|
|
||||||
retval = process_binary(option, cachename);
|
retval = process_binary(option, cachename);
|
||||||
if (!retval || skip_bad_cache_rebuild)
|
if (!retval || skip_bad_cache_rebuild)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
if (write_cache) {
|
|
||||||
/* Otherwise, set up to save a cached copy */
|
cachetmp = setup_cache_tmp(&cachetmpname, cachename);
|
||||||
if (asprintf(&cachetemp, "%s-XXXXXX", cachename)<0) {
|
|
||||||
perror("asprintf");
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
if ( (cache_fd = mkstemp(cachetemp)) < 0) {
|
|
||||||
perror("mkstemp");
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_cache)
|
if (show_cache)
|
||||||
@ -838,32 +806,18 @@ int process_profile(int option, const char *profilename)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = load_policy(option);
|
/* cache file generated by load_policy */
|
||||||
|
retval = load_policy(option, cachetmp);
|
||||||
|
if (retval == 0 && write_cache) {
|
||||||
|
if (cachetmp == -1) {
|
||||||
|
unlink(cachetmpname);
|
||||||
|
PERROR("Warning failed to create cache: %s\n",
|
||||||
|
basename);
|
||||||
|
} else {
|
||||||
|
install_cache(cachetmpname, cachename);
|
||||||
|
}
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
if (cachetemp) {
|
|
||||||
/* Only install the generate cache file if it parsed correctly
|
|
||||||
and did not have write/close errors */
|
|
||||||
int useable_cache = (cache_fd != -1 && retval == 0);
|
|
||||||
if (cache_fd != -1) {
|
|
||||||
if (close(cache_fd))
|
|
||||||
useable_cache = 0;
|
|
||||||
cache_fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useable_cache) {
|
|
||||||
if (rename(cachetemp, cachename) < 0) {
|
|
||||||
pwarn("Warning failed to write cache: %s\n", cachename);
|
|
||||||
unlink(cachetemp);
|
|
||||||
}
|
|
||||||
else if (show_cache)
|
|
||||||
PERROR("Wrote cache: %s\n", cachename);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unlink(cachetemp);
|
|
||||||
PERROR("Warning failed to create cache: %s\n", basename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -220,12 +220,12 @@ static int profile_add_hat_rules(Profile *prof)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_policy_list(ProfileList &list, int option)
|
int load_policy_list(ProfileList &list, int option, int cache_fd)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
for (ProfileList::iterator i = list.begin(); i != list.end(); i++) {
|
for (ProfileList::iterator i = list.begin(); i != list.end(); i++) {
|
||||||
res = load_profile(option, *i);
|
res = load_profile(option, *i, cache_fd);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -233,14 +233,14 @@ int load_policy_list(ProfileList &list, int option)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_flattened_hats(Profile *prof, int option)
|
int load_flattened_hats(Profile *prof, int option, int cache_fd)
|
||||||
{
|
{
|
||||||
return load_policy_list(prof->hat_table, option);
|
return load_policy_list(prof->hat_table, option, cache_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_policy(int option)
|
int load_policy(int option, int cache_fd)
|
||||||
{
|
{
|
||||||
return load_policy_list(policy_list, option);
|
return load_policy_list(policy_list, option, cache_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_hats(std::ostringstream &buf, Profile *prof)
|
int load_hats(std::ostringstream &buf, Profile *prof)
|
||||||
|
@ -145,3 +145,84 @@ error:
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *cache_filename(const char *cacheloc, const char *basename)
|
||||||
|
{
|
||||||
|
char *cachename;
|
||||||
|
|
||||||
|
if (asprintf(&cachename, "%s/%s", cacheloc, basename) < 0) {
|
||||||
|
PERROR(_("Memory allocation error."));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void valid_read_cache(const char *cachename)
|
||||||
|
{
|
||||||
|
struct stat stat_bin;
|
||||||
|
|
||||||
|
/* Load a binary cache if it exists and is newest */
|
||||||
|
if (!skip_read_cache) {
|
||||||
|
if (stat(cachename, &stat_bin) == 0 &&
|
||||||
|
stat_bin.st_size > 0) {
|
||||||
|
if (valid_cached_file_version(cachename))
|
||||||
|
set_mru_tstamp(stat_bin.st_ctim);
|
||||||
|
else if (!cond_clear_cache)
|
||||||
|
write_cache = 0;
|
||||||
|
} else {
|
||||||
|
if (!cond_clear_cache)
|
||||||
|
write_cache = 0;
|
||||||
|
if (debug_cache)
|
||||||
|
pwarn("%s: Invalid or missing cache file '%s' (%s)\n", progname, cachename, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cache_hit(const char *cachename)
|
||||||
|
{
|
||||||
|
if (!mru_skip_cache) {
|
||||||
|
if (show_cache)
|
||||||
|
PERROR("Cache hit: %s\n", cachename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setup_cache_tmp(const char **cachetmpname, const char *cachename)
|
||||||
|
{
|
||||||
|
char *tmpname;
|
||||||
|
int cache_fd = -1;
|
||||||
|
|
||||||
|
*cachetmpname = NULL;
|
||||||
|
if (write_cache) {
|
||||||
|
/* Otherwise, set up to save a cached copy */
|
||||||
|
if (asprintf(&tmpname, "%s-XXXXXX", cachename)<0) {
|
||||||
|
perror("asprintf");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((cache_fd = mkstemp(tmpname)) < 0) {
|
||||||
|
perror("mkstemp");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*cachetmpname = tmpname;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void install_cache(const char *cachetmpname, const char *cachename)
|
||||||
|
{
|
||||||
|
/* Only install the generate cache file if it parsed correctly
|
||||||
|
and did not have write/close errors */
|
||||||
|
if (cachetmpname) {
|
||||||
|
if (rename(cachetmpname, cachename) < 0) {
|
||||||
|
pwarn("Warning failed to write cache: %s\n", cachename);
|
||||||
|
unlink(cachetmpname);
|
||||||
|
}
|
||||||
|
else if (show_cache) {
|
||||||
|
PERROR("Wrote cache: %s\n", cachename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -41,5 +41,10 @@ void update_mru_tstamp(FILE *file, const char *path);
|
|||||||
bool valid_cached_file_version(const char *cachename);
|
bool valid_cached_file_version(const char *cachename);
|
||||||
int clear_cache_files(const char *path);
|
int clear_cache_files(const char *path);
|
||||||
int create_cache(const char *cachedir, const char *path, const char *features);
|
int create_cache(const char *cachedir, const char *path, const char *features);
|
||||||
|
char *cache_filename(const char *cacheloc, const char *basename);
|
||||||
|
void valid_read_cache(const char *cachename);
|
||||||
|
int cache_hit(const char *cachename);
|
||||||
|
int setup_cache_tmp(const char **cachetmpname, const char *cachename);
|
||||||
|
void install_cache(const char *cachetmpname, const char *cachename);
|
||||||
|
|
||||||
#endif /* __AA_POLICY_CACHE_H */
|
#endif /* __AA_POLICY_CACHE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user