[PATCH 1/3] Protectable memory support

kbuild test robot lkp at intel.com
Tue Jul 11 02:05:12 UTC 2017


Hi Igor,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.12 next-20170710]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Igor-Stoppa/mm-security-ro-protection-for-dynamic-data/20170711-084116
config: i386-randconfig-x070-07101331 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   mm/pmalloc.c: In function '__pmalloc_pool_show_avail':
   mm/pmalloc.c:78:25: warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
     return sprintf(buf, "%lu\n", gen_pool_avail(data->pool));
                            ^
   mm/pmalloc.c: In function '__pmalloc_pool_show_size':
   mm/pmalloc.c:88:25: warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'size_t {aka unsigned int}' [-Wformat=]
     return sprintf(buf, "%lu\n", gen_pool_size(data->pool));
                            ^
   In file included from include/linux/init.h:4:0,
                    from include/linux/printk.h:5,
                    from mm/pmalloc.c:13:
   mm/pmalloc.c: In function 'pmalloc':
   mm/pmalloc.c:263:5: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
        (phys_addr_t)NULL, chunk_size, NUMA_NO_NODE));
        ^
   include/linux/compiler.h:175:42: note: in definition of macro 'unlikely'
    # define unlikely(x) __builtin_expect(!!(x), 0)
                                             ^
   mm/pmalloc.c:262:2: note: in expansion of macro 'BUG_ON'
     BUG_ON(gen_pool_add_virt(pool, (unsigned long)chunk,
     ^~~~~~
   mm/pmalloc.c: In function '__pmalloc_connect':
>> mm/pmalloc.c:118:2: warning: ignoring return value of 'sysfs_create_file', declared with attribute warn_unused_result [-Wunused-result]
     sysfs_create_file(data->pool_kobject, &data->attr_protected.attr);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   mm/pmalloc.c:119:2: warning: ignoring return value of 'sysfs_create_file', declared with attribute warn_unused_result [-Wunused-result]
     sysfs_create_file(data->pool_kobject, &data->attr_avail.attr);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   mm/pmalloc.c:120:2: warning: ignoring return value of 'sysfs_create_file', declared with attribute warn_unused_result [-Wunused-result]
     sysfs_create_file(data->pool_kobject, &data->attr_size.attr);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   mm/pmalloc.c:121:2: warning: ignoring return value of 'sysfs_create_file', declared with attribute warn_unused_result [-Wunused-result]
     sysfs_create_file(data->pool_kobject, &data->attr_chunks.attr);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/sysfs_create_file +118 mm/pmalloc.c

   110	
   111	/**
   112	 * Exposes the pool and its attributes through sysfs.
   113	 */
   114	static void __pmalloc_connect(struct pmalloc_data *data)
   115	{
   116		data->pool_kobject = kobject_create_and_add(data->pool->name,
   117							    pmalloc_kobject);
 > 118		sysfs_create_file(data->pool_kobject, &data->attr_protected.attr);
   119		sysfs_create_file(data->pool_kobject, &data->attr_avail.attr);
   120		sysfs_create_file(data->pool_kobject, &data->attr_size.attr);
   121		sysfs_create_file(data->pool_kobject, &data->attr_chunks.attr);
   122	}
   123	
   124	/**
   125	 * Removes the pool and its attributes from sysfs.
   126	 */
   127	static void __pmalloc_disconnect(struct pmalloc_data *data)
   128	{
   129		sysfs_remove_file(data->pool_kobject, &data->attr_protected.attr);
   130		sysfs_remove_file(data->pool_kobject, &data->attr_avail.attr);
   131		sysfs_remove_file(data->pool_kobject, &data->attr_size.attr);
   132		sysfs_remove_file(data->pool_kobject, &data->attr_chunks.attr);
   133		kobject_put(data->pool_kobject);
   134	}
   135	
   136	/**
   137	 * Declares an attribute of the pool.
   138	 */
   139	
   140	
   141	#ifdef CONFIG_DEBUG_LOCK_ALLOC
   142	#define do_lock_dep(data, attr_name) \
   143		(data->attr_##attr_name.attr.ignore_lockdep = 1)
   144	#else
   145	#define do_lock_dep(data, attr_name) do {} while (0)
   146	#endif
   147	
   148	#define __pmalloc_attr_init(data, attr_name) \
   149	do { \
   150		data->attr_##attr_name.attr.name = #attr_name; \
   151		data->attr_##attr_name.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444); \
   152		data->attr_##attr_name.show = __pmalloc_pool_show_##attr_name; \
   153		do_lock_dep(data, attr_name); \
   154	} while (0)
   155	
   156	struct gen_pool *pmalloc_create_pool(const char *name, int min_alloc_order)
   157	{
   158		struct gen_pool *pool;
   159		const char *pool_name;
   160		struct pmalloc_data *data;
   161	
   162		if (!name)
   163			return NULL;
   164		pool_name = kstrdup(name, GFP_KERNEL);
   165		if (!pool_name)
   166			return NULL;
   167		data = kzalloc(sizeof(struct pmalloc_data), GFP_KERNEL);
   168		if (!data)
   169			return NULL;
   170		if (min_alloc_order < 0)
   171			min_alloc_order = ilog2(sizeof(unsigned long));
   172		pool = gen_pool_create(min_alloc_order, NUMA_NO_NODE);
   173		if (!pool) {
   174			kfree(pool_name);
   175			kfree(data);
   176			return NULL;
   177		}
   178		data->protected = false;
   179		data->pool = pool;
   180		mutex_init(&data->mutex);
   181		__pmalloc_attr_init(data, protected);
   182		__pmalloc_attr_init(data, avail);
   183		__pmalloc_attr_init(data, size);
   184		__pmalloc_attr_init(data, chunks);
   185		pool->data = data;
   186		pool->name = pool_name;
   187		mutex_lock(&pmalloc_mutex);
   188		list_add(&data->node, &pmalloc_tmp_list);
   189		if (pmalloc_list == &pmalloc_final_list)
   190			__pmalloc_connect(data);
   191		mutex_unlock(&pmalloc_mutex);
   192		return pool;
   193	}
   194	
   195	
   196	bool is_pmalloc_page(struct page *page)
   197	{
   198		return page && page_private(page) &&
   199			page->private == pmalloc_signature;
   200	}
   201	EXPORT_SYMBOL(is_pmalloc_page);
   202	
   203	/**
   204	 * To support hardened usercopy, tag/untag pages supplied by pmalloc.
   205	 * Pages are tagged when added to a pool and untagged when removed
   206	 * from said pool.
   207	 */
   208	#define PMALLOC_TAG_PAGE true
   209	#define PMALLOC_UNTAG_PAGE false
   210	static inline
   211	int __pmalloc_tag_pages(void *base, const size_t size, const bool set_tag)
   212	{
   213		void *end = base + size - 1;
   214	
   215		do {
   216			struct page *page;
   217	
   218			if (!is_vmalloc_addr(base))
   219				return -EINVAL;
   220			page = vmalloc_to_page(base);
   221			if (set_tag) {
   222				BUG_ON(page_private(page) || page->private);
   223				set_page_private(page, 1);
   224				page->private = pmalloc_signature;
   225			} else {
   226				BUG_ON(!(page_private(page) &&
   227					 page->private == pmalloc_signature));
   228				set_page_private(page, 0);
   229				page->private = 0;
   230			}
   231			base += PAGE_SIZE;
   232		} while ((PAGE_MASK & (unsigned long)base) <=
   233			 (PAGE_MASK & (unsigned long)end));
   234		return 0;
   235	}
   236	
   237	
   238	static void __page_untag(struct gen_pool *pool,
   239				 struct gen_pool_chunk *chunk, void *data)
   240	{
   241		__pmalloc_tag_pages((void *)chunk->start_addr,
   242				    chunk->end_addr - chunk->start_addr + 1,
   243				    PMALLOC_UNTAG_PAGE);
   244	}
   245	
   246	void *pmalloc(struct gen_pool *pool, size_t size)
   247	{
   248		void *retval, *chunk;
   249		size_t chunk_size;
   250	
   251		if (!size || !pool || ((struct pmalloc_data *)pool->data)->protected)
   252			return NULL;
   253		retval = (void *)gen_pool_alloc(pool, size);
   254		if (retval)
   255			return retval;
   256		chunk_size = roundup(size, PAGE_SIZE);
   257		chunk = vmalloc(chunk_size);
   258		if (!chunk)
   259			return NULL;
   260		__pmalloc_tag_pages(chunk, size, PMALLOC_TAG_PAGE);
   261		/* Locking is already done inside gen_pool_add_virt */
 > 262		BUG_ON(gen_pool_add_virt(pool, (unsigned long)chunk,
   263					(phys_addr_t)NULL, chunk_size, NUMA_NO_NODE));
   264		return (void *)gen_pool_alloc(pool, size);
   265	}
   266	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation


More information about the Linux-security-module-archive mailing list