kernel: sysctl: add init protection to common mm-related nodes

The protected nodes are:
* dirty_ratio
* dirty_background_ratio
* dirty_bytes
* dirty_background_bytes
* dirty_expire_centisecs
* dirty_writeback_centisecs
* swappiness

This approach is inspired by [1] and makes use of the node tampering blacklist.

[1]: 239efdc263

Signed-off-by: Nahuel Gómez <nahuelgomez329@gmail.com>
This commit is contained in:
Nahuel Gómez 2024-10-26 15:31:18 -03:00 committed by Ksawlii
parent bfb3710a7c
commit 7059d8baa3
2 changed files with 28 additions and 2 deletions

View file

@ -2820,6 +2820,16 @@ static struct ctl_table kern_table[] = {
{ }
};
static int proc_swappiness_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
if (task_is_booster(current))
return 0;
return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
}
static struct ctl_table vm_table[] = {
{
.procname = "overcommit_memory",
@ -2921,7 +2931,7 @@ static struct ctl_table vm_table[] = {
.data = &dirty_expire_interval,
.maxlen = sizeof(dirty_expire_interval),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.proc_handler = proc_swappiness_handler,
.extra1 = SYSCTL_ZERO,
},
{
@ -2937,7 +2947,7 @@ static struct ctl_table vm_table[] = {
.data = &vm_swappiness,
.maxlen = sizeof(vm_swappiness),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.proc_handler = proc_swappiness_handler,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_TWO_HUNDRED,
},

View file

@ -38,6 +38,7 @@
#include <linux/sched/rt.h>
#include <linux/sched/signal.h>
#include <linux/mm_inline.h>
#include <linux/binfmts.h>
#include <trace/events/writeback.h>
#include "internal.h"
@ -528,6 +529,9 @@ int dirty_background_ratio_handler(struct ctl_table *table, int write,
{
int ret;
if (task_is_booster(current))
return 0;
ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret == 0 && write)
dirty_background_bytes = 0;
@ -540,6 +544,9 @@ int dirty_background_bytes_handler(struct ctl_table *table, int write,
int ret;
unsigned long old_bytes = dirty_background_bytes;
if (task_is_booster(current))
return 0;
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
if (ret == 0 && write) {
if (DIV_ROUND_UP(dirty_background_bytes, PAGE_SIZE) >
@ -558,6 +565,9 @@ int dirty_ratio_handler(struct ctl_table *table, int write, void *buffer,
int old_ratio = vm_dirty_ratio;
int ret;
if (task_is_booster(current))
return 0;
ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret == 0 && write && vm_dirty_ratio != old_ratio) {
writeback_set_ratelimit();
@ -572,6 +582,9 @@ int dirty_bytes_handler(struct ctl_table *table, int write,
unsigned long old_bytes = vm_dirty_bytes;
int ret;
if (task_is_booster(current))
return 0;
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
if (ret == 0 && write && vm_dirty_bytes != old_bytes) {
if (DIV_ROUND_UP(vm_dirty_bytes, PAGE_SIZE) > UINT_MAX) {
@ -2017,6 +2030,9 @@ int dirty_writeback_centisecs_handler(struct ctl_table *table, int write,
unsigned int old_interval = dirty_writeback_interval;
int ret;
if (task_is_booster(current))
return 0;
ret = proc_dointvec(table, write, buffer, length, ppos);
/*