From f69822107f90f68f8c92fe3b151ee1c06b8e658e Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 10 Aug 2011 15:53:39 -0700 Subject: [PATCH] Update apparmor's handling of rlimits for cpu limit and more natural units Allow for rlimit cpu to specified which is now supported by the kernel. Previously the rlimit units where limited to K, M, G and would fail when KB, MB, GB where used. Allow for both, also allow for units on lengths of time, by specifying "seconds", "minutes", "hours".. or any unique subset eg. "s", "sec", "m", "min", "h", "hour" .. NOTE: This patch does not extend rlimits to be able to handle setting of tasks that are confined by other profiles. Signed-off-by: John Johansen --- parser/parser_lex.l | 2 +- parser/parser_yacc.y | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/parser/parser_lex.l b/parser/parser_lex.l index f833b14ce..1bb3ab2e6 100644 --- a/parser/parser_lex.l +++ b/parser/parser_lex.l @@ -508,7 +508,7 @@ LT_EQUAL <= {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ } - -?{NUMBER}[kKMG]? { + -?{NUMBER}[[:alpha:]]* { DUMP_PREPROCESS; yylval.var_val = strdup(yytext); return TOK_VALUE; diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 4fc791c35..05e6c17fe 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -711,10 +711,31 @@ rules: rules TOK_SET TOK_RLIMIT TOK_ID TOK_LE TOK_VALUE TOK_END_OF_RULE if (strcmp($6, "infinity") == 0) { value = RLIM_INFINITY; } else { + const char *seconds = "seconds"; + const char *minutes = "minutes"; + const char *hours = "hours"; + const char *days = "days"; + const char *kb = "KB"; + const char *mb = "MB"; + const char *gb = "GB"; + tmp = strtoll($6, &end, 0); switch (limit) { case RLIMIT_CPU: - yyerror("RLIMIT '%s' is currently unsupported\n", $4); + if (!end || $6 == end || tmp < 0) + yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); + if (*end == '\0' || + strstr(seconds, end) == seconds) { + value = tmp; + } else if (strstr(minutes, end) == minutes) { + value = tmp * 60; + } else if (strstr(hours, end) == hours) { + value = tmp * 60 * 60; + } else if (strstr(days, end) == days) { + value = tmp * 60 * 60 * 24; + } else { + yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); + } break; case RLIMIT_NOFILE: case RLIMIT_NPROC: @@ -722,14 +743,14 @@ rules: rules TOK_SET TOK_RLIMIT TOK_ID TOK_LE TOK_VALUE TOK_END_OF_RULE case RLIMIT_SIGPENDING: #ifdef RLIMIT_RTPRIO case RLIMIT_RTPRIO: - if ($6 == end || *end != '\0' || tmp < 0) + if (!end || $6 == end || *end != '\0' || tmp < 0) yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); value = tmp; break; #endif #ifdef RLIMIT_NICE case RLIMIT_NICE: - if ($6 == end || *end != '\0') + if (!end || $6 == end || *end != '\0') yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); if (tmp < -20 || tmp > 19) yyerror("RLIMIT '%s' out of range (-20 .. 19) %d\n", $4, tmp); @@ -746,11 +767,11 @@ rules: rules TOK_SET TOK_RLIMIT TOK_ID TOK_LE TOK_VALUE TOK_END_OF_RULE case RLIMIT_MSGQUEUE: if ($6 == end || tmp < 0) yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); - if (strcmp(end, "K") == 0) { + if (strstr(kb, end) == kb) { tmp *= 1024; - } else if (strcmp(end, "M") == 0) { + } else if (strstr(mb, end) == mb) { tmp *= 1024*1024; - } else if (strcmp(end, "G") == 0) { + } else if (strstr(gb, end) == gb) { tmp *= 1024*1024*1024; } else if (*end != '\0') { yyerror("RLIMIT '%s' invalid value %s\n", $4, $6);