aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaroline Tice <cmtice@google.com>2013-02-05 23:00:29 +0000
committerCaroline Tice <cmtice@google.com>2013-02-05 23:00:29 +0000
commit64a93920e96316baead3c5d56d812b7ef7450cf3 (patch)
treec48d9481d70e386c3d9229ada8a50f1d70030d1a
parent93c99377e06b9489f1a663e7bf34a7abcd29a6bc (diff)
Backport fixes from gcc 4.7.google/gcc-4_6-mobile-vtable-security
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6-mobile-vtable-security@195770 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog.vtable-security10
-rw-r--r--gcc/cp/g++spec.c37
-rw-r--r--libstdc++-v3/libsupc++/vtv_rts.cc9
3 files changed, 45 insertions, 11 deletions
diff --git a/ChangeLog.vtable-security b/ChangeLog.vtable-security
index f0f71cd6d7b..4c4d9f98eda 100644
--- a/ChangeLog.vtable-security
+++ b/ChangeLog.vtable-security
@@ -1,3 +1,13 @@
+2013-02-04 Caroline Tice <cmtice@google.com>
+
+ * gcc/cp/g++spec.c: (lang_specific_driver): Add new value to
+ saw_vtable_verify for preinit option; increase the size of num_args if
+ appropriate; only add the vtable verification linker options if the
+ linker will actually be called.
+ * libstdc++-v3/libsupc++/vtv_rts.cc (dl_iterate_phdr_callback): Add
+ check for empty name-stirng with non-zero address (for
+ linux-vdso.so.1); change vtv_assert (fd != 1) to an if-condition.
+
2013-01-30 Caroline Tice <cmtice@google.com>
* libstdc++-v3/configure: Add vtv_start.o and vtv_end.o to
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 8fad0d1d35d..ccd7a9f1f6e 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -247,6 +247,8 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
case OPT_fvtable_verify_:
if (strcmp(arg, "std") == 0)
saw_vtable_verify = 1;
+ else if (strcmp(arg, "preinit") == 0)
+ saw_vtable_verify = 2;
break;
}
@@ -260,6 +262,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
/* Add one for shared_libgcc or extra static library. */
num_args = argc + added + need_math + (library > 0) * 4 + 1;
+
+ /* Add two more linker args, '-Wl,-u_vtable_map_vars_start and
+ '-Wl,-u_vtable_map_vars_end. */
+ if (saw_vtable_verify)
+ num_args += 2;
+
new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
i = 0;
@@ -322,13 +330,30 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
j++;
}
- if (saw_vtable_verify && library > 0)
+ if (saw_vtable_verify == 1 && library > 0)
{
- generate_option(OPT_Wl_, VTABLE_LOAD_MODULE_INIT, 1,
+ generate_option(OPT_Wl_, VTABLE_LOAD_MODULE_INIT, 1,
CL_DRIVER, &new_decoded_options[j]);
added_libraries++;
j++;
}
+
+ /* If we are doing vtable verification, make sure the linker does
+ not garbage-collect the special symbols that mark the start and
+ end of the ".vtable_map_vars" section in the binary. (See
+ comments in vtv_start.c and vtv_end.c for more details). */
+
+ if (saw_vtable_verify > 0 && library > 0)
+ {
+ generate_option (OPT_Wl_,"-u_vtable_map_vars_start", 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ j++;
+
+ generate_option (OPT_Wl_,"-u_vtable_map_vars_end", 1,
+ CL_DRIVER, &new_decoded_options[j]);
+ j++;
+ }
+
/* Add `-lstdc++' if we haven't already done so. */
if (library > 0)
{
@@ -340,14 +365,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
j++;
}
#endif
- generate_option (OPT_Wl_,"-u_vtable_map_vars_start", 1,
- CL_DRIVER, &new_decoded_options[j]);
- j++;
-
-
- generate_option (OPT_Wl_,"-u_vtable_map_vars_end", 1,
- CL_DRIVER, &new_decoded_options[j]);
- j++;
generate_option (OPT_l,
saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1,
diff --git a/libstdc++-v3/libsupc++/vtv_rts.cc b/libstdc++-v3/libsupc++/vtv_rts.cc
index acc78a5b9c3..9e8e355130e 100644
--- a/libstdc++-v3/libsupc++/vtv_rts.cc
+++ b/libstdc++-v3/libsupc++/vtv_rts.cc
@@ -213,6 +213,10 @@ dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t,
if (strcmp (info->dlpi_name, "linux-vdso.so.1") == 0)
return 0;
+ if (strlen (info->dlpi_name) == 0
+ && info->dlpi_addr != 0)
+ return 0;
+
/* Get the name of the main executable. This may or may not include
arguments passed to the program. Find the first space, assume it
is the start of the argument list, and change it to a '\0'. */
@@ -254,7 +258,9 @@ dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t,
else
fd = open (info->dlpi_name, O_RDONLY);
- VTV_ASSERT (fd != -1);
+ /* VTV_ASSERT (fd != -1); */
+ if (fd != -1)
+ {
/* Find the section header information in the file. */
ElfW(Half) strtab_idx = ehdr_info->e_shstrndx;
@@ -294,6 +300,7 @@ dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t,
}
}
close (fd);
+ } /* if fd != -1 */
}
start_addr = (const ElfW(Addr)) info->dlpi_addr + map_sect_offset;
}