[CRIU] [PATCH] net: Relax xmalloc-ing (and fix NULL deref)
Andrei Vagin
avagin at virtuozzo.com
Thu Jun 22 00:22:20 MSK 2017
Applied, thanks!
On Fri, Jun 16, 2017 at 06:19:04PM +0300, Pavel Emelyanov wrote:
> There's potential NULL-derefernece in dump_netns_con() -- two xmalloc
> results are not checked. However, since there's a huge set of these
> xmallocs, I propose to relax the whole thing with one big xmalloc and
> xptr_pull() helper.
>
> Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
> ---
> criu/net.c | 55 +++++++++++++++++++++----------------------------------
> 1 file changed, 21 insertions(+), 34 deletions(-)
>
> diff --git a/criu/net.c b/criu/net.c
> index 6849cd2..90aa947 100644
> --- a/criu/net.c
> +++ b/criu/net.c
> @@ -1564,6 +1564,7 @@ static inline int dump_iptables(struct cr_imgset *fds)
>
> static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
> {
> + void *buf, *o_buf;
> int ret = -1;
> int i;
> NetnsEntry netns = NETNS_ENTRY__INIT;
> @@ -1580,8 +1581,16 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
> list_for_each_entry(p, &ns->net.ids, node)
> i++;
>
> - netns.nsids = xmalloc(sizeof(NetnsId *) * i);
> - ids = xmalloc(sizeof(NetnsId) * i);
> + o_buf = buf = xmalloc(
> + i * (sizeof(NetnsId*) + sizeof(NetnsId)) +
> + size4 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 +
> + size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2
> + );
> + if (!buf)
> + goto out;
> +
> + netns.nsids = xptr_pull_s(&buf, i * sizeof(NetnsId*));
> + ids = xptr_pull_s(&buf, i * sizeof(NetnsId));
> i = 0;
> list_for_each_entry(p, &ns->net.ids, node) {
> netns_id__init(&ids[i]);
> @@ -1594,18 +1603,10 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>
> netns.n_def_conf4 = size4;
> netns.n_all_conf4 = size4;
> - netns.def_conf4 = xmalloc(sizeof(SysctlEntry *) * size4);
> - if (!netns.def_conf4)
> - goto err_free;
> - netns.all_conf4 = xmalloc(sizeof(SysctlEntry *) * size4);
> - if (!netns.all_conf4)
> - goto err_free;
> - def_confs4 = xmalloc(sizeof(SysctlEntry) * size4);
> - if (!def_confs4)
> - goto err_free;
> - all_confs4 = xmalloc(sizeof(SysctlEntry) * size4);
> - if (!all_confs4)
> - goto err_free;
> + netns.def_conf4 = xptr_pull_s(&buf, size4 * sizeof(SysctlEntry*));
> + netns.all_conf4 = xptr_pull_s(&buf, size4 * sizeof(SysctlEntry*));
> + def_confs4 = xptr_pull_s(&buf, size4 * sizeof(SysctlEntry));
> + all_confs4 = xptr_pull_s(&buf, size4 * sizeof(SysctlEntry));
>
> for (i = 0; i < size4; i++) {
> sysctl_entry__init(&def_confs4[i]);
> @@ -1618,18 +1619,10 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>
> netns.n_def_conf6 = size6;
> netns.n_all_conf6 = size6;
> - netns.def_conf6 = xmalloc(sizeof(SysctlEntry *) * size6);
> - if (!netns.def_conf6)
> - goto err_free;
> - netns.all_conf6 = xmalloc(sizeof(SysctlEntry *) * size6);
> - if (!netns.all_conf6)
> - goto err_free;
> - def_confs6 = xmalloc(sizeof(SysctlEntry) * size6);
> - if (!def_confs6)
> - goto err_free;
> - all_confs6 = xmalloc(sizeof(SysctlEntry) * size6);
> - if (!all_confs6)
> - goto err_free;
> + netns.def_conf6 = xptr_pull_s(&buf, size6 * sizeof(SysctlEntry*));
> + netns.all_conf6 = xptr_pull_s(&buf, size6 * sizeof(SysctlEntry*));
> + def_confs6 = xptr_pull_s(&buf, size6 * sizeof(SysctlEntry));
> + all_confs6 = xptr_pull_s(&buf, size6 * sizeof(SysctlEntry));
>
> for (i = 0; i < size6; i++) {
> sysctl_entry__init(&def_confs6[i]);
> @@ -1663,14 +1656,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>
> ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS);
> err_free:
> - xfree(netns.def_conf4);
> - xfree(netns.all_conf4);
> - xfree(def_confs4);
> - xfree(all_confs4);
> - xfree(netns.def_conf6);
> - xfree(netns.all_conf6);
> - xfree(def_confs6);
> - xfree(all_confs6);
> + xfree(o_buf);
> +out:
> return ret;
> }
>
> --
> 2.1.4
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list