Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 01 Apr 2015 19:26:29 +0800
From:      Julian Elischer <julian@freebsd.org>
To:        Mateusz Guzik <mjguzik@gmail.com>, Oliver Pinter <oliver.pinter@hardenedbsd.org>, Yue Chen <ycyc321@gmail.com>, Benjamin Kaduk <bjk@freebsd.org>, "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>, HardenedBSD Core <core@hardenedbsd.org>, PaX Team <pageexec@freemail.hu>
Subject:   Re: How to traverse kernel threads?
Message-ID:  <551BD5E5.6050404@freebsd.org>
In-Reply-To: <20150330173358.GB9095@dft-labs.eu>
References:  <CAKtBrB4h13ZFJ=V0fvkDeTG-L6=e5Uz9%2BHfYc8vY523Y3X6N0A@mail.gmail.com> <20150321220246.GE14650@dft-labs.eu> <CAKtBrB5KNqt6UJ1R_BQpPfTvQZdUzGvZZtT7Uz5qd4VrrfgEdw@mail.gmail.com> <20150321232622.GF14650@dft-labs.eu> <alpine.GSO.1.10.1503221644440.22210@multics.mit.edu> <CAPQ4ffuszSi%2B_SopJdCkoFr4OoY9=BZVbO6oo_s0sKrn8Rgjrw@mail.gmail.com> <CAKtBrB6ZF2FVExmDd%2Bt8yFpN0H7xHwaieWgvryR535Vc2cNBjw@mail.gmail.com> <20150327194920.GB18158@dft-labs.eu> <CAKtBrB6qeNTyemG-ws7X_OKcB2t-6muxJrOZ1Eyr0CRjjso5mQ@mail.gmail.com> <CAPQ4fft%2BmNJObMSw8SFvsweZsB-UKNUV2yghg4jB%2BdvSg9ho2w@mail.gmail.com> <20150330173358.GB9095@dft-labs.eu>

next in thread | previous in thread | raw e-mail | index | archive | help
On 3/31/15 1:33 AM, Mateusz Guzik wrote:
>
> I do not believe this can be implemented reliably without some serious
> tinkering around the kernel. Surely I'm not a live patching expert (not
> any other kind of expert), but hear my out.
>
> It seems proposed approach is to move the kernel around and then updated
> all relevant pointers in all pages.
>
> I do not believe this can be done reliably without corrupting data,
> unless a major surgery is performed on the kernel.
>
> Consider:
> struct meh {
> 	func_t *m_func;
> 	size_t	m_len;
> 	data	*m_buf;
> };
>
> Here we have 'm_func' which needs to be updated, but we don't know if
> that's the only pointer so we have to scan the entire struct. But m_buf
> can have data which looks like kernel pointers (i.e. matches some kernel
> funcs) and how will you know not to modify it? What if this is some sort
> of a hack and in fact you *should* modify it?

two examples..
in the VFS code it is not unknown for a local stack variable to be 
initialised to a method pointer
and used separately from the structure..

methodp = struct foo->method;
{
   some code
}
result = methodp(args);

also things like network mbufs can (AND DO!) have functions pointers 
in them.
They can contain pointers to their own 'free' routines.
so every packet in transit needs to be scanned as well.

one could say that all this difficulty will make your success even 
more amazing :-)


>
> CTF or some other solutions like that don't help if you just traverse
> all allocated buffers since you have no idea what the object you found
> really is.
>
> So, assuming this has to be done in runtime, the only somewhat workable
> solution I see would require leaving function entry points at contant
> addresses and only insert jumps to new locations.
>
> This would be a performance hit and would leave a lot of data at
> constant addresses, defeating the point to some extent.
>
> Also runtime relocation of everything definitely has a lot of unknown
> unknowns, so all in all I would say this is a non-starter.
>
> One could consider a different approach where kernel data is randomly
> shuffled around with some granularity and relevant symbol relocated
> prior to booting.
>
> This should provide unique enough layout, which paired with big
> likelyhood of a kernel panic on first bad exploit attempt may be an
> acceptable solution.
>
> But then the kernel may still have enough info leaks for this to not
> matter, so I would not be so eager to implement it.
>
> That said, what prompted this entire effort? Is there an operating
> system which got this to work or what?
>
>




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?551BD5E5.6050404>