Commit dedd0a9e authored by tsepez@chromium.org's avatar tsepez@chromium.org

Implement off-the-wire validation scheme for emum types.

This CL adds explicit IPC macros that can be used to ensure that the values being read off the wire are legitimate for
the enum type.  


BUG=176110
R=jam@chromium.org

Review URL: https://chromiumcodereview.appspot.com/15841011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203892 0039d316-1c4b-4281-b951-d872f2087c98
parent d966f777
......@@ -11,7 +11,7 @@
#include "chrome/common/content_settings.h"
#include "ipc/ipc_message_macros.h"
IPC_ENUM_TRAITS(ContentSetting)
IPC_ENUM_TRAITS(ContentSettingsType)
IPC_ENUM_TRAITS_MAX_VALUE(ContentSetting, CONTENT_SETTING_NUM_SETTINGS - 1)
IPC_ENUM_TRAITS_MAX_VALUE(ContentSettingsType, CONTENT_SETTINGS_NUM_TYPES - 1)
#endif // CHROME_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
......@@ -510,13 +510,11 @@ class PickleCracker : public Pickle {
#include "ipc/ipc_message_null_macros.h"
// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent)\
IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
IPC_STRUCT_TRAITS_BEGIN(struct_name)
#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
......@@ -540,8 +538,8 @@ class PickleCracker : public Pickle {
} \
};
#undef IPC_ENUM_TRAITS
#define IPC_ENUM_TRAITS(enum_name) \
#undef IPC_ENUM_TRAITS_VALIDATE
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
template <> \
struct FuzzTraits<enum_name> { \
static void Fuzz(enum_name* p, IPC::Fuzzer* fuzzer) { \
......
......@@ -130,7 +130,9 @@
// to proclaim equivalent struct declarations for use by callers, as well
// as later registering the type with the message generation. Note that
// IPC_STRUCT_MEMBER() is only permitted inside matching calls to
// IPC_STRUCT_BEGIN() / IPC_STRUCT_END().
// IPC_STRUCT_BEGIN() / IPC_STRUCT_END(). There is also an
// IPC_STRUCT_BEGIN_WITH_PARENT(), which behaves like IPC_STRUCT_BEGIN(),
// but also accomodates structs that inherit from other structs.
//
// Externally-defined structs are registered with IPC_STRUCT_TRAITS_BEGIN(),
// IPC_STRUCT_TRAITS_MEMBER(), and IPC_STRUCT_TRAITS_END() macros. These
......@@ -141,8 +143,16 @@
// inside matching calls to IPC_STRUCT_TRAITS_BEGIN() /
// IPC_STRUCT_TRAITS_END().
//
// Enum types are registered with a single IPC_ENUM_TRAITS() macro. There
// is no need to enumerate each value to the IPC mechanism.
// Enum types are registered with a single IPC_ENUM_TRAITS_VALIDATE() macro.
// There is no need to enumerate each value to the IPC mechanism. Instead,
// pass an expression in terms of the parameter |value| to provide
// range-checking. For convenience, the IPC_ENUM_TRAITS() is provided which
// performs no checking, passing everything including out-of-range values.
// Its use is discouraged. The IPC_ENUM_TRAITS_MAX_VALUE() macro can be used
// for the typical case where the enum must be in the range 0..maxvalue
// inclusive. The IPC_ENUM_TRAITS_MIN_MAX_VALUE() macro can be used for the
// less typical case where the enum must be in the range minvalue..maxvalue
// inclusive.
//
// Do not place semicolons following these IPC_ macro invocations. There
// is no reason to expect that their expansion corresponds one-to-one with
......@@ -192,9 +202,12 @@
#include "ipc/ipc_message_utils_impl.h"
#endif
// Macros for defining structs. May be subsequently redefined.
// Convenience macro for defining structs without inheritence. Should not need
// to be subsequently redefined.
#define IPC_STRUCT_BEGIN(struct_name) \
IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, IPC::NoParams)
// Macros for defining structs. Will be subsequently redefined.
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
struct struct_name; \
IPC_STRUCT_TRAITS_BEGIN(struct_name) \
......
......@@ -6,7 +6,6 @@
// NULL out all the macros that need NULLing, so that multiple includes of
// the XXXX_messages_internal.h files will not generate noise.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
......@@ -14,10 +13,9 @@
#undef IPC_STRUCT_TRAITS_MEMBER
#undef IPC_STRUCT_TRAITS_PARENT
#undef IPC_STRUCT_TRAITS_END
#undef IPC_ENUM_TRAITS
#undef IPC_ENUM_TRAITS_VALIDATE
#undef IPC_MESSAGE_DECL
#define IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent)
#define IPC_STRUCT_MEMBER(type, name, ...)
#define IPC_STRUCT_END()
......@@ -25,7 +23,7 @@
#define IPC_STRUCT_TRAITS_MEMBER(name)
#define IPC_STRUCT_TRAITS_PARENT(type)
#define IPC_STRUCT_TRAITS_END()
#define IPC_ENUM_TRAITS(enum_name)
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression)
#define IPC_MESSAGE_DECL(sync, kind, msg_class, \
in_cnt, out_cnt, in_list, out_list)
......@@ -11,13 +11,11 @@
#include "ipc/ipc_message_null_macros.h"
// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
IPC_STRUCT_TRAITS_BEGIN(struct_name)
#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
......@@ -44,8 +42,8 @@
l->append(")"); \
}
#undef IPC_ENUM_TRAITS
#define IPC_ENUM_TRAITS(enum_name) \
#undef IPC_ENUM_TRAITS_VALIDATE
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
void ParamTraits<enum_name>::Log(const param_type& p, std::string* l) { \
LogParam(static_cast<int>(p), l); \
}
......
......@@ -23,8 +23,27 @@
#define IPC_STRUCT_TRAITS_PARENT(type)
#define IPC_STRUCT_TRAITS_END()
// Traits generation for enums.
#define IPC_ENUM_TRAITS(enum_name) \
// Convenience macro for defining enumerated type traits for types which are
// not range-checked by the IPC system. The author of the message handlers
// is responsible for all validation. This macro should not need to be
// subsequently redefined.
#define IPC_ENUM_TRAITS(type) \
IPC_ENUM_TRAITS_VALIDATE(type, true)
// Convenience macro for defining enumerated type traits for types which are
// range-checked by the IPC system to be in the range of 0..maxvalue inclusive.
// This macro should not need to be subsequently redefined.
#define IPC_ENUM_TRAITS_MAX_VALUE(type, maxvalue) \
IPC_ENUM_TRAITS_MIN_MAX_VALUE(type, 0, maxvalue)
// Convenience macro for defining enumerated type traits for types which are
// range-checked by the IPC system to be in the range of minvalue..maxvalue
// inclusive. This macro should not need to be subsequently redefined.
#define IPC_ENUM_TRAITS_MIN_MAX_VALUE(type, minvalue, maxvalue) \
IPC_ENUM_TRAITS_VALIDATE(type, (value >= (minvalue) && value <= (maxvalue)))
// Traits generation for enums. This macro may be redefined later.
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
namespace IPC { \
template <> \
struct IPC_MESSAGE_EXPORT ParamTraits<enum_name> { \
......
......@@ -9,13 +9,11 @@
#include "ipc/ipc_message_null_macros.h"
// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
IPC_STRUCT_TRAITS_BEGIN(struct_name)
#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
......@@ -32,14 +30,16 @@
#define IPC_STRUCT_TRAITS_PARENT(type) ParamTraits<type>::Read(m, iter, p) &&
#define IPC_STRUCT_TRAITS_END() 1; }
#undef IPC_ENUM_TRAITS
#define IPC_ENUM_TRAITS(enum_name) \
#undef IPC_ENUM_TRAITS_VALIDATE
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
bool ParamTraits<enum_name>:: \
Read(const Message* m, PickleIterator* iter, param_type* p) { \
int type; \
if (!m->ReadInt(iter, &type)) \
int value; \
if (!m->ReadInt(iter, &value)) \
return false; \
*p = static_cast<param_type>(type); \
if (!(validation_expression)) \
return false; \
*p = static_cast<param_type>(value); \
return true; \
}
......
......@@ -9,13 +9,11 @@
#include "ipc/ipc_message_null_macros.h"
// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
IPC_STRUCT_TRAITS_BEGIN(struct_name)
#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
......@@ -30,10 +28,11 @@
#define IPC_STRUCT_TRAITS_PARENT(type) ParamTraits<type>::Write(m, p);
#define IPC_STRUCT_TRAITS_END() }
#undef IPC_ENUM_TRAITS
#define IPC_ENUM_TRAITS(enum_name) \
void ParamTraits<enum_name>::Write(Message* m, const param_type& p) { \
m->WriteInt(static_cast<int>(p)); \
#undef IPC_ENUM_TRAITS_VALIDATE
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
void ParamTraits<enum_name>::Write(Message* m, const param_type& value) { \
DCHECK(validation_expression); \
m->WriteInt(static_cast<int>(value)); \
}
#endif // IPC_PARAM_TRAITS_WRITE_MACROS_H_
......
......@@ -9,11 +9,9 @@
#include "ipc/ipc_message_null_macros.h"
// Set up so next include will generate constructors.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
#define IPC_STRUCT_BEGIN(struct_name) struct_name::struct_name() : NoParams()
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
struct_name::struct_name() : parent()
#define IPC_STRUCT_MEMBER(type, name, ...) , name(__VA_ARGS__)
......
......@@ -9,11 +9,9 @@
#include "ipc/ipc_message_null_macros.h"
// Set up so next include will generate destructors.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN(struct_name) struct_name::~struct_name() {}
struct_name::~struct_name() {}
#endif // IPC_STRUCT_DESTRUCTOR_MACROS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment