Skip to content

Commit

Permalink
fix Issue 11171 - text relocations in shared phobos library
Browse files Browse the repository at this point in the history
- Read-only data with relocations cannot be added to CDATA,
  because text relocations are prohibited by many security
  checks (SELinux).
  Also text relocations effectively break sharing of
  read-only segments across multiple processes.
  • Loading branch information
MartinNowak committed Feb 7, 2014
1 parent 8706495 commit 1a99b8b
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 16 deletions.
19 changes: 19 additions & 0 deletions src/backend/dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,25 @@ bool dtallzeros(const dt_t *dt)
return dt->dt == DT_azeros && !dt->DTnext;
}

/************************************
* Return true if dt contains pointers (requires relocations).
*/

bool dtpointers(const dt_t *dtstart)
{
for (const dt_t *dt = dtstart; dt; dt = dt->DTnext)
{
switch (dt->dt)
{
case DT_abytes:
case DT_xoff:
case DT_coff:
return true;
}
}
return false;
}

/***********************************
* Turn DT_azeros into DTcommon
*/
Expand Down
1 change: 1 addition & 0 deletions src/backend/dt.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void init_common(Symbol *);
unsigned dt_size(const dt_t *dtstart);
dt_t **dtend(dt_t** pdt);
bool dtallzeros(const dt_t *dt);
bool dtpointers(const dt_t *dt);
void dt2common(dt_t **pdt);

#endif /* DT_H */
Expand Down
36 changes: 21 additions & 15 deletions src/backend/elfobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1586,11 +1586,13 @@ void Obj::ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym)

symbol *ehtab_entry = symbol_generate(SCstatic,type_alloc(TYint));
symbol_keep(ehtab_entry);
ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
int seg = ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);

const int shf_flags = SHF_ALLOC | (config.flags3 & CFG3pic ? SHF_WRITE : 0);
ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
int seg = ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
ehtab_entry->Sseg = seg;
Outbuffer *buf = SegData[seg]->SDbuf;
ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
ehtab_entry->Stype->Tmangle = mTYman_c;
ehsym->Stype->Tmangle = mTYman_c;

Expand All @@ -1608,16 +1610,17 @@ void Obj::ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym)

void Obj::ehsections()
{
int sec = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
const int shf_flags = SHF_ALLOC | (config.flags3 & CFG3pic ? SHF_WRITE : 0);
int sec = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
//Obj::bytes(sec, 0, 4, NULL);

IDXSTR namidx = Obj::addstr(symtab_strings,"_deh_beg");
elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec));
//elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec));

ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);

sec = ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
sec = ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
namidx = Obj::addstr(symtab_strings,"_deh_end");
elf_addsym(namidx, 0, 4, STT_OBJECT, STB_GLOBAL, MAP_SEG2SECIDX(sec));

Expand Down Expand Up @@ -3100,9 +3103,10 @@ void Obj::moduleinfo(Symbol *scc)
const int CFflags = I64 ? (CFoffset64 | CFoff) : CFoff;

{
ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
const int seg = ElfObj::getsegment(".minfo", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
ElfObj::getsegment(".minfo_end", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
const int shf_flags = SHF_ALLOC | (config.flags3 & CFG3pic ? SHF_WRITE : 0);
ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
const int seg = ElfObj::getsegment(".minfo", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
ElfObj::getsegment(".minfo_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
SegData[seg]->SDoffset +=
reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFflags);
}
Expand Down Expand Up @@ -3165,21 +3169,23 @@ static void obj_rtinit()
int seg;

{
seg = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
const int shf_flags = SHF_ALLOC | (config.flags3 & CFG3pic ? SHF_WRITE : 0);

seg = ElfObj::getsegment(".deh_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
deh_beg = MAP_SEG2SYMIDX(seg);

ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
ElfObj::getsegment(".deh_eh", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);

seg = ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
seg = ElfObj::getsegment(".deh_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
deh_end = MAP_SEG2SYMIDX(seg);


seg = ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
seg = ElfObj::getsegment(".minfo_beg", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
minfo_beg = MAP_SEG2SYMIDX(seg);

ElfObj::getsegment(".minfo", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
ElfObj::getsegment(".minfo", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);

seg = ElfObj::getsegment(".minfo_end", NULL, SHT_PROGDEF, SHF_ALLOC, NPTRSIZE);
seg = ElfObj::getsegment(".minfo_end", NULL, SHT_PROGDEF, shf_flags, NPTRSIZE);
minfo_end = MAP_SEG2SYMIDX(seg);
}

Expand Down
7 changes: 6 additions & 1 deletion src/backend/out.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,12 @@ void out_readonly(symbol *s)
{
// The default is DATA
#if ELFOBJ
s->Sseg = CDATA;
/* Cannot have pointers in CDATA when compiling PIC code, because
* they require dynamic relocations of the read-only segment.
* Instead use the .data.rel.ro section. See Bugzilla 11171.
*/
if (!(config.flags3 & CFG3pic && dtpointers(s->Sdt)))
s->Sseg = CDATA;
#endif
#if MACHOBJ
/* Because of PIC and CDATA being in the _TEXT segment;
Expand Down

0 comments on commit 1a99b8b

Please sign in to comment.