From: Serge E. Hallyn <serue@xxxxxxxxxx> unsigned longs are not a good value to checkpoint between x86-32 and x86-64 32-bit tasks :) Signed-off-by: Serge E. Hallyn <serue@xxxxxxxxxx> --- checkpoint/checkpoint.c | 5 +-- checkpoint/memory.c | 53 +++++++++++++++++++++++++++++++++++++-- checkpoint/restart.c | 6 ++-- include/linux/checkpoint_hdr.h | 2 +- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c index b4e0021..b3c1c4f 100644 --- a/checkpoint/checkpoint.c +++ b/checkpoint/checkpoint.c @@ -103,13 +103,12 @@ int ckpt_write_string(struct ckpt_ctx *ctx, char *str, int len) static void fill_kernel_const(struct ckpt_const *h) { struct task_struct *tsk; - struct mm_struct *mm; struct new_utsname *uts; /* task */ h->task_comm_len = sizeof(tsk->comm); - /* mm */ - h->mm_saved_auxv_len = sizeof(mm->saved_auxv); + /* mm->saved_auxv size */ + h->at_vector_size = AT_VECTOR_SIZE; /* signal */ h->signal_nsig = _NSIG; /* uts */ diff --git a/checkpoint/memory.c b/checkpoint/memory.c index d51f94b..5058ab3 100644 --- a/checkpoint/memory.c +++ b/checkpoint/memory.c @@ -661,6 +661,25 @@ static int checkpoint_vmas(struct ckpt_ctx *ctx, struct mm_struct *mm) return ret < 0 ? ret : map_count; } +#define CKPT_AT_SZ (AT_VECTOR_SIZE * sizeof(u64)) +/* + * We always write saved_auxv out as an array of u64s, though it is + * an array of u32s on 32-bit arch. + */ +static int ckpt_write_auxv(struct ckpt_ctx *ctx, struct mm_struct *mm) +{ + int i, ret; + u64 *buf = kzalloc(CKPT_AT_SZ, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + for (i=0; i<AT_VECTOR_SIZE; i++) + buf[i] = mm->saved_auxv[i]; + ret = ckpt_write_buffer(ctx, buf, CKPT_AT_SZ); + kfree(buf); + return ret; +} + static int do_checkpoint_mm(struct ckpt_ctx *ctx, struct mm_struct *mm) { struct ckpt_hdr_mm *h; @@ -718,7 +737,7 @@ static int do_checkpoint_mm(struct ckpt_ctx *ctx, struct mm_struct *mm) if (ret < 0) goto out; - ret = ckpt_write_buffer(ctx, mm->saved_auxv, sizeof(mm->saved_auxv)); + ret = ckpt_write_auxv(ctx, mm); if (ret < 0) return ret; @@ -1205,6 +1224,32 @@ static int restore_vma(struct ckpt_ctx *ctx, struct mm_struct *mm) return ret; } +static int ckpt_read_auxv(struct ckpt_ctx *ctx, struct mm_struct *mm) +{ + int i, ret; + u64 *buf = kmalloc(CKPT_AT_SZ, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + ret = _ckpt_read_buffer(ctx, buf, CKPT_AT_SZ); + if (ret < 0) { + kfree(buf); + return ret; + } + + for (i=0; i<AT_VECTOR_SIZE; i++) + if (buf[i] > (u64) ULONG_MAX) { + kfree(buf); + return -E2BIG; + } + + for (i=0; i<AT_VECTOR_SIZE; i++) + mm->saved_auxv[i] = buf[i]; + + kfree(buf); + return 0; +} + static struct mm_struct *do_restore_mm(struct ckpt_ctx *ctx) { struct ckpt_hdr_mm *h; @@ -1270,9 +1315,11 @@ static struct mm_struct *do_restore_mm(struct ckpt_ctx *ctx) } up_write(&mm->mmap_sem); - ret = _ckpt_read_buffer(ctx, mm->saved_auxv, sizeof(mm->saved_auxv)); - if (ret < 0) + ret = ckpt_read_auxv(ctx, mm); + if (ret < 0) { + ckpt_err(ctx, ret, "Error restoring auxv\n"); goto out; + } for (nr = h->map_count; nr; nr--) { ret = restore_vma(ctx, mm); diff --git a/checkpoint/restart.c b/checkpoint/restart.c index 9bb17fc..a5f30f2 100644 --- a/checkpoint/restart.c +++ b/checkpoint/restart.c @@ -552,15 +552,15 @@ int ckpt_read_consume(struct ckpt_ctx *ctx, int len, int type) static int check_kernel_const(struct ckpt_const *h) { struct task_struct *tsk; - struct mm_struct *mm; struct new_utsname *uts; /* task */ if (h->task_comm_len != sizeof(tsk->comm)) return -EINVAL; - /* mm */ - if (h->mm_saved_auxv_len != sizeof(mm->saved_auxv)) + /* mm->saved_auxv size */ + if (h->at_vector_size != AT_VECTOR_SIZE) return -EINVAL; + /* signal */ if (h->signal_nsig != _NSIG) return -EINVAL; diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h index 5a68178..b5dd95c 100644 --- a/include/linux/checkpoint_hdr.h +++ b/include/linux/checkpoint_hdr.h @@ -262,7 +262,7 @@ struct ckpt_const { /* task */ __u16 task_comm_len; /* mm */ - __u16 mm_saved_auxv_len; + __u16 at_vector_size; /* signal */ __u16 signal_nsig; /* uts */ -- 1.6.0.4 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers