mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 06:16:03 +00:00
parser: Shove binary file and fd reading into kernel_interface.c
This is the start of the kernel_interface API that allows callers to specify a buffer, a file path, or a file descriptor that should be copied to the proper kernel interface for loading, replacing, or removing in-kernel policies. Support exists for reading from a file path or file descriptor into a buffer and then writing that buffer to the appropriate apparmorfs interface file. An aa_kernel_interface_write_policy() function is also provided for callers that want to route a buffer to an arbitrary file descriptor instead of to an apparmorfs file. This is useful when an admin instructs apparmor_parser to write to stdout or a file. Additionally, it removes some parser-specific globals from the kernel_interface.c file, such as OPTION_{ADD,REPLACE,REMOVE}, in preparation for moving the code into a library. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
@@ -605,62 +605,55 @@ static void set_supported_features(void)
|
||||
|
||||
int process_binary(int option, const char *profilename)
|
||||
{
|
||||
autofree char *buffer = NULL;
|
||||
int retval = 0, size = 0, asize = 0, rsize;
|
||||
int chunksize = 1 << 14;
|
||||
autoclose int fd = -1;
|
||||
const char *printed_name;
|
||||
int retval;
|
||||
|
||||
if (profilename) {
|
||||
fd = open(profilename, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
retval = errno;
|
||||
PERROR(_("Error: Could not read binary profile or cache file %s: %s.\n"),
|
||||
profilename, strerror(errno));
|
||||
return retval;
|
||||
}
|
||||
} else {
|
||||
fd = dup(0);
|
||||
}
|
||||
printed_name = profilename ? profilename : "stdin";
|
||||
|
||||
do {
|
||||
if (asize - size == 0) {
|
||||
buffer = (char *) realloc(buffer, chunksize);
|
||||
asize = chunksize;
|
||||
chunksize <<= 1;
|
||||
if (!buffer) {
|
||||
PERROR(_("Memory allocation error."));
|
||||
return ENOMEM;
|
||||
if (kernel_load) {
|
||||
if (option == OPTION_ADD) {
|
||||
retval = profilename ?
|
||||
aa_kernel_interface_load_policy_from_file(profilename) :
|
||||
aa_kernel_interface_load_policy_from_fd(0);
|
||||
if (retval == -1) {
|
||||
retval = errno;
|
||||
PERROR(_("Error: Could not load profile %s: %s\n"),
|
||||
printed_name, strerror(retval));
|
||||
return retval;
|
||||
}
|
||||
} else if (option == OPTION_REPLACE) {
|
||||
retval = profilename ?
|
||||
aa_kernel_interface_replace_policy_from_file(profilename) :
|
||||
aa_kernel_interface_replace_policy_from_fd(0);
|
||||
if (retval == -1) {
|
||||
retval = errno;
|
||||
PERROR(_("Error: Could not replace profile %s: %s\n"),
|
||||
printed_name, strerror(retval));
|
||||
return retval;
|
||||
}
|
||||
} else {
|
||||
PERROR(_("Error: Invalid load option specified: %d\n"),
|
||||
option);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
rsize = read(fd, buffer + size, asize - size);
|
||||
if (rsize)
|
||||
size += rsize;
|
||||
} while (rsize > 0);
|
||||
|
||||
if (rsize == 0) {
|
||||
retval = aa_load_buffer(option, buffer, size);
|
||||
if (retval == -1)
|
||||
retval = -errno;
|
||||
} else
|
||||
retval = rsize;
|
||||
}
|
||||
|
||||
if (conf_verbose) {
|
||||
switch (option) {
|
||||
case OPTION_ADD:
|
||||
printf(_("Cached load succeeded for \"%s\".\n"),
|
||||
profilename ? profilename : "stdin");
|
||||
printed_name);
|
||||
break;
|
||||
case OPTION_REPLACE:
|
||||
printf(_("Cached reload succeeded for \"%s\".\n"),
|
||||
profilename ? profilename : "stdin");
|
||||
printed_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_parser(const char *filename)
|
||||
|
Reference in New Issue
Block a user