[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 1/9] livepatch: Clear .bss when payload is reverted
So that when we apply the patch again the .bss is cleared. Otherwise we may find some variables containing old values. The payloads may contain various .bss - especially if -fdata-sections is used which can create .bss.<name> sections. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- Cc: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> v3: Initial submission v4: s/EINVAL/EOPNOTSUPP/ Do memset in a single place Support multiple BSS sections. --- xen/common/livepatch.c | 60 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index 5da28a3..b5aef57 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -70,6 +70,9 @@ struct payload { unsigned int nsyms; /* Nr of entries in .strtab and symbols. */ struct livepatch_build_id id; /* ELFNOTE_DESC(.note.gnu.build-id) of the payload. */ struct livepatch_build_id dep; /* ELFNOTE_DESC(.livepatch.depends). */ + void **bss; /* .bss's of the payload. */ + size_t *bss_size; /* and their sizes. */ + size_t n_bss; /* Size of the array. */ char name[XEN_LIVEPATCH_NAME_SIZE]; /* Name of it. */ }; @@ -255,12 +258,18 @@ static struct payload *find_payload(const char *name) static void free_payload_data(struct payload *payload) { /* Set to zero until "move_payload". */ - if ( !payload->pages ) - return; - - vfree((void *)payload->text_addr); + if ( payload->pages ) + { + vfree((void *)payload->text_addr); + payload->pages = 0; + } - payload->pages = 0; + if ( payload->n_bss ) + { + xfree(payload->bss); + xfree(payload->bss_size); + payload->n_bss = 0; + } } /* @@ -287,6 +296,7 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) unsigned int i; size_t size = 0; unsigned int *offset; + unsigned int n_bss = 0; int rc = 0; offset = xmalloc_array(unsigned int, elf->hdr->e_shnum); @@ -309,7 +319,11 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) calc_section(&elf->sec[i], &payload->text_size, &offset[i]); else if ( !(elf->sec[i].sec->sh_flags & SHF_EXECINSTR) && (elf->sec[i].sec->sh_flags & SHF_WRITE) ) + { calc_section(&elf->sec[i], &payload->rw_size, &offset[i]); + if ( elf->sec[i].sec->sh_type == SHT_NOBITS ) + n_bss++; + } else if ( !(elf->sec[i].sec->sh_flags & SHF_EXECINSTR) && !(elf->sec[i].sec->sh_flags & SHF_WRITE) ) calc_section(&elf->sec[i], &payload->ro_size, &offset[i]); @@ -334,12 +348,8 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) size = PFN_UP(size); /* Nr of pages. */ text_buf = vmalloc_xen(size * PAGE_SIZE); if ( !text_buf ) - { - dprintk(XENLOG_ERR, LIVEPATCH "%s: Could not allocate memory for payload!\n", - elf->name); - rc = -ENOMEM; - goto out; - } + goto out_mem; + rw_buf = text_buf + PAGE_ALIGN(payload->text_size); ro_buf = rw_buf + PAGE_ALIGN(payload->rw_size); @@ -348,6 +358,14 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) payload->rw_addr = rw_buf; payload->ro_addr = ro_buf; + payload->bss = xmalloc_array(void *, n_bss); + payload->bss_size = xmalloc_array(size_t, n_bss); + if ( !payload->bss || !payload->bss_size ) + goto out_mem; + + payload->n_bss = n_bss; + n_bss = 0; /* Reusing as counter. */ + for ( i = 1; i < elf->hdr->e_shnum; i++ ) { if ( elf->sec[i].sec->sh_flags & SHF_ALLOC ) @@ -374,14 +392,24 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) elf->name, elf->sec[i].name, elf->sec[i].load_addr); } else - memset(elf->sec[i].load_addr, 0, elf->sec[i].sec->sh_size); + { + payload->bss[n_bss] = elf->sec[i].load_addr; + payload->bss_size[n_bss++] = elf->sec[i].sec->sh_size; + } } } + ASSERT(n_bss == payload->n_bss); out: xfree(offset); return rc; + + out_mem: + dprintk(XENLOG_ERR, LIVEPATCH "%s: Could not allocate memory for payload!\n", + elf->name); + rc = -ENOMEM; + goto out; } static int secure_payload(struct payload *payload, struct livepatch_elf *elf) @@ -997,6 +1025,10 @@ static int apply_payload(struct payload *data) printk(XENLOG_INFO LIVEPATCH "%s: Applying %u functions\n", data->name, data->nfuncs); + /* And clear the BSS for subsequent operation. */ + for ( i = 0; i < data->n_bss; i++ ) + memset(data->bss[i], 0, data->bss_size[i]); + arch_livepatch_quiesce(); for ( i = 0; i < data->nfuncs; i++ ) @@ -1513,9 +1545,9 @@ static void livepatch_printall(unsigned char key) list_for_each_entry ( data, &payload_list, list ) { - printk(" name=%s state=%s(%d) %p (.data=%p, .rodata=%p) using %u pages.\n", + printk(" name=%s state=%s(%d) %p (.data=%p, .rodata=%p) using %u pages (%zu .bss).\n", data->name, state2str(data->state), data->state, data->text_addr, - data->rw_addr, data->ro_addr, data->pages); + data->rw_addr, data->ro_addr, data->pages, data->n_bss); for ( i = 0; i < data->nfuncs; i++ ) { -- 2.4.11 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |