2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 22:35:35 +00:00

Compare commits

...

8 Commits

Author SHA1 Message Date
John Johansen
0b383ad769 Add tests to ensure parser is checking its own time stamp wrt profile cache
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2011-03-08 14:52:32 -08:00
John Johansen
55bad42088 apparmor_parser doesn't use its time stamp when determining if cache is stale
If the apparmor_parser is updated (outside of current packaging), when
doing profile loads it will use the existing cache of compiled profiles,
instead of forcing a recompile on profiles.

This can cause apparmor to load bad policy if the parser contains a bug
fix for the previous version of the parser.

This can be worked around in packaging by invalidating the cache and
forcing a profile reload when the parser is upgraded.

Signed-off-by: John Johansen <john.johansen@canonical.com>
2011-03-08 14:49:03 -08:00
John Johansen
258c39d4a5 Profiles that specify a name and attachment specification fail to attach when the
attachment specification doesn't contain globbing.

eg.
   # profile name and attachment the same - attaches as expected
   profile /usr/lib/chromium-browser/chromium-browser

   # profile without attachment specification - does not attach as expected
  profile chromium-browser

  # profile with name and attachment specification where the attachment specification uses globbing - attaches as expected
  profile chromium-browser /usr/lib/chromium-browser/chromium-broswer*

  # profile with name and attachment specification without globbing - FAILS to attach when it should
  profile chromium-browser /usr/lib/chromium-browser/chromium-browser


This occurs because the xmatch_len is not set correctly for the profiles that specify
a name and an attachment specification, where the attachment specification does not
contain globbing characters.

In this situation the correct length for the xmatch_len is the length of the name, as
the shortest possible unambiguous match is the name length.

This patch does not fix a related bug where an attachment specification of ** will not
match (/**) will.
2011-03-08 10:12:09 -08:00
John Johansen
9819bf5df0 Ensure that the buffer read from /proc/sys/kernel/osrelease is null terminated
Signed-off-by: Jamie Strandboge <jamie@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2011-03-03 15:53:23 -08:00
John Johansen
174c89f772 override AF_MAX for kernels that don't support proper masking
Older versions of the apparmor kernel patches didn't handle receiving
network tables of a larger size than expected.

Allow the parser to detect the kernel version and override the AF_MAX
value for those kernels.

This also replaces the hack using a hardcoded limit of 36 for kernels
missing the features flag.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Kees Cook <kees.cook@canonical.com>
2011-03-03 15:45:10 -08:00
Steve Beattie
52e14b5c93 merged:
Kees Cook 2011-03-02 update AA url in README
2011-03-02 20:12:27 -08:00
Kees Cook
83ef426514 update AA url in README 2011-03-02 12:19:35 -08:00
Steve Beattie
e14c6c39f1 Make tcp test support current network syntax, reanable tcp test 2011-03-02 05:02:45 -08:00
8 changed files with 145 additions and 20 deletions

3
README
View File

@@ -17,7 +17,8 @@ library, available under the LGPL license, which allows change_hat(2)
and change_profile(2) to be used by non-GPL binaries).
For more information, you can read the techdoc.pdf (available after
building the parser) and http://apparmor.wiki.kernel.org.
building the parser) and by visiting the http://apparmor.net/ web
site.
-------------

View File

@@ -179,6 +179,7 @@ struct var_string {
#define FLAG_CHANGEHAT_1_4 2
#define FLAG_CHANGEHAT_1_5 3
extern int kernel_supports_network;
extern int net_af_max_override;
extern int flag_changehat_version;
extern int read_implies_exec;
extern dfaflags_t dfaflags;

View File

@@ -90,6 +90,7 @@ char *flags_string = NULL;
int regex_type = AARE_DFA;
int perms_create = 0; /* perms contain create flag */
int kernel_supports_network = 1; /* kernel supports network rules */
int net_af_max_override = -1; /* use kernel to determine af_max */
char *profile_namespace = NULL;
int flag_changehat_version = FLAG_CHANGEHAT_1_5;
FILE *ofile = NULL;
@@ -804,6 +805,7 @@ int process_profile(int option, char *profilename)
char * cachename = NULL;
char * cachetemp = NULL;
char *basename = NULL;
FILE *cmd;
/* per-profile states */
force_complain = opt_force_complain;
@@ -851,6 +853,12 @@ int process_profile(int option, char *profilename)
update_mru_tstamp(yyin);
}
cmd = fopen("/proc/self/exe", "r");
if (cmd) {
update_mru_tstamp(cmd);
fclose(cmd);
}
retval = yyparse();
if (retval != 0)
goto out;

