mm: security: introduce init_on_alloc=1 and init_on_free=1 boot options · torvalds/linux@6471384

@@ -135,6 +135,55 @@ unsigned long totalcma_pages __read_mostly;

135135136136

int percpu_pagelist_fraction;

137137

gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;

138+

#ifdef CONFIG_INIT_ON_ALLOC_DEFAULT_ON

139+

DEFINE_STATIC_KEY_TRUE(init_on_alloc);

140+

#else

141+

DEFINE_STATIC_KEY_FALSE(init_on_alloc);

142+

#endif

143+

EXPORT_SYMBOL(init_on_alloc);

144+145+

#ifdef CONFIG_INIT_ON_FREE_DEFAULT_ON

146+

DEFINE_STATIC_KEY_TRUE(init_on_free);

147+

#else

148+

DEFINE_STATIC_KEY_FALSE(init_on_free);

149+

#endif

150+

EXPORT_SYMBOL(init_on_free);

151+152+

static int __init early_init_on_alloc(char *buf)

153+

{

154+

int ret;

155+

bool bool_result;

156+157+

if (!buf)

158+

return -EINVAL;

159+

ret = kstrtobool(buf, &bool_result);

160+

if (bool_result && page_poisoning_enabled())

161+

pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, will take precedence over init_on_alloc\n");

162+

if (bool_result)

163+

static_branch_enable(&init_on_alloc);

164+

else

165+

static_branch_disable(&init_on_alloc);

166+

return ret;

167+

}

168+

early_param("init_on_alloc", early_init_on_alloc);

169+170+

static int __init early_init_on_free(char *buf)

171+

{

172+

int ret;

173+

bool bool_result;

174+175+

if (!buf)

176+

return -EINVAL;

177+

ret = kstrtobool(buf, &bool_result);

178+

if (bool_result && page_poisoning_enabled())

179+

pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, will take precedence over init_on_free\n");

180+

if (bool_result)

181+

static_branch_enable(&init_on_free);

182+

else

183+

static_branch_disable(&init_on_free);

184+

return ret;

185+

}

186+

early_param("init_on_free", early_init_on_free);

138187139188

/*

140189

* A cached value of the page's pageblock's migratetype, used when the page is

@@ -1067,6 +1116,14 @@ static int free_tail_pages_check(struct page *head_page, struct page *page)

10671116

return ret;

10681117

}

106911181119+

static void kernel_init_free_pages(struct page *page, int numpages)

1120+

{

1121+

int i;

1122+1123+

for (i = 0; i < numpages; i++)

1124+

clear_highpage(page + i);

1125+

}

1126+10701127

static __always_inline bool free_pages_prepare(struct page *page,

10711128

unsigned int order, bool check_free)

10721129

{

@@ -1118,6 +1175,9 @@ static __always_inline bool free_pages_prepare(struct page *page,

11181175

PAGE_SIZE << order);

11191176

}

11201177

arch_free_page(page, order);

1178+

if (want_init_on_free())

1179+

kernel_init_free_pages(page, 1 << order);

1180+11211181

kernel_poison_pages(page, 1 << order, 0);

11221182

if (debug_pagealloc_enabled())

11231183

kernel_map_pages(page, 1 << order, 0);

@@ -2019,8 +2079,8 @@ static inline int check_new_page(struct page *page)

2019207920202080

static inline bool free_pages_prezeroed(void)

20212081

{

2022-

return IS_ENABLED(CONFIG_PAGE_POISONING_ZERO) &&

2023-

page_poisoning_enabled();

2082+

return (IS_ENABLED(CONFIG_PAGE_POISONING_ZERO) &&

2083+

page_poisoning_enabled()) || want_init_on_free();

20242084

}

2025208520262086

#ifdef CONFIG_DEBUG_VM

@@ -2090,13 +2150,10 @@ inline void post_alloc_hook(struct page *page, unsigned int order,

20902150

static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,

20912151

unsigned int alloc_flags)

20922152

{

2093-

int i;

2094-20952153

post_alloc_hook(page, order, gfp_flags);

209621542097-

if (!free_pages_prezeroed() && (gfp_flags & __GFP_ZERO))

2098-

for (i = 0; i < (1 << order); i++)

2099-

clear_highpage(page + i);

2155+

if (!free_pages_prezeroed() && want_init_on_alloc(gfp_flags))

2156+

kernel_init_free_pages(page, 1 << order);

2100215721012158

if (order && (gfp_flags & __GFP_COMP))

21022159

prep_compound_page(page, order);