BandwidthController: fixup insertion pos in costly chain handling

* Long time ago, setting an alert in a costly_<iface> chain required adding
it just before the ACCEPT rule that was at the end.
But since then the ACCEPT rule has been removed.
This would cause the insert to pick the last position no matter what.
Now we just append.

* A naughty app in the penalty box could waste up quota on packets that would
get dropped in the later penalty_box rule.
Now we check the penalty_box before feeding it to the quota.

Change-Id: Id4b6a7c020583f1cccc7dccde34c4b85d0fd9642
diff --git a/BandwidthController.cpp b/BandwidthController.cpp
index e4171d6..d51ea25 100644
--- a/BandwidthController.cpp
+++ b/BandwidthController.cpp
@@ -47,7 +47,6 @@
 
 /* Alphabetical */
 #define ALERT_IPT_TEMPLATE "%s %s -m quota2 ! --quota %lld --name %s"
-const int  BandwidthController::ALERT_RULE_POS_IN_COSTLY_CHAIN = 4;
 const char BandwidthController::ALERT_GLOBAL_NAME[] = "globalAlert";
 const char* BandwidthController::LOCAL_INPUT = "bw_INPUT";
 const char* BandwidthController::LOCAL_FORWARD = "bw_FORWARD";
@@ -280,6 +279,9 @@
     case IptOpInsert:
         opFlag = "-I";
         break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
     case IptOpReplace:
         opFlag = "-R";
         break;
@@ -382,6 +384,9 @@
     case IptOpInsert:
         opFlag = "-I";
         break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
     case IptOpReplace:
         opFlag = "-R";
         break;
@@ -625,8 +630,14 @@
     }
 
     if (it == quotaIfaces.end()) {
+        /* Preparing the iface adds a penalty_box check */
         res |= prepCostlyIface(ifn, QuotaUnique);
-        quotaCmd = makeIptablesQuotaCmd(IptOpInsert, costName, maxBytes);
+	/*
+	 * The rejecting quota limit should go after the penalty box checks
+	 * or else a naughty app could just eat up the quota.
+	 * So we append here.
+	 */
+        quotaCmd = makeIptablesQuotaCmd(IptOpAppend, costName, maxBytes);
         res |= runIpxtablesCmd(quotaCmd.c_str(), IptRejectAdd);
         if (res) {
             ALOGE("Failed set quota rule");
@@ -736,6 +747,9 @@
     case IptOpInsert:
         opFlag = "-I";
         break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
     case IptOpReplace:
         opFlag = "-R";
         break;
@@ -765,6 +779,9 @@
     case IptOpInsert:
         opFlag = "-I";
         break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
     case IptOpReplace:
         opFlag = "-R";
         break;
@@ -918,7 +935,7 @@
 
 int BandwidthController::setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes) {
     char *alertQuotaCmd;
-    char *chainNameAndPos;
+    char *chainName;
     int res = 0;
     char *alertName;
 
@@ -930,11 +947,11 @@
     if (*alertBytes) {
         res = updateQuota(alertName, *alertBytes);
     } else {
-        asprintf(&chainNameAndPos, "costly_%s %d", costName, ALERT_RULE_POS_IN_COSTLY_CHAIN);
-        asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, "-I", chainNameAndPos, bytes, alertName);
+        asprintf(&chainName, "costly_%s", costName);
+        asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, "-A", chainName, bytes, alertName);
         res |= runIpxtablesCmd(alertQuotaCmd, IptRejectNoAdd);
         free(alertQuotaCmd);
-        free(chainNameAndPos);
+        free(chainName);
     }
     *alertBytes = bytes;
     free(alertName);