From: Caroline Tice <cmtice@google.com>
To: Diego Novillo <dnovillo@google.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
Luis Lozano <llozano@google.com>,
Bhaskar Janakiraman <bjanakiraman@google.com>
Subject: Re: [PATCH, updated] Vtable pointer verification, main gcc changes (patch 2 of 3)
Date: Fri, 24 May 2013 20:52:00 -0000 [thread overview]
Message-ID: <CABtf2+RUUcAmEj0=6ZTwJk1u=n67ga828_5UmyvBGqSNbRjCpw@mail.gmail.com> (raw)
In-Reply-To: <5140BBEC.3040609@google.com>
On Wed, Mar 13, 2013 at 10:48 AM, Diego Novillo <dnovillo@google.com> wrote:
>
> On 2013-02-25 14:27 , Caroline Tice wrote:
>
>> Index: libgcc/Makefile.in
>> ===================================================================
>> --- libgcc/Makefile.in (revision 196266)
>> +++ libgcc/Makefile.in (working copy)
>> @@ -22,6 +22,7 @@
>> libgcc_topdir = @libgcc_topdir@
>> host_subdir = @host_subdir@
>>
>> +gcc_srcdir = $(libgcc_topdir)/gcc
>> gcc_objdir = $(MULTIBUILDTOP)../../$(host_subdir)/gcc
>>
>> srcdir = @srcdir@
>> @@ -969,6 +970,16 @@ crtendS$(objext): $(srcdir)/crtstuff.c
>> # This is a version of crtbegin for -static links.
>> crtbeginT$(objext): $(srcdir)/crtstuff.c
>> $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN -DCRTSTUFFT_O
>> +
>> +# These are used in vtable verification; see comments in source files for
>> +# more details.
>> +vtv_start$(objext): $(gcc_srcdir)/vtv_start.c
>> + $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) \
>> + -c $(gcc_srcdir)/vtv_start.c
>> +
>> +vtv_end$(objext): $(gcc_srcdir)/vtv_end.c
>> + $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) \
>> + -c $(gcc_srcdir)/vtv_end.c
>> endif
>
>
> Why not have these two files in libgcc? I don't think we want to depend on source files in gcc/ from libgcc/
>
I will put them there.
>>
>>
>> /* IPA Passes */
>> extern struct simple_ipa_opt_pass pass_ipa_lower_emutls;
>> Index: gcc/tree-vtable-verify.c
>> ===================================================================
>> --- gcc/tree-vtable-verify.c (revision 0)
>> +++ gcc/tree-vtable-verify.c (revision 0)
>
> I would like to get rid of this naming convention where we prefix file names with 'tree-'. Just vtable-verify.c is fine.
>
>> @@ -0,0 +1,724 @@
>> +/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
>
> Copyright (C) 2013
>
>>
>> +/* Virtual Table Pointer Security Pass - Detect corruption of vtable pointers
>> + before using them for virtual method dispatches. */
>
>
> Do you have a URL to a paper/presentation for it?
No, I don't at this time.
>
>> +
>> + To find and reference the set of valid vtable pointers for any given
>> + virtual class, we create a special global varible for each virtual
>
> s/varible/variable/
>
>>
>> +
>> + Some implementation details for this pass:
>> +
>> + To find the all of the virtual calls, we iterate through all the
>
> s/the all/all/
>>
>>
>> + struct vtable_registration key;
>> + struct vtable_registration **slot;
>> +
>> + gcc_assert (node && node->registered);
>> +
>> + key.vtable_decl = vtable_decl;
>> + slot = (struct vtable_registration **) htab_find_slot (node->registered,
>> + &key, NO_INSERT);
>
> Unless you need to use this in an old branch, I strongly suggest using the new hash table facilities (hash-table.h).
>
Ok, will do.
>> +
>> +
>> +/* Here are the three two structures into which we insert vtable map nodes.
>
> 'three two'?
>>
>>
>> + /* Verify that there aren't any qualifiers on the type. */
>> + type_quals = TYPE_QUALS (TREE_TYPE (class_type_decl));
>> + gcc_assert (type_quals == TYPE_UNQUALIFIED);
>> +
>> + /* Get the mangled name for the unqualified type. */
>> + class_name = DECL_ASSEMBLER_NAME (class_type_decl);
>
>
> DECL_ASSEMBLER_NAME has side-effects (it generates one if there isn't one already). Just to avoid this unwanted side effect, protect it with if (HAS_DECL_ASSEMBLER_NAME_P). In fact, I think you should abort if the class_type_decl does *not* have one. So, just adding gcc_assert (HAS_DECL_ASSEMBLER_NAME_P(class_type_decl)) should be sufficient.
>
Will do.
>>
>> +
>> +/* This function attempts to recover the declared class of an object
>> + that is used in making a virtual call. We try to get the type from
>> + the type cast in the gimple assignment statement that extracts the
>> + vtable pointer from the object (DEF_STMT). The gimple statment
>
> s/statment/statement/
>>
>> + usually looks something like this:
>> +
>> + D.2201_4 = MEM[(struct Event *)this_1(D)]._vptr.Event */
>> +
>> +static tree
>> +/* extract_object_class_type (gimple def_stmt) */
>
> Remove this?
Yes (I didn't realize I had left the commented out code in the patch;
I'm sorry about that).
>>
>> +extract_object_class_type (tree rhs)
>> +{
>> + /* tree rhs = NULL_TREE; */
>> +
>> + /* Try to find and extract the type cast from that stmt. */
>> +
>> + /* rhs = gimple_assign_rhs1 (def_stmt); */
>> + /*
>> + if (TREE_CODE (rhs) == COMPONENT_REF)
>> + {
>> + while (TREE_CODE (rhs) == COMPONENT_REF
>> + && (TREE_CODE (TREE_OPERAND (rhs, 0)) == COMPONENT_REF))
>> + rhs = TREE_OPERAND (rhs, 0);
>> +
>> + if (TREE_CODE (rhs) == COMPONENT_REF
>> + && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
>> + && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0)))== RECORD_TYPE)
>> + rhs = TREE_TYPE (TREE_OPERAND (rhs, 0));
>> + else
>> + rhs = NULL_TREE;
>> + }
>> + else
>> + rhs = NULL_TREE;
>> + */
>
>
> What's this? Is it needed? There's some other commented code here that seems out of place.
>
I will remove it. I didn't mean for it to be in the patch.
>> +
>> + tree result = NULL_TREE;
>> +
>> +
>> + if (TREE_CODE (rhs) == COMPONENT_REF)
>> + {
>> + tree op0 = TREE_OPERAND (rhs, 0);
>> + tree op1 = TREE_OPERAND (rhs, 1);
>> +
>> + if (TREE_CODE (op1) == FIELD_DECL
>> + && DECL_VIRTUAL_P (op1))
>> + {
>> + if (TREE_CODE (op0) == COMPONENT_REF
>> + && TREE_CODE (TREE_OPERAND (op0, 0)) == MEM_REF
>> + && TREE_CODE (TREE_TYPE (TREE_OPERAND (op0, 0)))== RECORD_TYPE)
>> + result = TREE_TYPE (TREE_OPERAND (op0, 0));
>> + else
>> + result = TREE_TYPE (op0);
>> + }
>> + else if (TREE_CODE (op0) == COMPONENT_REF)
>> + {
>> + result = extract_object_class_type (op0);
>> + if (result == NULL_TREE
>> + && TREE_CODE (op1) == COMPONENT_REF)
>> + result = extract_object_class_type (op1);
>> + }
>> + }
>
> Indentation seems off here.
>>
>> +
>> + return result;
>> +}
>> +
>> +bool
>> +vtv_defuse_fn (tree var, gimple def_stmt, void *data)
>> +{
>> + bool retval = false;
>> +
>> + return retval;
>> +}
>
>
> Huh?
>
Another piece I meant to remove previously (sorry again).
>>
>> + for (; !gsi_end_p (gsi_virtual_call); gsi_next (&gsi_virtual_call))
>> + {
>> + stmt = gsi_stmt (gsi_virtual_call);
>> + if (is_vtable_assignment_stmt (stmt))
>> + {
>> + tree lhs = gimple_assign_lhs (stmt);
>> + tree vtbl_var_decl = NULL_TREE;
>> + struct vtbl_map_node *vtable_map_node;
>> + tree vtbl_decl = NULL_TREE;
>> + gimple call_stmt;
>> + struct gimplify_ctx gctx;
>> + const char *vtable_name = "<unknown>";
>> + tree tmp0;
>> + bool found;
>> +
>> + gsi_vtbl_assign = gsi_for_stmt (stmt);
>
> Why not use 'gsi_virtual_call'?
>
I really do want to use two separate iterators here. gsi_virtual_call
iterates linearly through all the statements in the basic block.
gsi_vtbl_assign gets moved around a bit, later down in the code, to
find the exact position for inserting the verification call.
>>
>> + if (TREE_CODE (vtbl_decl) == VAR_DECL)
>> + vtable_name = IDENTIFIER_POINTER (DECL_NAME (vtbl_decl));
>> +
>> + push_gimplify_context (&gctx);
>
> Not needed. You are not calling the gimplifier.
>
Ok.
>>
>> +
>> + if (!next_stmt)
>> + {
>> + pop_gimplify_context (NULL);
>
> Likewise.
Ok.
>
>>
>> + gsi_insert_after (&gsi_vtbl_assign, call_stmt,
>> + GSI_NEW_STMT);
>> +
>> + pop_gimplify_context (NULL);
>
> Likewise.
>
Ok.
>
> Diego.
prev parent reply other threads:[~2013-05-24 20:52 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-25 19:28 Caroline Tice
2013-03-07 23:55 ` Caroline Tice
2013-03-13 17:48 ` Diego Novillo
2013-05-24 20:52 ` Caroline Tice [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CABtf2+RUUcAmEj0=6ZTwJk1u=n67ga828_5UmyvBGqSNbRjCpw@mail.gmail.com' \
--to=cmtice@google.com \
--cc=bjanakiraman@google.com \
--cc=dnovillo@google.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=llozano@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).