Linux Kernel: const annotation

Bhumika Goyal
2 min readJan 22, 2017

--

As mentioned in my previous blog my internship with the Linux Kernel is focused on the ways to make the kernel more secure. Adding const annotation to the structures is one of the ways to achieve this.

Annotating a variable of any data type with ‘const’ implies that it becomes read only and cannot be modified anywhere again after getting initialized in the beginning.

Consider a simple example.c file.

static struct stu abc = {
.one=1,
.two=2
};
void func1 (void)
{
...
struct x *p;
...
p->ops=&abc;
...
}
void func2(void)
{
...
process_mode(&abc)
...
}

Declaration of the structure x and prototype of the function process_mode is like:

//Declaration of x
struct x
{
...
const struct stu *ops;
...
}
//Prototype of process_mode
void process_mode (const struct stu *q);

As ops is of type const, it cannot modify the fields of the structure it points to. ops can still point to different structures in the same file but it cannot change the fields values of those structures.
Consider that structures abc and xyz of type stu are already initialized in example.c. A code snippet from example.c file :

//Operations possible:
p->ops=&abc;
p->ops=&xyz;
//Operations not possible:
p->ops->one=100;
p->ops->two=200;

ops points to abc first and it again points to xyz in the next line. This redefinition is possible as there is no restriction that a const structure pointer cannot change the address it points to. The restriction that exist is that it cannot change the value of the structure fields it points to.

Reference of abc is also passed as an argument to the function process_mode but as this argument is of type const, so abc cannot be modified in process_mode.

As both the function argument and ops is of type const, so abc cannot be modified and therefore abc can be annotated with const. New declaration becomes:

static const struct stu abc = {
.one=1,
.two=2
};

There are many such cases in the kernel but going to each driver and making the change is a bit tiring process. So for ease I write Coccinelle scripts to make the changes. So multiple files in different drivers can be changed at once.

Before submitting a patch for such changes I also check the size of the compiled object file(.o). An example:

Size details of media/platform/blackfin/bfin_capture.oFile size before patching:
text data bss dec hex filename
6776 176 0 6952 1b28 blackfin/bfin_capture.o
File size after patching:
text data bss dec hex filename
6816 136 0 6952 1b28 blackfin/bfin_capture.o

These numbers signifies the data and text segments of the object file.
When the structure was not const, it was stored in the data segment of
the memory as it was readable and writable. But after declaring it
const it became read-only and therefore got moved into the text
segment (.text) that contains read-only data. The shift in the bytes in
the object file shows that the now const structure was successfully
removed from the .data segment and added to the .text segment of the
memory.

--

--