mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
Use the gcc cleanup extension attribute to handle closing temp files
While some of these allocations will go away as we convert to C++, some of these need to stay C as the are going to be moved into a library to support loading cache from init daemons etc. For the bits that will eventually be C++ this helps clean things up, in the interim. TODO: apply to libapparmor as well Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Tyler Hicks <tyhicks@canonical.com>
This commit is contained in:
parent
82904cf0e6
commit
f62cc5c6bf
8 changed files with 39 additions and 36 deletions
|
@ -72,7 +72,8 @@ static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
|
||||||
fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "%s {", name);
|
fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "%s {", name);
|
||||||
|
|
||||||
if (S_ISREG(st->st_mode)) {
|
if (S_ISREG(st->st_mode)) {
|
||||||
int len, file;
|
autoclose int file = -1;
|
||||||
|
int len;
|
||||||
int remaining = fst->size - (fst->pos - *fst->buffer);
|
int remaining = fst->size - (fst->pos - *fst->buffer);
|
||||||
|
|
||||||
file = openat(dirfd(dir), name, O_RDONLY);
|
file = openat(dirfd(dir), name, O_RDONLY);
|
||||||
|
@ -98,7 +99,6 @@ static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
|
||||||
PDEBUG("Error reading feature file '%s'\n", name);
|
PDEBUG("Error reading feature file '%s'\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
close(file);
|
|
||||||
} else if (S_ISDIR(st->st_mode)) {
|
} else if (S_ISDIR(st->st_mode)) {
|
||||||
if (dirat_for_each(dir, name, fst, features_dir_cb))
|
if (dirat_for_each(dir, name, fst, features_dir_cb))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -124,7 +124,7 @@ static char *handle_features_dir(const char *filename, char **buffer, int size,
|
||||||
|
|
||||||
char *load_features_file(const char *name) {
|
char *load_features_file(const char *name) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
FILE *f = NULL;
|
autofclose FILE *f = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
f = fopen(name, "r");
|
f = fopen(name, "r");
|
||||||
|
@ -140,14 +140,11 @@ char *load_features_file(const char *name) {
|
||||||
goto fail;
|
goto fail;
|
||||||
buffer[size] = 0;
|
buffer[size] = 0;
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
int save = errno;
|
int save = errno;
|
||||||
free(buffer);
|
free(buffer);
|
||||||
if (f)
|
|
||||||
fclose(f);
|
|
||||||
errno = save;
|
errno = save;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
17
parser/lib.c
17
parser/lib.c
|
@ -40,6 +40,23 @@ void __autofree(void *p)
|
||||||
free(*_p);
|
free(*_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __autoclose(int *fd)
|
||||||
|
{
|
||||||
|
if (*fd != -1) {
|
||||||
|
/* if close was interrupted retry */
|
||||||
|
while(close(*fd) == -1 && errno == EINTR);
|
||||||
|
*fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __autofclose(FILE **f)
|
||||||
|
{
|
||||||
|
if (*f) {
|
||||||
|
fclose(*f);
|
||||||
|
*f = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dirat_for_each: iterate over a directory calling cb for each entry
|
* dirat_for_each: iterate over a directory calling cb for each entry
|
||||||
* @dir: already opened directory (MAY BE NULL)
|
* @dir: already opened directory (MAY BE NULL)
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
#define autofree __attribute((cleanup(__autofree)))
|
#define autofree __attribute((cleanup(__autofree)))
|
||||||
|
#define autoclose __attribute((cleanup(__autoclose)))
|
||||||
|
#define autofclose __attribute((cleanup(__autofclose)))
|
||||||
void __autofree(void *p);
|
void __autofree(void *p);
|
||||||
|
void __autoclose(int *fd);
|
||||||
|
void __autofclose(FILE **f);
|
||||||
|
|
||||||
int dirat_for_each(DIR *dir, const char *name, void *data,
|
int dirat_for_each(DIR *dir, const char *name, void *data,
|
||||||
int (* cb)(DIR *, const char *, struct stat *, void *));
|
int (* cb)(DIR *, const char *, struct stat *, void *));
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "parser_yacc.h"
|
#include "parser_yacc.h"
|
||||||
|
@ -154,7 +155,8 @@ static struct network_tuple network_mappings[] = {
|
||||||
static size_t kernel_af_max(void) {
|
static size_t kernel_af_max(void) {
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
int major;
|
int major;
|
||||||
int fd, res;
|
autoclose int fd = -1;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (!net_af_max_override) {
|
if (!net_af_max_override) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -168,7 +170,6 @@ static size_t kernel_af_max(void) {
|
||||||
/* fall back to default provided during build */
|
/* fall back to default provided during build */
|
||||||
return 0;
|
return 0;
|
||||||
res = read(fd, &buffer, sizeof(buffer) - 1);
|
res = read(fd, &buffer, sizeof(buffer) - 1);
|
||||||
close(fd);
|
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
buffer[res] = '\0';
|
buffer[res] = '\0';
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "parser_include.h"
|
#include "parser_include.h"
|
||||||
|
|
||||||
|
@ -176,7 +178,7 @@ int add_search_dir(const char *dir)
|
||||||
SUBDOMAIN_PATH=/etc/subdomain.d/include */
|
SUBDOMAIN_PATH=/etc/subdomain.d/include */
|
||||||
void parse_default_paths(void)
|
void parse_default_paths(void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
autofclose FILE *f;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *t, *s;
|
char *t, *s;
|
||||||
int saved_npath = npath;
|
int saved_npath = npath;
|
||||||
|
@ -202,7 +204,6 @@ void parse_default_paths(void)
|
||||||
} while (s != NULL);
|
} while (s != NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
/* if subdomain.conf doesn't set a base search dir set it to this */
|
/* if subdomain.conf doesn't set a base search dir set it to this */
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -479,7 +479,7 @@ void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile)
|
||||||
int cache_fd = -1;
|
int cache_fd = -1;
|
||||||
int __sd_serialize_profile(int option, Profile *prof)
|
int __sd_serialize_profile(int option, Profile *prof)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
autoclose int fd = -1;
|
||||||
int error = -ENOMEM, size, wsize;
|
int error = -ENOMEM, size, wsize;
|
||||||
std::ostringstream work_area;
|
std::ostringstream work_area;
|
||||||
autofree char *filename = NULL;
|
autofree char *filename = NULL;
|
||||||
|
@ -594,9 +594,6 @@ int __sd_serialize_profile(int option, Profile *prof)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
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) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -641,7 +638,7 @@ static int write_buffer(int fd, char *buffer, int size, bool set)
|
||||||
|
|
||||||
int sd_load_buffer(int option, char *buffer, int size)
|
int sd_load_buffer(int option, char *buffer, int size)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
autoclose int fd = -1;
|
||||||
int error, bsize;
|
int error, bsize;
|
||||||
autofree char *filename = NULL;
|
autofree char *filename = NULL;
|
||||||
|
|
||||||
|
@ -666,8 +663,7 @@ int sd_load_buffer(int option, char *buffer, int size)
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
PERROR(_("Unable to open %s - %s\n"), filename,
|
PERROR(_("Unable to open %s - %s\n"), filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
error = -errno;
|
return -errno;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kernel_supports_setload) {
|
if (kernel_supports_setload) {
|
||||||
|
@ -688,8 +684,6 @@ int sd_load_buffer(int option, char *buffer, int size)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(fd);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,7 +498,7 @@ static int process_args(int argc, char *argv[])
|
||||||
static int process_config_file(const char *name)
|
static int process_config_file(const char *name)
|
||||||
{
|
{
|
||||||
char *optarg;
|
char *optarg;
|
||||||
FILE *f;
|
autofclose FILE *f = NULL;
|
||||||
int c, o;
|
int c, o;
|
||||||
|
|
||||||
f = fopen(name, "r");
|
f = fopen(name, "r");
|
||||||
|
@ -507,7 +507,6 @@ static int process_config_file(const char *name)
|
||||||
|
|
||||||
while ((c = getopt_long_file(f, long_options, &optarg, &o)) != -1)
|
while ((c = getopt_long_file(f, long_options, &optarg, &o)) != -1)
|
||||||
process_arg(c, optarg);
|
process_arg(c, optarg);
|
||||||
fclose(f);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +552,7 @@ int have_enough_privilege(void)
|
||||||
|
|
||||||
static void set_features_by_match_file(void)
|
static void set_features_by_match_file(void)
|
||||||
{
|
{
|
||||||
FILE *ms = fopen(MATCH_FILE, "r");
|
autofclose FILE *ms = fopen(MATCH_FILE, "r");
|
||||||
if (ms) {
|
if (ms) {
|
||||||
autofree char *match_string = (char *) malloc(1000);
|
autofree char *match_string = (char *) malloc(1000);
|
||||||
if (!match_string)
|
if (!match_string)
|
||||||
|
@ -563,14 +562,10 @@ static void set_features_by_match_file(void)
|
||||||
if (strstr(match_string, " perms=c"))
|
if (strstr(match_string, " perms=c"))
|
||||||
perms_create = 1;
|
perms_create = 1;
|
||||||
kernel_supports_network = 1;
|
kernel_supports_network = 1;
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
no_match:
|
no_match:
|
||||||
perms_create = 1;
|
perms_create = 1;
|
||||||
|
|
||||||
out:
|
|
||||||
if (ms)
|
|
||||||
fclose(ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_supported_features(void) {
|
static void set_supported_features(void) {
|
||||||
|
@ -618,7 +613,7 @@ int process_binary(int option, const char *profilename)
|
||||||
autofree char *buffer = NULL;
|
autofree char *buffer = NULL;
|
||||||
int retval = 0, size = 0, asize = 0, rsize;
|
int retval = 0, size = 0, asize = 0, rsize;
|
||||||
int chunksize = 1 << 14;
|
int chunksize = 1 << 14;
|
||||||
int fd;
|
autoclose int fd = -1;
|
||||||
|
|
||||||
if (profilename) {
|
if (profilename) {
|
||||||
fd = open(profilename, O_RDONLY);
|
fd = open(profilename, O_RDONLY);
|
||||||
|
@ -648,8 +643,6 @@ int process_binary(int option, const char *profilename)
|
||||||
size += rsize;
|
size += rsize;
|
||||||
} while (rsize > 0);
|
} while (rsize > 0);
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (rsize == 0)
|
if (rsize == 0)
|
||||||
retval = sd_load_buffer(option, buffer, size);
|
retval = sd_load_buffer(option, buffer, size);
|
||||||
else
|
else
|
||||||
|
|
|
@ -40,13 +40,12 @@ const char header_string[] = "\004\010\000version\000\002";
|
||||||
bool valid_cached_file_version(const char *cachename)
|
bool valid_cached_file_version(const char *cachename)
|
||||||
{
|
{
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
FILE *f;
|
autofclose FILE *f;
|
||||||
if (!(f = fopen(cachename, "r"))) {
|
if (!(f = fopen(cachename, "r"))) {
|
||||||
PERROR(_("Error: Could not read cache file '%s', skipping...\n"), cachename);
|
PERROR(_("Error: Could not read cache file '%s', skipping...\n"), cachename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t res = fread(buffer, 1, 16, f);
|
size_t res = fread(buffer, 1, 16, f);
|
||||||
fclose(f);
|
|
||||||
if (res < 16) {
|
if (res < 16) {
|
||||||
if (debug_cache)
|
if (debug_cache)
|
||||||
pwarn("%s: cache file '%s' invalid size\n", progname, cachename);
|
pwarn("%s: cache file '%s' invalid size\n", progname, cachename);
|
||||||
|
@ -111,7 +110,7 @@ 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)
|
||||||
{
|
{
|
||||||
struct stat stat_file;
|
struct stat stat_file;
|
||||||
FILE * f = NULL;
|
autofclose FILE * f = NULL;
|
||||||
|
|
||||||
if (clear_cache_files(cachedir) != 0)
|
if (clear_cache_files(cachedir) != 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -122,9 +121,6 @@ create_file:
|
||||||
if (fwrite(features, strlen(features), 1, f) != 1 )
|
if (fwrite(features, strlen(features), 1, f) != 1 )
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue