From 7ede4697cf27b09bfde82c0d948ba7af165bb74a Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 10 Mar 2015 21:46:57 +0300 Subject: [PATCH] bfd: Don't leak image-open flags into bfdopen Signed-off-by: Pavel Emelyanov --- bfd.c | 16 +++++++++++++--- image.c | 11 +++++++++-- include/bfd.h | 5 +++-- proc_parse.c | 8 ++++---- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/bfd.c b/bfd.c index 9ebffc4a4..d63b3e0e2 100644 --- a/bfd.c +++ b/bfd.c @@ -87,17 +87,27 @@ static void buf_put(struct xbuf *xb) xb->data = NULL; } -int bfdopen(struct bfd *f, int mode) +static int bfdopen(struct bfd *f, bool writable) { if (buf_get(&f->b)) { close(f->fd); return -1; } - f->mode = mode; + f->writable = writable; return 0; } +int bfdopenr(struct bfd *f) +{ + return bfdopen(f, false); +} + +int bfdopenw(struct bfd *f) +{ + return bfdopen(f, true); +} + static int bflush(struct bfd *bfd); static bool flush_failed = false; @@ -109,7 +119,7 @@ int bfd_flush_images(void) void bclose(struct bfd *f) { if (bfd_buffered(f)) { - if ((f->mode != O_RDONLY) && bflush(f) < 0) { + if (f->writable && bflush(f) < 0) { /* * This is to propagate error up. It's * hardly possible by returning and diff --git a/image.c b/image.c index 9de88cb51..106c2833c 100644 --- a/image.c +++ b/image.c @@ -239,8 +239,15 @@ struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...) img->_x.fd = ret; if (oflags & O_NOBUF) bfd_setraw(&img->_x); - else if (bfdopen(&img->_x, flags)) - goto err_close; + else { + if (flags == O_RDONLY) + ret = bfdopenr(&img->_x); + else + ret = bfdopenw(&img->_x); + + if (ret) + goto err_close; + } if (imgset_template[type].magic == RAW_IMAGE_MAGIC) goto skip_magic; diff --git a/include/bfd.h b/include/bfd.h index cd2f4ad5a..1dd1ea2e0 100644 --- a/include/bfd.h +++ b/include/bfd.h @@ -13,7 +13,7 @@ struct xbuf { struct bfd { int fd; - int mode; + bool writable; struct xbuf b; }; @@ -27,7 +27,8 @@ static inline void bfd_setraw(struct bfd *b) b->b.mem = NULL; } -int bfdopen(struct bfd *f, int mode); +int bfdopenr(struct bfd *f); +int bfdopenw(struct bfd *f); void bclose(struct bfd *f); char *breadline(struct bfd *f); int bwrite(struct bfd *f, const void *buf, int sz); diff --git a/proc_parse.c b/proc_parse.c index c8034c1cd..8ad9d217a 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -358,7 +358,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list) if (f.fd < 0) goto err_n; - if (bfdopen(&f, O_RDONLY)) + if (bfdopenr(&f)) goto err_n; map_files_dir = opendir_proc(pid, "map_files"); @@ -733,7 +733,7 @@ int parse_pid_status(pid_t pid, struct proc_status_creds *cr) return -1; } - if (bfdopen(&f, O_RDONLY)) + if (bfdopenr(&f)) return -1; while (done < 8 && (str = breadline(&f))) { @@ -1165,7 +1165,7 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, return -1; } - if (bfdopen(&f, O_RDONLY)) + if (bfdopenr(&f)) return -1; while (1) { @@ -1616,7 +1616,7 @@ int parse_posix_timers(pid_t pid, struct proc_posix_timers_stat *args) return -1; } - if (bfdopen(&f, O_RDONLY)) + if (bfdopenr(&f)) return -1; while (1) {