内核中为防止用户对敏感数据(比如一些关键指针)的直接引用,通常会采用“掩饰”的方法,即在分配相关数据的时候,就对其进行掩饰,
然后在引用时,又对其进行还原,这样的话,用户就不能直接引用相应数据(会导致非法访问),而必须使用内核提供的标准接口来引用。
示例如下:
-
void *__alloc_percpu(size_t size, size_t align)
-
{
-
/*
-
* We allocate whole cache lines to avoid false sharing
-
*/
-
size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size());
-
void *pdata = kzalloc(sz, GFP_KERNEL);
-
void *__pdata = __percpu_disguise(pdata);//调用__percpu_disguise对pdata数据进行“掩饰”,实际对地址进行“取非”操作
-
-
/*
-
* Can't easily make larger alignment work with kmalloc. WARN
-
* on it. Larger alignment should only be used for module
-
* percpu sections on SMP for which this path isn't used.
-
*/
-
WARN_ON_ONCE(align > SMP_CACHE_BYTES);
-
-
if (unlikely(!pdata))
-
return NULL;
-
if (likely(!__percpu_populate_mask(__pdata, size, GFP_KERNEL,
-
&cpu_possible_map)))
-
return __pdata;
-
kfree(pdata);
-
return NULL;
-
}
-
#ifndef CONFIG_DEBUG_KMEMLEAK
-
#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) //对指针进行“取非”
-
#else
-
#define __percpu_disguise(pdata) (struct percpu_data *)(pdata)
-
#endif
-
-
#define per_cpu_ptr(ptr, cpu) \
-
({ \
-
struct percpu_data *__p = __percpu_disguise(ptr); \ //应用指针时,再使用__percpu_disguise接口对指针进行取非,从而通过“两次取非”,将指针还原,这里不能直接引用,因为之前分配pdata数据时就已经“取非”了,所以必须使用标准接口__percpu_disguise
-
(__typeof__(ptr))__p->ptrs[(cpu)]; \
-
})
阅读(1987) | 评论(0) | 转发(0) |