[apparmor] [patch] Update RlimitRule to match the parser changes

Christian Boltz apparmor at cboltz.de
Thu Jul 9 20:48:51 UTC 2015


Hello,

this patch updates RlimitRule to match the parser changes in John's patch:
- allow only a specific set of time units
- optionally allow whitespace between rlimit value and unit
- move check for invalid time units to time_to_int()

Also update the tests:
- add several tests with whitespace between value and unit
- change a test that used the (now invalid) "1m" to "1min"
- change the time_to_int() tests to use 'us' as default unit, and add
  a test with 'seconds as default unit



[ 71-update-rlimit-rule-for-parser-changes.diff ]

=== modified file utils/apparmor/regex.py
--- utils/apparmor/regex.py     2015-07-07 21:36:25.882222444 +0200
+++ utils/apparmor/regex.py     2015-07-09 22:37:23.235594522 +0200
@@ -35,7 +35,7 @@
 RE_PROFILE_CAP          = re.compile(RE_AUDIT_DENY + 'capability(?P<capability>(\s+\S+)+)?' + RE_COMMA_EOL)
 RE_PROFILE_LINK         = re.compile(RE_AUDIT_DENY + 'link\s+(((subset)|(<=))\s+)?([\"\@\/].*?"??)\s+->\s*([\"\@\/].*?"??)' + RE_COMMA_EOL)
 RE_PROFILE_ALIAS        = re.compile('^\s*alias\s+("??.+?"??)\s+->\s*("??.+?"??)' + RE_COMMA_EOL)
-RE_PROFILE_RLIMIT       = re.compile('^\s*set\s+rlimit\s+(?P<rlimit>[a-z]+)\s*<=\s*(?P<value>[^ ]+)' + RE_COMMA_EOL)
+RE_PROFILE_RLIMIT       = re.compile('^\s*set\s+rlimit\s+(?P<rlimit>[a-z]+)\s*<=\s*(?P<value>[^ ]+(\s+[a-zA-Z]+)?)' + RE_COMMA_EOL)
 RE_PROFILE_BOOLEAN      = re.compile('^\s*(\$\{?\w*\}?)\s*=\s*(true|false)\s*,?' + RE_EOL, flags=re.IGNORECASE)
 RE_PROFILE_VARIABLE     = re.compile('^\s*(@\{?\w+\}?)\s*(\+?=)\s*(@*.+?)\s*,?' + RE_EOL)
 RE_PROFILE_CONDITIONAL  = re.compile('^\s*if\s+(not\s+)?(\$\{?\w*\}?)\s*\{' + RE_EOL)
=== modified file utils/apparmor/rule/rlimit.py
--- utils/apparmor/rule/rlimit.py       2015-07-05 16:49:43.818137611 +0200
+++ utils/apparmor/rule/rlimit.py       2015-07-09 22:31:40.358766963 +0200
@@ -31,9 +31,9 @@
 
 rlimit_all      = rlimit_size + rlimit_number + rlimit_time + rlimit_nice
 
-RE_NUMBER_UNIT  = re.compile('^(?P<number>[0-9]+)(?P<unit>[a-zA-Z]*)$')
+RE_NUMBER_UNIT  = re.compile('^(?P<number>[0-9]+)\s*(?P<unit>[a-zA-Z]*)$')
 RE_NUMBER       = re.compile('^[0-9]+$')
-RE_UNIT_SIZE    = re.compile('^[0-9]+([KMG]B?)?$')
+RE_UNIT_SIZE    = re.compile('^[0-9]+\s*([KMG]B?)?$')
 RE_NICE         = re.compile('^(-20|-[01]?[0-9]|[01]?[0-9])$')
 
 
@@ -89,11 +89,6 @@
                 if not RE_NUMBER_UNIT.match(value):
                     raise AppArmorException('Invalid value in rlimit %s %s rule' % (rlimit, value))
                 number, unit = split_unit(value)
-                if unit == 'm' and rlimit == 'rttime':
-                    raise AppArmorException('Ambiguous value %s in rlimit %s rule - use "ms" or "minutes"' % (value, rlimit))
-                if unit != '' and not ('seconds'.startswith(unit) or 'minutes'.startswith(unit) or 'hours'.startswith(unit) or
-                        (rlimit == 'rttime' and unit in ['ms', 'us']) ):
-                    raise AppArmorException('Invalid unit in rlimit %s %s rule' % (rlimit, value))
 
                 if rlimit == 'rttime':
                     self.value_as_int = self.time_to_int(value, 'us')
@@ -181,16 +176,24 @@
         if unit == '':
             unit = default_unit
 
-        if unit == 'us':
+        if unit in ['us', 'microsecond', 'microseconds']:
             number = number / 1000000.0
-        elif unit == 'ms':
+            if default_unit == 'seconds':
+                raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value)
+        elif unit in ['ms', 'millisecond', 'milliseconds']:
             number = number / 1000.0
-        elif 'seconds'.startswith(unit):
+            if default_unit == 'seconds':
+                raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value)
+        elif unit in ['s', 'sec', 'second', 'seconds']: # manpage doesn't list sec
             pass
-        elif 'minutes'.startswith(unit):
+        elif unit in ['min', 'minute', 'minutes']:
             number = number * 60
-        elif 'hours'.startswith(unit):
+        elif unit in ['h', 'hour', 'hours']:
             number = number * 60 * 60
+        elif unit in ['d', 'day', 'days']: # manpage doesn't list 'd'
+            number = number * 60 * 60 * 24
+        elif unit in ['week', 'weeks']:
+            number = number * 60 * 60 * 24 * 7
         else:
             raise AppArmorException('Unknown unit %s in rlimit %s %s' % (unit, self.rlimit, value))
 
