xen/livepatch: Don't crash on encountering STN_UNDEF relocations

A symndx of STN_UNDEF is special, and means a symbol value of 0.  While
legitimate in the ELF standard, its existance in a livepatch is questionable
at best.  Until a plausible usecase presents itself, reject such a relocation
with -EOPNOTSUPP.

Additionally, fix an off-by-one error while range checking symndx, and perform
a safety check on elf->sym[symndx].sym before derefencing it, to avoid
tripping over a NULL pointer when calculating val.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> [x86 and arm32]
Reviewed-by: Jan Beulich <JBeulich@suse.com>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
This commit is contained in:
Andrew Cooper committed 2017-06-23 15:00:37 +01:00
1 parent bd53b85156
commit 2ff229643b
3 files changed
+39 -3

No files matched your search

+13 -1
View File
@@ -254,12 +254,24 @@ int arch_livepatch_perform(struct livepatch_elf *elf,
addend = get_addend(type, dest);
}
if ( symndx > elf->nsym )
if ( symndx == STN_UNDEF )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: Encountered STN_UNDEF\n",
elf->name);
return -EOPNOTSUPP;
}
else if ( symndx >= elf->nsym )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative symbol wants symbol@%u which is past end!\n",
elf->name, symndx);
return -EINVAL;
}
else if ( !elf->sym[symndx].sym )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: No relative symbol@%u\n",
elf->name, symndx);
return -EINVAL;
}
val = elf->sym[symndx].sym->st_value; /* S */
+13 -1
View File
@@ -252,12 +252,24 @@ int arch_livepatch_perform_rela(struct livepatch_elf *elf,
int ovf = 0;
uint64_t val;
if ( symndx > elf->nsym )
if ( symndx == STN_UNDEF )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: Encountered STN_UNDEF\n",
elf->name);
return -EOPNOTSUPP;
}
else if ( symndx >= elf->nsym )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative relocation wants symbol@%u which is past end!\n",
elf->name, symndx);
return -EINVAL;
}
else if ( !elf->sym[symndx].sym )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: No relative symbol@%u\n",
elf->name, symndx);
return -EINVAL;
}
val = elf->sym[symndx].sym->st_value + r->r_addend; /* S+A */
+13 -1
View File
@@ -170,12 +170,24 @@ int arch_livepatch_perform_rela(struct livepatch_elf *elf,
uint8_t *dest = base->load_addr + r->r_offset;
uint64_t val;
if ( symndx > elf->nsym )
if ( symndx == STN_UNDEF )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: Encountered STN_UNDEF\n",
elf->name);
return -EOPNOTSUPP;
}
else if ( symndx >= elf->nsym )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative relocation wants symbol@%u which is past end!\n",
elf->name, symndx);
return -EINVAL;
}
else if ( !elf->sym[symndx].sym )
{
dprintk(XENLOG_ERR, LIVEPATCH "%s: No symbol@%u\n",
elf->name, symndx);
return -EINVAL;
}
val = r->r_addend + elf->sym[symndx].sym->st_value;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.