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

fix #1147 : init frag variable before use. #1162

Merged
merged 6 commits into from
Feb 12, 2019
Merged

Conversation

vankoven
Copy link
Contributor

Original PR is #1149

Copy link
Contributor

@krizhanovsky krizhanovsky left a comment

Choose a reason for hiding this comment

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

Looks good for me, but the fix is very subtle, so a review from @aleksostapenko is very wished.


BUG_ON(TFW_STR_DUP(data));
if (WARN_ON_ONCE(it->frag >= skb_shinfo(it->skb)->nr_frags))
return -E2BIG;
Copy link
Contributor

Choose a reason for hiding this comment

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

In case of *skb == skb_head in ss_skb_frag_next() we get here skb_head == it->skb and 0 == it->frag; so, condition it->frag >= skb_shinfo(it->skb)->nr_frags) probably will be false here and we continue execute all the following tfw_msg_write() calls without warnings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The scenario you've described may happen on subsequent tfw_msg_write() calls, which is very common case. So yes, the condition will false and we will continue to execute the function. But *skb == skb_head really means that we run out of the spare place in the skb fragments, and no more data can be pushed there. So if we continue to execute the function, we will walk through all the fragments once again and return -E2BIG error.

So there is no errors and the function can be called multiple times without any worries. The tfw_msg_write() function is used only for preallocated skbs, and data size is known before skb allocations, thus data should perfectly fit the it.

The reason for WARN_ON is invalid it state, where is it->frag points to nonexistent fragment.

frag = &skb_shinfo(it->skb)->frags[it->frag];
unsigned int f_size;
skb_frag_t *frag = &skb_shinfo(it->skb)->frags[it->frag];

Copy link
Contributor

@aleksostapenko aleksostapenko Jan 31, 2019

Choose a reason for hiding this comment

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

It seems that there is a problem with using skb header when allocating more than one skb - in tfw_http_msg_setup() each skb is allocated with a place under the header:

struct sk_buff *skb = alloc_skb(MAX_TCP_HEADER + n, GFP_ATOMIC);

but in tfw_msg_write() only the header of the first skb in list is used (it->frag < 0):
} else {

for subsequent skb it-> frag is always initialized to zero:

so then we always fall into the it->frag >= 0 branch.
Looks like the current master version of tfw_msg_write() has the same issue.

The function receives TfwMsgIter as argumrnt (as the arguments actually),
The 'skb' and 'f' point to specific fragment of the skb. If the condition
is false, then TfwMsgIter->skb and TfwMsgIter->frag may point to
unexisting skb fragment.
The issue was noticed in comment
#1169 (comment)
Anyway tfw_apm_update() in tfw_http_hm_drop_resp() doesn't look good.
Copy link
Contributor

@aleksostapenko aleksostapenko left a comment

Choose a reason for hiding this comment

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

Looks good to me (with https://github.com/tempesta-tech/tempesta/pull/1162/files#r252545944 will be fixed in other PR).

@vankoven vankoven merged commit c14a33b into master Feb 12, 2019
@vankoven vankoven deleted the ik-fix-uninited-var branch February 12, 2019 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants