diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-04-13 20:31:37 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-04-29 15:40:23 -0400 |
commit | 3dc20cb282ec03cc4c997130d680c800011ed479 (patch) | |
tree | d8374e58a433a144c571e193cb0b024374ee0b6a /fs/binfmt_flat.c | |
parent | 3af0761307d04f6b9a4626fb80011a22c143d75e (diff) |
new helper: read_code()
switch binfmts that use ->read() to that (and to kernel_read()
in several cases in binfmt_flat - sure, it's nommu, but still,
doing ->read() into kmalloc'ed buffer...)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/binfmt_flat.c')
-rw-r--r-- | fs/binfmt_flat.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 2036d21baaef..d50bbe59da1e 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -207,11 +207,12 @@ static int decompress_exec( | |||
207 | 207 | ||
208 | /* Read in first chunk of data and parse gzip header. */ | 208 | /* Read in first chunk of data and parse gzip header. */ |
209 | fpos = offset; | 209 | fpos = offset; |
210 | ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); | 210 | ret = kernel_read(bprm->file, offset, buf, LBUFSIZE); |
211 | 211 | ||
212 | strm.next_in = buf; | 212 | strm.next_in = buf; |
213 | strm.avail_in = ret; | 213 | strm.avail_in = ret; |
214 | strm.total_in = 0; | 214 | strm.total_in = 0; |
215 | fpos += ret; | ||
215 | 216 | ||
216 | retval = -ENOEXEC; | 217 | retval = -ENOEXEC; |
217 | 218 | ||
@@ -277,7 +278,7 @@ static int decompress_exec( | |||
277 | } | 278 | } |
278 | 279 | ||
279 | while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { | 280 | while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { |
280 | ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); | 281 | ret = kernel_read(bprm->file, fpos, buf, LBUFSIZE); |
281 | if (ret <= 0) | 282 | if (ret <= 0) |
282 | break; | 283 | break; |
283 | len -= ret; | 284 | len -= ret; |
@@ -285,6 +286,7 @@ static int decompress_exec( | |||
285 | strm.next_in = buf; | 286 | strm.next_in = buf; |
286 | strm.avail_in = ret; | 287 | strm.avail_in = ret; |
287 | strm.total_in = 0; | 288 | strm.total_in = 0; |
289 | fpos += ret; | ||
288 | } | 290 | } |
289 | 291 | ||
290 | if (ret < 0) { | 292 | if (ret < 0) { |
@@ -428,6 +430,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
428 | unsigned long textpos = 0, datapos = 0, result; | 430 | unsigned long textpos = 0, datapos = 0, result; |
429 | unsigned long realdatastart = 0; | 431 | unsigned long realdatastart = 0; |
430 | unsigned long text_len, data_len, bss_len, stack_len, flags; | 432 | unsigned long text_len, data_len, bss_len, stack_len, flags; |
433 | unsigned long full_data; | ||
431 | unsigned long len, memp = 0; | 434 | unsigned long len, memp = 0; |
432 | unsigned long memp_size, extra, rlim; | 435 | unsigned long memp_size, extra, rlim; |
433 | unsigned long *reloc = 0, *rp; | 436 | unsigned long *reloc = 0, *rp; |
@@ -451,6 +454,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
451 | relocs = ntohl(hdr->reloc_count); | 454 | relocs = ntohl(hdr->reloc_count); |
452 | flags = ntohl(hdr->flags); | 455 | flags = ntohl(hdr->flags); |
453 | rev = ntohl(hdr->rev); | 456 | rev = ntohl(hdr->rev); |
457 | full_data = data_len + relocs * sizeof(unsigned long); | ||
454 | 458 | ||
455 | if (strncmp(hdr->magic, "bFLT", 4)) { | 459 | if (strncmp(hdr->magic, "bFLT", 4)) { |
456 | /* | 460 | /* |
@@ -577,12 +581,12 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
577 | #ifdef CONFIG_BINFMT_ZFLAT | 581 | #ifdef CONFIG_BINFMT_ZFLAT |
578 | if (flags & FLAT_FLAG_GZDATA) { | 582 | if (flags & FLAT_FLAG_GZDATA) { |
579 | result = decompress_exec(bprm, fpos, (char *) datapos, | 583 | result = decompress_exec(bprm, fpos, (char *) datapos, |
580 | data_len + (relocs * sizeof(unsigned long)), 0); | 584 | full_data, 0); |
581 | } else | 585 | } else |
582 | #endif | 586 | #endif |
583 | { | 587 | { |
584 | result = bprm->file->f_op->read(bprm->file, (char *) datapos, | 588 | result = read_code(bprm->file, datapos, fpos, |
585 | data_len + (relocs * sizeof(unsigned long)), &fpos); | 589 | full_data); |
586 | } | 590 | } |
587 | if (IS_ERR_VALUE(result)) { | 591 | if (IS_ERR_VALUE(result)) { |
588 | printk("Unable to read data+bss, errno %d\n", (int)-result); | 592 | printk("Unable to read data+bss, errno %d\n", (int)-result); |
@@ -627,30 +631,25 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
627 | if (flags & FLAT_FLAG_GZIP) { | 631 | if (flags & FLAT_FLAG_GZIP) { |
628 | result = decompress_exec(bprm, sizeof (struct flat_hdr), | 632 | result = decompress_exec(bprm, sizeof (struct flat_hdr), |
629 | (((char *) textpos) + sizeof (struct flat_hdr)), | 633 | (((char *) textpos) + sizeof (struct flat_hdr)), |
630 | (text_len + data_len + (relocs * sizeof(unsigned long)) | 634 | (text_len + full_data |
631 | - sizeof (struct flat_hdr)), | 635 | - sizeof (struct flat_hdr)), |
632 | 0); | 636 | 0); |
633 | memmove((void *) datapos, (void *) realdatastart, | 637 | memmove((void *) datapos, (void *) realdatastart, |
634 | data_len + (relocs * sizeof(unsigned long))); | 638 | full_data); |
635 | } else if (flags & FLAT_FLAG_GZDATA) { | 639 | } else if (flags & FLAT_FLAG_GZDATA) { |
636 | fpos = 0; | 640 | result = read_code(bprm->file, textpos, 0, text_len); |
637 | result = bprm->file->f_op->read(bprm->file, | ||
638 | (char *) textpos, text_len, &fpos); | ||
639 | if (!IS_ERR_VALUE(result)) | 641 | if (!IS_ERR_VALUE(result)) |
640 | result = decompress_exec(bprm, text_len, (char *) datapos, | 642 | result = decompress_exec(bprm, text_len, (char *) datapos, |
641 | data_len + (relocs * sizeof(unsigned long)), 0); | 643 | full_data, 0); |
642 | } | 644 | } |
643 | else | 645 | else |
644 | #endif | 646 | #endif |
645 | { | 647 | { |
646 | fpos = 0; | 648 | result = read_code(bprm->file, textpos, 0, text_len); |
647 | result = bprm->file->f_op->read(bprm->file, | 649 | if (!IS_ERR_VALUE(result)) |
648 | (char *) textpos, text_len, &fpos); | 650 | result = read_code(bprm->file, datapos, |
649 | if (!IS_ERR_VALUE(result)) { | 651 | ntohl(hdr->data_start), |
650 | fpos = ntohl(hdr->data_start); | 652 | full_data); |
651 | result = bprm->file->f_op->read(bprm->file, (char *) datapos, | ||
652 | data_len + (relocs * sizeof(unsigned long)), &fpos); | ||
653 | } | ||
654 | } | 653 | } |
655 | if (IS_ERR_VALUE(result)) { | 654 | if (IS_ERR_VALUE(result)) { |
656 | printk("Unable to read code+data+bss, errno %d\n",(int)-result); | 655 | printk("Unable to read code+data+bss, errno %d\n",(int)-result); |