[grsec] Q. 'const'antify the members of a structure

pageexec at freemail.hu pageexec at freemail.hu
Thu May 27 15:43:05 EDT 2010


On 28 May 2010 at 1:37, J. R. Okajima wrote:

> pageexec at freemail.hu:
> > you're talking about the human point of view, but that's only part of the
> > whole picture, the machine point of view is quite different in fact. in
> > particular it's up to the toolchain and runtime environment to actually
> > enforce the const (read-only) property of code/data. as you may have inferred
> > it by now, PaX (and in particular KERNEXEC) does exactly that. even vanilla
> > kernels have been able to do this partially (DEBUG_RODATA) for a while now.
> 
> Do you mean that there is such environment which puts these const
> members in a readonly section?

well, it's a multi-step process, something i should have elaborated more in
the previous reply perhaps, so let's do it now.

as i said, the ultimate goal is to eliminate writable function pointers, or
at least reduce their numbers as much as possible (why that's a goal is
another question, the PaX docs should get you started). to reach that goal
first we have to identify the various function pointers in the kernel and
then see how we can make them const. these function pointers come in several
flavours, something like this:

  1. return addresses on the stack
  2. function addresses stored in global variables
  3. function addresses stored in dynamically allocated variables (on the heap)
  4. function addresses stored in local variables (on the stack)

of these we cannot do much about 1 and 4 (for this discussion, that is, there's
a separate line of development that addresses them). 2 and 3 can however be
handled even with the existing toolchain, with some effort.

in particular, 2 can be handled by marking the variables in question as const,
the toolchain then will ensure that such variables are read-only at runtime.
there're some special cases that i won't digress into (__read_only, etc), you
can dig them out of the patch if you're interested.

the last remaining case is 3 and we have it on good authority (namely, Al Viro)
that such constructs are not desirable in linux in general and should never
occur in fact. now C doesn't make it possible to express this property easily,
however there's an arguably hackish way to do it: by declaring the individual
structure members as const, like this:

  struct some_ops {
    void (* const some_op)(void);
  }

what this does is that at compile time it'll fail on code which tries to
directly write into the some_op field of such a structure (it does allow
initialization which is what you need for case 2), which in turn implies
that such structures cannot be dynamically allocated since they'd need
direct writes to set up the individual members after the allocation. so
this is the real reason for making field members const, it implicitly forces
the programmer to think twice about what he's doing. or rather, it would,
were such code to enter the vanilla kernel, in our case it helps us find
already offending code so that we can change it (the cuse patch is a good
example of what changes are needed to get rid of such writable function
pointers).

of course in your own code you can do whatever override you want, but were
you attempt to submit such code to us, we'd catch the suspicious casts or
whatever method you choose immediately and would not accept it ;).

so this is how this mechanism works, it has both a runtime enforcement and
a development time component, both of which are needed to be able to reach
and maintain the ultimate goal. ideally, we'd have a more intelligent
toolchain that would lessen the amount of patches and be more robust at
the same time, it's on my todo list among too many other things.
 
> > try that under KERNEXEC (or even DEBUG_RODATA) and report back the results ;).
> 
> After applying the grsec patch, DEBUG_RODATA is not selectable since it
> depends upon BROKEN, is it?

sure, since you can do it only one or the other way ;). so if you have a PaX
kernel, try KERNEXEC, otherwise try DEBUG_RODATA. that's what i meant but
didn't want to be too verbose :).
 
> If my mail made you offended, I should apology. That is not what I
> meant. I know developing these patches has to be a hard work. I just
> wanted to say that introducing a tiny code will make your un-trivial
> business easier.

no offense taken but i wanted to make sure that you and others understand
that this is just the tip of the iceberg as far as 'things to check for PaX'
are concerned.



More information about the grsecurity mailing list