mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 22:35:35 +00:00
Compare commits
8 Commits
v2.6.0
...
v2.6-branc
Author | SHA1 | Date | |
---|---|---|---|
|
0b383ad769 | ||
|
55bad42088 | ||
|
258c39d4a5 | ||
|
9819bf5df0 | ||
|
174c89f772 | ||
|
52e14b5c93 | ||
|
83ef426514 | ||
|
e14c6c39f1 |
3
README
3
README
@@ -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.
|
||||
|
||||
|
||||
-------------
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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"
|
||||
|
@@ -143,6 +143,7 @@ TESTS=access \
|
||||
setattr \
|
||||
symlink \
|
||||
syscall \
|
||||
tcp \
|
||||
unix_fd_server \
|
||||
unlink\
|
||||
xattrs\
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user