apparmor/parser/parser_lex.l

619 lines
14 KiB
Text
Raw Normal View History

/*
2007-04-11 08:12:51 +00:00
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
* NOVELL (All rights reserved)
* Copyright (c) 2010 - 2013
* Canonical Ltd. (All rights reserved)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Canonical, Ltd.
*/
/* Definitions section */
/* %option main */
/* eliminates need to link with libfl */
%option noyywrap
%option nounput
%option stack
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <unordered_map>
#include <string>
#define _(s) gettext(s)
#include "parser.h"
#include "profile.h"
#include "parser_include.h"
#include "parser_yacc.h"
#include "lib.h"
#ifdef PDEBUG
#undef PDEBUG
#endif
/* #define DEBUG */
#ifdef DEBUG
static int yy_top_state(void);
#define PDEBUG(fmt, args...) printf("Lexer (Line %d) (state %s): " fmt, current_lineno, state_names[YY_START].c_str(), ## args)
#else
#define PDEBUG(fmt, args...) /* Do nothing */
#endif
#define NPDEBUG(fmt, args...) /* Do nothing */
#define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0)
#define DUMP_AND_DEBUG(X...) \
do { \
DUMP_PREPROCESS; \
PDEBUG(X); \
} while (0)
#define EAT_TOKEN(X...) DUMP_AND_DEBUG(X)
#define RETURN_TOKEN(X) \
do { \
DUMP_AND_DEBUG("Matched: %s\n", yytext); \
return (X); \
} while (0)
#define POP() \
do { \
DUMP_AND_DEBUG(" (pop_to(%s)): Matched: %s\n", state_names[yy_top_state()].c_str(), yytext); \
yy_pop_state(); \
} while (0)
#define PUSH(X) \
do { \
DUMP_AND_DEBUG(" (push(%s)): Matched: %s\n", state_names[(X)].c_str(), yytext); \
yy_push_state(X); \
} while (0)
#define POP_AND_RETURN(X) \
do { \
POP(); \
return (X); \
} while (0)
#define PUSH_AND_RETURN(X, Y) \
do { \
PUSH(X); \
return (Y); \
} while (0)
#define BEGIN_AND_RETURN(X, Y) \
do { \
DUMP_AND_DEBUG(" (begin(%s)): Matched: %s\n", state_names[(X)].c_str(), yytext); \
BEGIN(X); \
return (Y); \
} while (0)
#define YY_NO_INPUT
#define STATE_TABLE_ENT(X) {X, #X }
extern unordered_map<int, string> state_names;
struct cb_struct {
const char *fullpath;
const char *filename;
};
static int include_dir_cb(__unused DIR *dir, const char *name, struct stat *st,
void *data)
{
struct cb_struct *d = (struct cb_struct *) data;
char *path;
if (asprintf(&path, "%s/%s", d->fullpath, name) < 0)
yyerror("Out of memory");
if (is_blacklisted(name, path)) {
free(path);
return 0;
}
if (S_ISREG(st->st_mode)) {
if (!(yyin = fopen(path,"r")))
yyerror(_("Could not open '%s' in '%s'"), path, d->filename);
PDEBUG("Opened include \"%s\" in \"%s\"\n", path, d->filename);
update_mru_tstamp(yyin);
push_include_stack(path);
yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
}
free(path);
return 0;
}
void include_filename(char *filename, int search)
{
FILE *include_file = NULL;
struct stat my_stat;
char *fullpath = NULL;
if (search) {
if (preprocess_only)
fprintf(yyout, "\n\n##included <%s>\n", filename);
include_file = search_path(filename, &fullpath);
} else {
if (preprocess_only)
fprintf(yyout, "\n\n##included \"%s\"\n", filename);
fullpath = strdup(filename);
include_file = fopen(fullpath, "r");
}
if (!include_file)
yyerror(_("Could not open '%s'"),
fullpath ? fullpath: filename);
if (fstat(fileno(include_file), &my_stat))
yyerror(_("fstat failed for '%s'"), fullpath);
if (S_ISREG(my_stat.st_mode)) {
yyin = include_file;
update_mru_tstamp(include_file);
PDEBUG("Opened include \"%s\"\n", fullpath);
push_include_stack(fullpath);
yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
} else if (S_ISDIR(my_stat.st_mode)) {
struct cb_struct data = { fullpath, filename };
fclose(include_file);
include_file = NULL;
if (dirat_for_each(NULL, fullpath, &data, include_dir_cb)) {
yyerror(_("Could not process include directory"
" '%s' in '%s'"), fullpath, filename);;
}
}
if (fullpath)
free(fullpath);
}
%}
CARET "^"
OPEN_BRACE \{
CLOSE_BRACE \}
SLASH \/
COLON :
END_OF_RULE [,]
RANGE -
MODE_CHARS ([RrWwaLlMmkXx])|(([Pp]|[Cc])[Xx])|(([Pp]|[Cc])?([IiUu])[Xx])
MODES {MODE_CHARS}+
WS [[:blank:]]
NUMBER [[:digit:]]+
ID_CHARS [^ \t\n"!,]
ID {ID_CHARS}|(,{ID_CHARS})
IDS {ID}+
POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+]
POST_VAR_ID {POST_VAR_ID_CHARS}|(,{POST_VAR_ID_CHARS})
LIST_VALUE_ID_CHARS [^ \t\n"!,]{-}[()]
LIST_VALUE_ID {LIST_VALUE_ID_CHARS}+
QUOTED_LIST_VALUE_ID {LIST_VALUE_ID}|\"{LIST_VALUE_ID}\"
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
ID_CHARS_NOEQ [^ \t\n"!,]{-}[=]
LEADING_ID_CHARS_NOEQ [^ \t\n"!,]{-}[=()+&]
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
ID_NOEQ {ID_CHARS_NOEQ}|(,{ID_CHARS_NOEQ})
IDS_NOEQ {LEADING_ID_CHARS_NOEQ}{ID_NOEQ}*
ALLOWED_QUOTED_ID [^\0"]|\\\"
QUOTED_ID \"{ALLOWED_QUOTED_ID}*\"
IP {NUMBER}\.{NUMBER}\.{NUMBER}\.{NUMBER}
HAT hat{WS}*
PROFILE profile{WS}*
KEYWORD [[:alpha:]_]+
VARIABLE_NAME [[:alpha:]][[:alnum:]_]*
SET_VAR_PREFIX @
SET_VARIABLE {SET_VAR_PREFIX}(\{{VARIABLE_NAME}\}|{VARIABLE_NAME})
BOOL_VARIABLE $(\{{VARIABLE_NAME}\}|{VARIABLE_NAME})
PATHNAME (\/|{SET_VARIABLE}{POST_VAR_ID}){ID}*
QPATHNAME \"(\/|{SET_VAR_PREFIX})([^\0"]|\\\")*\"
OPEN_PAREN \(
CLOSE_PAREN \)
COMMA \,
EQUALS =
ADD_ASSIGN \+=
ARROW ->
2008-04-06 18:55:46 +00:00
LT_EQUAL <=
/* IF adding new state please update state_names table at eof */
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
%x SUB_ID
%x SUB_VALUE
%x EXTCOND_MODE
%x EXTCONDLIST_MODE
%x NETWORK_MODE
%x LIST_VAL_MODE
%x LIST_COND_MODE
%x LIST_COND_VAL
%x LIST_COND_PAREN_VAL
%x ASSIGN_MODE
2008-04-06 18:55:46 +00:00
%x RLIMIT_MODE
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
%x MOUNT_MODE
%x DBUS_MODE
%x CHANGE_PROFILE_MODE
%x INCLUDE
%%
%{
/* Copied directly into yylex function */
if (parser_token) {
int t = parser_token;
parser_token = 0;
return t;
}
%}
<INITIAL,INCLUDE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE>{
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
}
<INCLUDE>{
(\<([^\> \t\n]+)\>|\"([^\" \t\n]+)\") { /* <filename> */
char *filename = strndup(yytext, yyleng - 1);
include_filename(filename + 1, *filename == '<');
free(filename);
yy_pop_state();
}
[^\<\>\" \t\n]+ { /* filename */
include_filename(yytext, 0);
yy_pop_state();
}
}
<<EOF>> {
fclose(yyin);
pop_include_stack();
yypop_buffer_state();
if ( !YY_CURRENT_BUFFER )
yyterminate();
}
<INITIAL,MOUNT_MODE,DBUS_MODE>{
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
{VARIABLE_NAME}/{WS}*= {
/* we match to the = in the lexer so that we can switch scanner
* state. By the time the parser see the = it may be too late
* as bison may have requested the next token from the scanner
*/
int token = get_keyword_token(yytext);
if (token == TOK_PEER) {
PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID);
} else {
yylval.id = processid(yytext, yyleng);
PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID);
}
}
{VARIABLE_NAME}/{WS}+in{WS}*\( {
/* we match to 'in' in the lexer so that we can switch scanner
* state. By the time the parser see the 'in' it may be to
* late as bison may have requested the next token from the
* scanner
*/
yylval.id = processid(yytext, yyleng);
PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID);
}
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
}
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
<SUB_ID>{
({IDS}|{QUOTED_ID}) {
/* Go into separate state to match generic ID strings */
yylval.id = processid(yytext, yyleng);
POP_AND_RETURN(TOK_ID);
}
}
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
<SUB_VALUE>{
({IDS}|{QUOTED_ID}) {
/* Go into separate state to match generic VALUE strings */
yylval.id = processid(yytext, yyleng);
POP_AND_RETURN(TOK_VALUE);
}
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
}
<LIST_VAL_MODE>{
{CLOSE_PAREN} { POP_AND_RETURN(TOK_CLOSEPAREN); }
{COMMA} { EAT_TOKEN("listval: ,\n"); }
({LIST_VALUE_ID}|{QUOTED_ID}) {
yylval.id = processid(yytext, yyleng);
RETURN_TOKEN(TOK_VALUE);
}
}
<EXTCOND_MODE>{
{EQUALS}{WS}*/[^(\n]{-}{WS} { BEGIN_AND_RETURN(SUB_VALUE, TOK_EQUALS);}
{EQUALS} { RETURN_TOKEN(TOK_EQUALS); }
/* Don't push state here as this is a transition start condition and
* we want to return to the start condition that invoked <EXTCOND_MODE>
* when LIST_VAL_ID is done
*/
{OPEN_PAREN} { BEGIN_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); }
in { RETURN_TOKEN(TOK_IN); }
}
<LIST_COND_VAL>{
({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
yylval.id = processid(yytext, yyleng);
POP_AND_RETURN(TOK_VALUE);
}
}
<LIST_COND_PAREN_VAL>{
{CLOSE_PAREN} { POP(); }
({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
yylval.id = processid(yytext, yyleng);
RETURN_TOKEN(TOK_VALUE);
}
}
<LIST_COND_MODE>{
{CLOSE_PAREN} { POP_AND_RETURN(TOK_CLOSEPAREN); }
{COMMA} { EAT_TOKEN("listcond: , \n"); }
{ID_CHARS_NOEQ}+ {
yylval.id = processid(yytext, yyleng);
RETURN_TOKEN(TOK_CONDID);
}
{EQUALS}{WS}*{OPEN_PAREN} {
PUSH_AND_RETURN(LIST_COND_PAREN_VAL, TOK_EQUALS);
}
{EQUALS} {
PUSH_AND_RETURN(LIST_COND_VAL, TOK_EQUALS);
}
}
<EXTCONDLIST_MODE>{
{EQUALS} { RETURN_TOKEN(TOK_EQUALS); }
{OPEN_PAREN} {
/* Don't push state here as this is a transition
* start condition and we want to return to the start
* condition that invoked <EXTCONDLIST_MODE> when
* LIST_VAL_ID is done
*/
BEGIN_AND_RETURN(LIST_COND_MODE, TOK_OPENPAREN);
}
}
<ASSIGN_MODE>{
({IDS}|{QUOTED_ID}) {
yylval.var_val = processid(yytext, yyleng);
RETURN_TOKEN(TOK_VALUE);
}
{END_OF_RULE} {
yylval.id = strdup(yytext);
DUMP_PREPROCESS;
yyerror(_("Variable declarations do not accept trailing commas"));
}
\\\n { DUMP_PREPROCESS; current_lineno++ ; }
\r?\n {
DUMP_PREPROCESS;
current_lineno++;
yy_pop_state();
}
}
<NETWORK_MODE>{
{IDS} {
yylval.id = strdup(yytext);
RETURN_TOKEN(TOK_ID);
}
}
<CHANGE_PROFILE_MODE>{
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
({IDS}|{QUOTED_ID}) {
yylval.id = processid(yytext, yyleng);
POP_AND_RETURN(TOK_ID);
}
}
2008-04-06 18:55:46 +00:00
<RLIMIT_MODE>{
-?{NUMBER}[[:alpha:]]* {
yylval.var_val = strdup(yytext);
RETURN_TOKEN(TOK_VALUE);
}
2008-04-06 18:55:46 +00:00
{KEYWORD} {
yylval.id = strdup(yytext);
if (strcmp(yytext, "infinity") == 0)
RETURN_TOKEN(TOK_VALUE);
RETURN_TOKEN(TOK_ID);
}
2008-04-06 18:55:46 +00:00
{LT_EQUAL} { RETURN_TOKEN(TOK_LE); }
2008-04-06 18:55:46 +00:00
}
<DBUS_MODE>{
send { RETURN_TOKEN(TOK_SEND); }
receive { RETURN_TOKEN(TOK_RECEIVE); }
bind { RETURN_TOKEN(TOK_BIND); }
read { RETURN_TOKEN(TOK_READ); }
write { RETURN_TOKEN(TOK_WRITE); }
eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); }
{OPEN_PAREN} {
yy_push_state(LIST_VAL_MODE);
RETURN_TOKEN(TOK_OPENPAREN);
}
(r|w|rw|wr)/([[:space:],]) {
yylval.mode = strdup(yytext);
RETURN_TOKEN(TOK_MODE);
}
}
<MOUNT_MODE,DBUS_MODE>{
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) {
yylval.id = processid(yytext, yyleng);
RETURN_TOKEN(TOK_ID);
}
Add mount rules Add the ability to control mounting and unmounting The basic form of the rules are. [audit] [deny] mount [conds]* [device] [ -> [conds] path], [audit] [deny] remount [conds]* [path], [audit] [deny] umount [conds]* [path], [audit] [deny] pivotroot [oldroot=<value>] <path> -> <profile> remount is just a short cut for mount options=remount where [conds] can be fstype=<expr> options=<expr> conds follow the extended conditional syntax of allowing either: * a single value after the equals, which has the same character range as regular IDS (ie most anything but it can't be terminated with a , (comma) and if spaces or other characters are needed it can be quoted eg. options=foo options = foo options="foo bar" * a list of values after the equals, the list of values is enclosed within parenthesis () and its has a slightly reduced character set but again elements can be quoted. the separation between elements is whitespace and commas. eg. options=(foo bar) options=(foo, bar) options=(foo , bar) options=(foo,bar) The rules are flexible and follow a similar pattern as network, capability, etc. mount, # allow all mounts, but not umount or pivotroot mount fstype=procfs, # allow mounting procfs anywhere mount options=(bind, ro) /foo -> /bar, # readonly bind mount mount /dev/sda -> /mnt, mount /dev/sd** -> /mnt/**, mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/ umount, umount /m*, Currently variables and regexs are are supported on the device and mount point. ie. mount <devince> -> <mount point>, Regexes are supported in fstype and options. The options have a further caveat that regexs only work if the option is fs specific option. eg. options=(upperdir=/tmp/*,lowerdir=/) regex's will not currently work against the standard options like ro, rw nosuid Conditionals (fstype) can only be applied to the device (source) at this time and will be disregarded in situations where the mount is manipulating an existing mount (bind, remount). Options can be specified multiple times mount option=rw option=(nosuid,upperdir=/foo), and will be combined together into a single set of values The ordering of the standard mount options (rw,ro, ...) does not matter but the ordering of fs specific options does. Specifying that the value of a particular option does not matter can be acheived by providing both the positive and negative forms of and option option=(rw,ro) options=(suid,nosuid) For the fs specific options specifying that a particular value does not matter is achieve using a regex with alternations. Improvements to the syntax and order restrictions are planned for the future. Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-02-24 04:19:38 -08:00
}
#include/.*\r?\n {
/* Don't use push here as we don't want #include echoed out. It needs
* to be handled specially
*/
yy_push_state(INCLUDE);
}
#.*\r?\n { /* normal comment */
DUMP_AND_DEBUG("comment(%d): %s\n", current_lineno, yytext);
current_lineno++;
}
{CARET} { PUSH_AND_RETURN(SUB_ID, TOK_CARET); }
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
{EQUALS} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_EQUALS); }
{ADD_ASSIGN} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_ADD_ASSIGN); }
{SET_VARIABLE} {
yylval.set_var = strdup(yytext);
RETURN_TOKEN(TOK_SET_VAR);
}
{BOOL_VARIABLE} {
yylval.bool_var = strdup(yytext);
RETURN_TOKEN(TOK_BOOL_VAR);
}
{OPEN_BRACE} { RETURN_TOKEN(TOK_OPEN); }
{CLOSE_BRACE} { RETURN_TOKEN(TOK_CLOSE); }
2007-11-16 09:31:33 +00:00
({PATHNAME}|{QPATHNAME}) {
yylval.id = processid(yytext, yyleng);
RETURN_TOKEN(TOK_ID);
}
({MODES})/([[:space:],]) {
yylval.mode = strdup(yytext);
RETURN_TOKEN(TOK_MODE);
}
{HAT} { PUSH_AND_RETURN(SUB_ID, TOK_HAT); }
{PROFILE} { PUSH_AND_RETURN(SUB_ID, TOK_PROFILE); }
{COLON} { RETURN_TOKEN(TOK_COLON); }
{OPEN_PAREN} { PUSH_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); }
{VARIABLE_NAME} {
int token = get_keyword_token(yytext);
int state = INITIAL;
/* special cases */
switch (token) {
case -1:
/* no token found */
yylval.id = processunquoted(yytext, yyleng);
RETURN_TOKEN(TOK_ID);
break;
case TOK_RLIMIT:
state = RLIMIT_MODE;
break;
case TOK_NETWORK:
state = NETWORK_MODE;
break;
case TOK_CHANGE_PROFILE:
state = CHANGE_PROFILE_MODE;
break;
case TOK_MOUNT:
case TOK_REMOUNT:
case TOK_UMOUNT:
state = MOUNT_MODE;
break;
case TOK_DBUS:
state = DBUS_MODE;
break;
default: /* nothing */
break;
}
PUSH_AND_RETURN(state, token);
}
<INITIAL,NETWORK_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE>{
{END_OF_RULE} {
if (YY_START != INITIAL)
yy_pop_state();
RETURN_TOKEN(TOK_END_OF_RULE);
}
\r?\n {
DUMP_PREPROCESS;
current_lineno++;
}
}
<INITIAL,SUB_ID,SUB_VALUE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,MOUNT_MODE,DBUS_MODE>{
[^\n] {
DUMP_PREPROCESS;
/* Something we didn't expect */
yyerror(_("Found unexpected character: '%s'"), yytext);
}
}
%%
/* Create a table mapping lexer state number to the name used in the
* in the code. This allows for better debug output
*/
unordered_map<int, string> state_names = {
STATE_TABLE_ENT(INITIAL),
STATE_TABLE_ENT(SUB_ID),
STATE_TABLE_ENT(SUB_VALUE),
STATE_TABLE_ENT(EXTCOND_MODE),
STATE_TABLE_ENT(EXTCONDLIST_MODE),
STATE_TABLE_ENT(NETWORK_MODE),
STATE_TABLE_ENT(LIST_VAL_MODE),
STATE_TABLE_ENT(LIST_COND_MODE),
STATE_TABLE_ENT(LIST_COND_VAL),
STATE_TABLE_ENT(LIST_COND_PAREN_VAL),
STATE_TABLE_ENT(ASSIGN_MODE),
STATE_TABLE_ENT(RLIMIT_MODE),
STATE_TABLE_ENT(MOUNT_MODE),
STATE_TABLE_ENT(DBUS_MODE),
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
STATE_TABLE_ENT(INCLUDE),
};