Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address comments from PR 812: Add check before deserializing messages #816

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions common/events_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,6 @@ struct serialization
int
deserialize(const string& s, Map& data)
{
if (s.size() < 2) { // zmq identifying message of length 1
return 0;
}
try {
istringstream ss(s);
boost::archive::text_iarchive iarch(ss);
Expand Down Expand Up @@ -312,7 +309,8 @@ struct serialization
more = 0;
zmq_msg_init(&msg);
int rc = zmq_msg_recv(&msg, sock, flag);
if (rc != -1) {
size_t msg_size = zmq_msg_size(&msg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I check eventd code, it's not use zmq_read_part, how this change can fix the original eventd issue.

Copy link
Contributor

@liuh-80 liuh-80 Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By read eventd code, I found it's a code bug in channel read, please check following code and fix it:

int
event_service::channel_read(int &code, event_serialized_lst_t &data)
{
event_serialized_lst_t().swap(data);
return zmq_message_read(m_socket, 0, code, data); <== code is a int*
}

template<typename P1, typename P2>
int
zmq_message_read(void *sock, int flag, P1 &pt1, P2 &pt2)
{
auto render = boost::serialization::singleton::get_const_instance();

return render.zmq_message_read(sock, flag, pt1, pt2); <-- pt1 is a int*

}

template<typename P1, typename P2>
int
zmq_message_read(void *sock, int flag, P1 &pt1, P2 &pt2)
{
    int more = 0, rc, rc2 = 0;

    rc = zmq_read_part(sock, flag, more, pt1); <== pt1 is a int*

    if (more) {
        /*
         * read second part if more is set, irrespective
         * of any failure. More is set, only if sock is valid.
         */
        rc2 = zmq_read_part(sock, 0, more, pt2);
    }




template<typename DT>
int 
zmq_read_part(void *sock, int flag, int &more, DT &data) <== data maybe a int*
{
    zmq_msg_t msg;

    more = 0;
    zmq_msg_init(&msg);
    int rc = zmq_msg_recv(&msg, sock, flag);
    if (rc != -1) {
        size_t more_size = sizeof (more);

        zmq_getsockopt (sock, ZMQ_RCVMORE, &more, &more_size);

        rc = zmsg_to_map(msg, data); <== data here maybe a int* and msg maybe a int
        RET_ON_ERR(rc == 0, "Failed to deserialize part rc=%d", rc);
        /* read more flag if message read fails to de-serialize */
    }



template <typename Map>
int
zmsg_to_map(zmq_msg_t &msg, Map& data)
{
    string s((const char *)zmq_msg_data(&msg), zmq_msg_size(&msg));
    return deserialize(s, data); <== may try to deserialize a int data to a int pointer
}

Copy link
Contributor

@liuh-80 liuh-80 Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May not related with original issue, suggest create UT in other PR to fix.
#closed

if (rc != -1 && msg_size > 1) {
size_t more_size = sizeof (more);

zmq_getsockopt (sock, ZMQ_RCVMORE, &more, &more_size);
Expand Down
11 changes: 8 additions & 3 deletions tests/events_common_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,24 @@ TEST(events_common, send_recv)
void *sock_p1 = zmq_socket (zmq_ctx, ZMQ_PAIR);
EXPECT_EQ(0, zmq_bind (sock_p1, path));

string source("Hello"), source1, source2("#");
string source("Hello"), source1, source2, source3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ut can pass without any code change in zmq_read_part, which means the UT change is not necessary.

Copy link
Contributor

@liuh-80 liuh-80 Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By read the eventd code, I found it's using event_service.
So you need create new UT to cover channel_read in https://github.com/sonic-net/sonic-swss-common/blob/master/tests/events_service_ut.cpp

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion offline ,suggest revert this PR.


map<string, string> m = {{"foo", "bar"}, {"hello", "world"}, {"good", "day"}};
map<string, string> m1, m2;
map<string, string> m1, m2, m3;

EXPECT_EQ(0, zmq_message_send(sock_p0, source, m));

EXPECT_EQ(0, zmq_message_read(sock_p1, 0, source1, m1));

EXPECT_EQ(source, source1);
EXPECT_EQ(m, m1);


EXPECT_EQ(0, zmq_message_send(sock_p0, source2, m2));
EXPECT_EQ(0, zmq_message_read(sock_p1, 0, source3, m3));

EXPECT_EQ(0, deserialize(source2, m2));
EXPECT_EQ(source2, source3);
EXPECT_EQ(m2, m3);

zmq_close(sock_p0);
zmq_close(sock_p1);
Expand Down