=== modified file utils/test/test-rlimit.py
--- utils/test/test-rlimit.py   2015-06-26 23:12:26.000028914 +0200
+++ utils/test/test-rlimit.py   2015-07-09 22:38:46.384702949 +0200
@@ -43,10 +43,13 @@
     tests = [
         # rawrule                                    audit  allow  deny   comment         rlimit          value      all/infinity?
         ('set rlimit as <= 2047MB,'            , exp(False, False, False, ''           , 'as'           , '2047MB'      , False)),
+        ('set rlimit as <= 2047 MB,'           , exp(False, False, False, ''           , 'as'           , '2047 MB'     , False)),
         ('set rlimit cpu <= 1024,'             , exp(False, False, False, ''           , 'cpu'          , '1024'        , False)),
         ('set rlimit stack <= 1024GB,'         , exp(False, False, False, ''           , 'stack'        , '1024GB'      , False)),
+        ('set rlimit stack <= 1024 GB,'        , exp(False, False, False, ''           , 'stack'        , '1024 GB'     , False)),
         ('set rlimit rtprio <= 10, # comment'  , exp(False, False, False, ' # comment' , 'rtprio'       , '10'          , False)),
         ('set rlimit core <= 44444KB,'         , exp(False, False, False, ''           , 'core'         , '44444KB'     , False)),
+        ('set rlimit core <= 44444 KB,'        , exp(False, False, False, ''           , 'core'         , '44444 KB'    , False)),
         ('set rlimit rttime <= 60ms,'          , exp(False, False, False, ''           , 'rttime'       , '60ms'        , False)),
         ('set rlimit cpu <= infinity,'         , exp(False, False, False, ''           , 'cpu'          , None          , True )),
         ('set rlimit nofile <= 256,'           , exp(False, False, False, ''           , 'nofile'       , '256'         , False)),
@@ -117,6 +120,7 @@
     tests = [
         # RlimitRule object                                  audit  allow  deny   comment        rlimit         value     all/infinity?
         (RlimitRule('as', '2047MB')                     , exp(False, False, False, ''           , 'as'      ,   '2047MB'    , False)),
+        (RlimitRule('as', '2047 MB')                    , exp(False, False, False, ''           , 'as'      ,   '2047 MB'   , False)),
         (RlimitRule('cpu', '1024')                      , exp(False, False, False, ''           , 'cpu'     ,   '1024'      , False)),
         (RlimitRule('rttime', '60minutes')              , exp(False, False, False, ''           , 'rttime'  ,    '60minutes', False)),
         (RlimitRule('nice', '-10')                      , exp(False, False, False, ''           , 'nice'    ,   '-10'       , False)),
@@ -254,9 +258,11 @@
         ('set rlimit cpu <= 150seconds,', [ True    , False         , True      , True      ]),
         ('set rlimit cpu <= 300seconds,', [ False   , False         , False     , False     ]),
         ('set rlimit cpu <= 1minutes,'  , [ False   , False         , True      , True      ]),
-        ('set rlimit cpu <= 1m,'        , [ False   , False         , True      , True      ]),
+        ('set rlimit cpu <= 1min,'      , [ False   , False         , True      , True      ]),
         ('set rlimit cpu <= 3minutes,'  , [ False   , False         , False     , False     ]),
         ('set rlimit cpu <= 1hour,'     , [ False   , False         , False     , False     ]),
+        ('set rlimit cpu <= 2 days,'    , [ False   , False         , False     , False     ]),
+        ('set rlimit cpu <= 1 week,'    , [ False   , False         , False     , False     ]),
     ]
 
 class RlimitCoveredTest_02(RlimitCoveredTest):
@@ -270,7 +276,9 @@
         ('set rlimit data <= 4194304,'  , [ True    , False         , True      , True      ]),
         ('set rlimit data <= 4096KB,'   , [ True    , False         , True      , True      ]),
         ('set rlimit data <= 4MB,'      , [ True    , True          , True      , True      ]),
+        ('set rlimit data <= 4 MB,'     , [ True    , False         , True      , True      ]),
         ('set rlimit data <= 6MB,'      , [ False   , False         , False     , False     ]),
+        ('set rlimit data <= 6 MB,'     , [ False   , False         , False     , False     ]),
         ('set rlimit data <= 1GB,'      , [ False   , False         , False     , False     ]),
     ]
 
@@ -418,6 +426,7 @@
 class RlimitSplit_unitTest(AATest):
     tests = [
         ('40MB'  , ( 40, 'MB',)),
+        ('40 MB' , ( 40, 'MB',)),
         ('40'  ,   ( 40, '',  )),
     ]
 
@@ -451,16 +460,21 @@
         self.obj = RlimitRule('cpu', '1')
 
     tests = [
+        ('40'       ,       0.00004),
         ('30us'     ,       0.00003),
         ('40ms'     ,       0.04),
-        ('40'       ,      40),
         ('40seconds',      40),
         ('2minutes' ,    2*60),
         ('2hours'   , 2*60*60),
+        ('1 day'    , 1*60*60*24),
+        ('2 weeks'  , 2*60*60*24*7),
     ]
 
     def _run_test(self, params, expected):
-        self.assertEqual(self.obj.time_to_int(params, 'seconds'), expected)
+        self.assertEqual(self.obj.time_to_int(params, 'us'), expected)
+
+    def test_with_seconds_as_default(self):
+        self.assertEqual(self.obj.time_to_int('40', 'seconds'), 40)
 
     def test_with_ms_as_default(self):
         self.assertEqual(self.obj.time_to_int('40', 'ms'), 0.04)


Regards,

Christian Boltz
-- 
> Status?
NEW
[Ihno Krumreich and Stephan Kulow on
 https://bugzilla.novell.com/show_bug.cgi?id=159223]




More information about the AppArmor mailing list