1 From: Alan Modra <amodra@gmail.com>
2 Date: Tue, 5 Jun 2018 21:04:00 +0930
3 Subject: [PATCH] PR23254, ld.bfd mishandles file pointers while scanning
6 Best practice is to not mix lseek/read with fseek/fread on the same
7 underlying file descriptor, as not all stdio implementations will cope.
8 Since the plugin uses lseek/read while bfd uses fseek/fread this patch
9 reopens the file for exclusive use by the plugin rather than trying to
10 restore the file descriptor. That allows the plugin to read the file
11 after plugin_call_claim_file too.
15 * plugin.c (bfd_plugin_open_input): Allow for possibility of
16 nested archives. Open file again for plugin.
17 (try_claim): Don't save and restore file position. Close file
19 * sysdep.h (O_BINARY): Define.
22 * plugin.c (plugin_call_claim_file): Revert 2016-07-19 patch.
23 (plugin_object_p): Don't dup file descriptor.
28 @@ -165,14 +165,22 @@ bfd_plugin_open_input (bfd *ibfd, struct
32 - if (ibfd->my_archive && !bfd_is_thin_archive (ibfd->my_archive))
33 - iobfd = ibfd->my_archive;
34 + while (iobfd->my_archive
35 + && !bfd_is_thin_archive (iobfd->my_archive))
36 + iobfd = iobfd->my_archive;
37 file->name = iobfd->filename;
39 if (!iobfd->iostream && !bfd_open_file (iobfd))
42 - file->fd = fileno ((FILE *) iobfd->iostream);
43 + /* The plugin API expects that the file descriptor won't be closed
44 + and reused as done by the bfd file cache. So open it again.
45 + dup isn't good enough. plugin IO uses lseek/read while BFD uses
46 + fseek/fread. It isn't wise to mix the unistd and stdio calls on
47 + the same underlying file descriptor. */
48 + file->fd = open (file->name, O_RDONLY | O_BINARY);
54 @@ -196,12 +204,12 @@ try_claim (bfd *abfd)
56 struct ld_plugin_input_file file;
59 if (!bfd_plugin_open_input (abfd, &file))
62 - off_t cur_offset = lseek (file.fd, 0, SEEK_CUR);
63 claim_file (&file, &claimed);
64 - lseek (file.fd, cur_offset, SEEK_SET);
72 @@ -108,6 +108,10 @@ extern char *strrchr ();
74 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
76 +/* Systems that don't already define this, don't need it. */
85 @@ -1053,14 +1053,10 @@ plugin_call_claim_file (const struct ld_
87 if (curplug->claim_file_handler)
90 enum ld_plugin_status rv;
92 called_plugin = curplug;
93 - cur_offset = lseek (file->fd, 0, SEEK_CUR);
94 rv = (*curplug->claim_file_handler) (file, claimed);
96 - lseek (file->fd, cur_offset, SEEK_SET);
99 set_plugin_error (curplug->name);
100 @@ -1126,12 +1122,6 @@ plugin_object_p (bfd *ibfd)
104 - /* The plugin API expects that the file descriptor won't be closed
105 - and reused as done by the bfd file cache. So dup one. */
106 - file.fd = dup (file.fd);
111 input->view_buffer.addr = NULL;
112 input->view_buffer.filesize = 0;