Re: [PATCH 3.10 12/27] x86-64, espfix: Dont leak bits 31:16 of %esp returning to 16-bit stack

From: Luis Henriques
Date: Wed Aug 06 2014 - 11:55:37 EST


On Wed, Aug 06, 2014 at 08:24:17AM -0700, Greg Kroah-Hartman wrote:
> On Wed, Aug 06, 2014 at 04:16:20PM +0100, Luis Henriques wrote:
> > On Tue, Aug 05, 2014 at 11:14:04AM -0700, Greg Kroah-Hartman wrote:
> > <...>
> > > @@ -188,17 +193,21 @@ static void note_page(struct seq_file *m
> > > /*
> > > * Now print the actual finished series
> > > */
> > > - seq_printf(m, "0x%0*lx-0x%0*lx ",
> > > - width, st->start_address,
> > > - width, st->current_address);
> > > -
> > > - delta = (st->current_address - st->start_address) >> 10;
> > > - while (!(delta & 1023) && unit[1]) {
> > > - delta >>= 10;
> > > - unit++;
> > > + if (!st->marker->max_lines ||
> > > + st->lines < st->marker->max_lines) {
> > > + seq_printf(m, "0x%0*lx-0x%0*lx ",
> > > + width, st->start_address,
> > > + width, st->current_address);
> > > +
> > > + delta = (st->current_address - st->start_address) >> 10;

Actually, the line above doesn't seem correct either. In the
original commit the shift operation is removed:

delta = st->current_address - st->start_address;

> > > + while (!(delta & 1023) && unit[1]) {
> > > + delta >>= 10;
> > > + unit++;
> > > + }
> > > + seq_printf(m, "%9lu%c ", delta, *unit);
> > > + printk_prot(m, st->current_prot, st->level);
> > > }
> > > - seq_printf(m, "%9lu%c ", delta, *unit);
> > > - printk_prot(m, st->current_prot, st->level);
> > > + st->lines++;
> > >
> > > /*
> > > * We print markers for special areas of address space,
> >
> > Hmm... the original commit has a 2nd hunk here that does seem to be
> > applicable to 3.10. Was this dropped accidentally or on purpose?
>
> I don't remember at all, sorry. What is the hunk that I missed?

I was referring to the following code in the original commit:

@@ -226,7 +238,17 @@ static void note_page(struct seq_file *m, struct pg_state *st,
* This helps in the interpretation.
*/
if (st->current_address >= st->marker[1].start_address) {
+ if (st->marker->max_lines &&
+ st->lines > st->marker->max_lines) {
+ unsigned long nskip =
+ st->lines - st->marker->max_lines;
+ pt_dump_seq_printf(m, st->to_dmesg,
+ "... %lu entr%s skipped ... \n",
+ nskip,
+ nskip == 1 ? "y" : "ies");
+ }
st->marker++;
+ st->lines = 0;
pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n",
st->marker->name);
}

I am attaching a 3.10 backport of 3891a04aafd6 ("x86-64, espfix: Don't
leak bits 31:16 of %esp returning to 16-bit stack"), based on the
backport I was planning to queue for the 3.11 kernel.

I believe this is similar to the one you have queued, except from the
two differences above. A second pair of eyes would be awesome, as I
may be missing something here.

Cheers,
--
Luís