diff --git a/extensions/xt_quota2.c b/extensions/xt_quota2.c index 8a2a509..b4d142e 100644 --- a/extensions/xt_quota2.c +++ b/extensions/xt_quota2.c @@ -82,7 +82,7 @@ quota_proc_write(struct file *file, const char __user *input, size_t size, loff_t *loff) { struct xt_quota_counter *e = PDE_DATA(file_inode(file)); - char buf[sizeof("18446744073709551616")]; + char buf[sizeof("+-18446744073709551616")]; if (size > sizeof(buf)) size = sizeof(buf); @@ -92,9 +92,29 @@ quota_proc_write(struct file *file, const char __user *input, if (size < sizeof(buf)) buf[size] = '\0'; - spin_lock_bh(&e->lock); - e->quota = simple_strtoull(buf, NULL, 0); - spin_unlock_bh(&e->lock); + if (*buf == '+') { + int64_t temp = simple_strtoll(buf + 1, NULL, 0); + spin_lock_bh(&e->lock); + /* Do not let quota become negative if @tmp is very negative */ + if (temp > 0 || -temp < e->quota) + e->quota += temp; + else + e->quota = 0; + spin_unlock_bh(&e->lock); + } else if (*buf == '-') { + int64_t temp = simple_strtoll(buf + 1, NULL, 0); + spin_lock_bh(&e->lock); + /* Do not let quota become negative if @tmp is very big */ + if (temp < 0 || temp < e->quota) + e->quota -= temp; + else + e->quota = 0; + spin_unlock_bh(&e->lock); + } else { + spin_lock_bh(&e->lock); + e->quota = simple_strtoull(buf, NULL, 0); + spin_unlock_bh(&e->lock); + } return size; }