View File

@@ -29,6 +29,10 @@
#include <linux/limits.h>
#include <arpa/inet.h>
#include <linux/capability.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "parser.h"
#include "parser_yacc.h"
@@ -203,6 +207,69 @@ static struct network_tuple network_mappings[] = {
{NULL, 0, NULL, 0, NULL, 0}
};
/* The apparmor kernel patches up until 2.6.38 didn't handle networking
* tables with sizes > AF_MAX correctly. This could happen when the
* parser was built against newer kernel headers and then used to load
* policy on an older kernel. This could happen during upgrades or
* in multi-kernel boot systems.
*
* Try to detect the running kernel version and use that to determine
* AF_MAX
*/
#define PROC_VERSION "/proc/sys/kernel/osrelease"
static size_t kernel_af_max(void) {
char buffer[32];
int major;
int fd, res;
if (!net_af_max_override) {
return 0;
}
/* the override parameter is specifying the max value */
if (net_af_max_override > 0)
return net_af_max_override;
fd = open(PROC_VERSION, O_RDONLY);
if (!fd)
/* fall back to default provided during build */
return 0;
res = read(fd, &buffer, sizeof(buffer));
close(fd);
if (!res)
return 0;
buffer[sizeof(buffer)-1] = '\0';
res = sscanf(buffer, "2.6.%d", &major);
if (res != 1)
return 0;
switch(major) {
case 24:
case 25:
case 26:
return 34;
case 27:
return 35;
case 28:
case 29:
case 30:
return 36;
case 31:
case 32:
case 33:
case 34:
case 35:
return 37;
case 36:
case 37:
return 38;
/* kernels .38 and later should handle this correctly so no
* static mapping needed
*/
default:
return 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,
@@ -213,13 +280,29 @@ static struct network_tuple network_mappings[] = {
* hence the wrapping function.
*/
size_t get_af_max() {
size_t af_max;
/* HACK: declare that version without "create" had a static AF_MAX */
if (!perms_create) return 36;
if (!perms_create && !net_af_max_override)
net_af_max_override = -1;
#if AA_AF_MAX > AF_MAX
return AA_AF_MAX;
af_max = AA_AF_MAX;
#else
return AF_MAX;
af_max = AF_MAX;
#endif
/* HACK: some kernels didn't handle network tables from parsers
* compiled against newer kernel headers as they are larger than
* the running kernel expected. If net_override is defined check
* to see if there is a static max specified for that kernel
*/
if (net_af_max_override) {
size_t max = kernel_af_max();
if (max && max < af_max)
return max;
}
return af_max;
}
struct aa_network_entry *new_network_ent(unsigned int family,
unsigned int type,

View File

@@ -392,6 +392,8 @@ static int process_profile_name_xmatch(struct codomain *cod)
name = local_name(cod->name);
ptype = convert_aaregex_to_pcre(name, 0, tbuf, PATH_MAX + 3,
&cod->xmatch_len);
if (ptype == ePatternBasic)
cod->xmatch_len = strlen(name);
if (ptype == ePatternInvalid) {
PERROR(_("%s: Invalid profile name '%s' - bad regular expression\n"), progname, name);
@@ -414,8 +416,14 @@ static int process_profile_name_xmatch(struct codomain *cod)
struct alt_name *alt;
list_for_each(cod->altnames, alt) {
int len;
convert_aaregex_to_pcre(alt->name, 0, tbuf,
PATH_MAX + 3, &len);
ptype = convert_aaregex_to_pcre(alt->name, 0,
tbuf,
PATH_MAX + 3,
&len);
if (ptype == ePatternBasic)
len = strlen(alt->name);
if (len < cod->xmatch_len)
cod->xmatch_len = len;
if (!aare_add_rule(rule, tbuf, 0, AA_MAY_EXEC, 0, dfaflags)) {
aare_delete_ruleset(rule);
return FALSE;

View File

@@ -94,3 +94,13 @@ sleep $timeout
touch $basedir/cache/$profile
../apparmor_parser $ARGS -v -r $basedir/$profile | grep -q 'Cached reload succeeded' || { echo "FAIL"; exit 1; }
echo "ok"
echo -n "Cache reading is skipped when parser is newer: "
mkdir $basedir/parser
cp ../apparmor_parser $basedir/parser/
$basedir/parser/apparmor_parser $ARGS -v -r $basedir/$profile | grep -q 'Replacement succeeded for' || { echo "FAIL"; exit 1; }
echo "ok"
echo -n "Cache reading is skipped when parser in \$PATH is newer: "
(PATH=$basedir/parser/ /bin/sh -c "apparmor_parser $ARGS -v -r $basedir/$profile") | grep -q 'Replacement succeeded for' || { echo "FAIL"; exit 1; }
echo "ok"

View File

@@ -143,6 +143,7 @@ TESTS=access \
setattr \
symlink \
syscall \
tcp \
unix_fd_server \
unlink\
xattrs\

View File

@@ -21,18 +21,37 @@ ip="127.0.0.1"
#badperm1=r
#badperm2=w
# PASS TEST - no netdomain rules
genprofile
runchecktest "TCP" pass $port
# PASS TEST - no apparmor rules
runchecktest "TCP (no apparmor)" pass $port
# PASS TEST - simple
genprofile tcp_accept: tcp_connect:
runchecktest "TCP (accept, connect)" pass $port
# FAIL TEST - no network rules
genprofile
runchecktest "TCP (accept, connect) no network rules" fail $port
# PASS TEST - allow tcp
genprofile network:tcp
runchecktest "TCP (accept, connect) allow tcp" pass $port
# PASS TEST - allow inet
genprofile network:inet
runchecktest "TCP (accept, connect) allow inet" pass $port
# PASS TEST - allow inet stream
genprofile "network:inet stream"
runchecktest "TCP (accept, connect) allow inet stream" pass $port
# PASS TEST - simple / low-numbered port
# you damn well better not be running telnet
genprofile tcp_accept: tcp_connect: cap:net_bind_service
runchecktest "TCP (accept, connect)" pass 23
genprofile network:inet cap:net_bind_service
runchecktest "TCP (accept, connect) low numbered port/bind cap" pass 23
# FAIL TEST - simple / low-numbered port
# will always fail unless process has net_bind_service capability.
# you damn well better not be running telnetd.
genprofile network:inet
runchecktest "TCP (accept, connect) low numbered port/no bind cap" fail 23
exit 0
# PASS TEST - accept via interface
genprofile tcp_accept:via:lo tcp_connect:
@@ -62,12 +81,6 @@ runchecktest "TCP (accept, connect)" pass $port
genprofile tcp_accept:to:127.0.0.0/255.255.192.0::${port} tcp_connect:
runchecktest "TCP (accept, connect)" pass $port
# FAIL TEST - simple / low-numbered port
# will always fail unless process has net_bind_service capability.
# you damn well better not be running telnetd.
genprofile tcp_accept: tcp_connect:
runchecktest "TCP (accept, connect, port 23)" fail 23
# PASS TEST - simple / low-numbered port
# will always fail unless process has net_bind_service capability.
# you damn well better not be running telnetd.