Bah, the whole using linux/socket.h get AF_* tokens versus sys/socket.h

thing again. Fix to use the kernel's definition of AF_MAX in
linux/socket.h if it's larger than glibc's AF_MAX definition in
sys/socket.h and add a wrapper function so that we don't have include
af_names.h everywhere.

Also, fix memory leaks around the handling of network entries of
policies.
This commit is contained in:
Steve Beattie 2009-07-24 17:24:41 +00:00
parent 098598c98d
commit b8cde97ab7
6 changed files with 42 additions and 16 deletions

View file

@ -188,6 +188,8 @@ __FILTER=$(shell echo $(strip $(FILTER_FAMILIES)) | sed -e 's/ /\\\|/g')
af_names.h: /usr/include/linux/socket.h
LC_ALL=C sed -n -e '/$(__FILTER)/d' -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/#ifndef AF_\\1\\n# define AF_\\1 \\2\\n#endif\\nAA_GEN_NET_ENT(\"\\L\\1\", \\UAF_\\1)\\n/p" $< > $@
# define local AF_MAX which may differ from that of bits/socket.h
LC_ALL=C sed -n -e "s/^\#define[ \\t]\\+\\(AF_MAX\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/#define AA_\\1 \\2\n/p" $< >> $@
cap_names.h: /usr/include/linux/capability.h
LC_ALL=C sed -n -e "/CAP_EMPTY_SET/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9xa-f]\\+\\)\\(.*\\)\$$/\{\"\\L\\1\", \\UCAP_\\1\},/p" $< > $@

View file

@ -248,6 +248,7 @@ extern struct aa_network_entry *new_network_ent(unsigned int family,
extern struct aa_network_entry *network_entry(const char *family,
const char *type,
const char *protocol);
extern size_t get_af_max(void);
extern void debug_cod_list(struct codomain *list);
/* returns -1 if value != true or false, otherwise 0 == false, 1 == true */

View file

@ -656,10 +656,10 @@ int sd_serialize_profile(sd_serialize *p, struct codomain *profile,
return 0;
if (profile->network_allowed) {
int i;
if (!sd_write_array(p, "net_allowed_af", AF_MAX))
size_t i;
if (!sd_write_array(p, "net_allowed_af", get_af_max()))
return 0;
for (i = 0; i < AF_MAX; i++) {
for (i = 0; i < get_af_max(); i++) {
u16 allowed = profile->network_allowed[i] &
~profile->deny_network[i];
if (!sd_write16(p, allowed))

View file

@ -236,6 +236,22 @@ static struct network_tuple network_mappings[] = {
{NULL, 0, NULL, 0, NULL, 0}
};
/* Yuck. We grab AF_* values to define above from linux/socket.h because
* they are more accurate than sys/socket.h for what the kernel actually
* supports. However, we can't just include linux/socket.h directly,
* because the AF_* definitions are protected with an ifdef KERNEL
* wrapper, but we don't want to define that because that can cause
* other redefinitions from glibc. However, because the kernel may have
* more definitions than glibc, we need make sure AF_MAX reflects this,
* hence the wrapping function.
*/
size_t get_af_max() {
#if AA_AF_MAX > AF_MAX
return AA_AF_MAX;
#else
return AF_MAX;
#endif
}
struct aa_network_entry *new_network_ent(unsigned int family,
unsigned int type,
unsigned int protocol)

View file

@ -646,8 +646,8 @@ struct codomain *merge_policy(struct codomain *a, struct codomain *b)
a->set_caps = a->set_caps | b->set_caps;
if (a->network_allowed) {
int i;
for (i = 0; i < AF_MAX; i++) {
size_t i;
for (i = 0; i < get_af_max(); i++) {
a->network_allowed[i] |= b->network_allowed[i];
a->audit_network[i] |= b->audit_network[i];
a->deny_network[i] |= b->deny_network[i];
@ -732,6 +732,14 @@ void free_policy(struct codomain *cod)
free(cod->name);
if (cod->namespace)
free(cod->namespace);
if (cod->network_allowed)
free(cod->network_allowed);
if (cod->audit_network)
free(cod->audit_network);
if (cod->deny_network)
free(cod->deny_network);
if (cod->quiet_network)
free(cod->quiet_network);
free(cod);
}

View file

@ -34,7 +34,6 @@
#include "parser.h"
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/capability.h>
@ -515,13 +514,13 @@ rules: rules opt_audit_flag TOK_DENY network_rule
if (!$4)
yyerror(_("Assert: `network_rule' return invalid protocol."));
if (!$1->network_allowed) {
$1->network_allowed = calloc(AF_MAX,
$1->network_allowed = calloc(get_af_max(),
sizeof(unsigned int));
$1->audit_network = calloc(AF_MAX,
$1->audit_network = calloc(get_af_max(),
sizeof(unsigned int));
$1->deny_network = calloc(AF_MAX,
$1->deny_network = calloc(get_af_max(),
sizeof(unsigned int));
$1->quiet_network = calloc(AF_MAX,
$1->quiet_network = calloc(get_af_max(),
sizeof(unsigned int));
if (!$1->network_allowed || !$1->audit_network ||
!$1->deny_network || !$1->quiet_network)
@ -553,13 +552,13 @@ rules: rules opt_audit_flag network_rule
if (!$3)
yyerror(_("Assert: `network_rule' return invalid protocol."));
if (!$1->network_allowed) {
$1->network_allowed = calloc(AF_MAX,
$1->network_allowed = calloc(get_af_max(),
sizeof(unsigned int));
$1->audit_network = calloc(AF_MAX,
$1->audit_network = calloc(get_af_max(),
sizeof(unsigned int));
$1->deny_network = calloc(AF_MAX,
$1->deny_network = calloc(get_af_max(),
sizeof(unsigned int));
$1->quiet_network = calloc(AF_MAX,
$1->quiet_network = calloc(get_af_max(),
sizeof(unsigned int));
if (!$1->network_allowed || !$1->audit_network ||
!$1->deny_network || !$1->quiet_network)
@ -960,9 +959,9 @@ local_profile: TOK_PROFILE TOK_ID flags TOK_OPEN rules TOK_CLOSE
network_rule: TOK_NETWORK TOK_END_OF_RULE
{
int family;
size_t family;
struct aa_network_entry *new_entry, *entry = NULL;
for (family = AF_UNSPEC; family < AF_MAX; family++) {
for (family = AF_UNSPEC; family < get_af_max(); family++) {
new_entry = new_network_ent(family, 0xffffffff,
0xffffffff);
if (!new_entry)