From mboxrd@z Thu Jan 1 00:00:00 1970 From: Al Viro Subject: [RFC][bug?] "net/act_pedit: Introduce 'add' operation" is broken for anything wider than an octet Date: Wed, 15 Aug 2018 01:22:45 +0100 Message-ID: <20180815002245.GU6515@ZenIV.linux.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Amir Vadai , David Miller To: netdev@vger.kernel.org Return-path: Received: from zeniv.linux.org.uk ([195.92.253.2]:36876 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726837AbeHODM1 (ORCPT ); Tue, 14 Aug 2018 23:12:27 -0400 Content-Disposition: inline Sender: netdev-owner@vger.kernel.org List-ID: The code doing addition in that commit is + switch (cmd) { + case TCA_PEDIT_KEY_EX_CMD_SET: + val = tkey->val; + break; + case TCA_PEDIT_KEY_EX_CMD_ADD: + val = (*ptr + tkey->val) & ~tkey->mask; + break; + default: + pr_info("tc filter pedit bad command (%d)\n", + cmd); + goto bad; + } + + *ptr = ((*ptr & tkey->mask) ^ val); Any net-endian field wider than an octet will have the carry between octets handled wrong on little-endian hosts. Should we at least verify that ~mask fits into one octet? As it is, consider e.g. an attempt to subtract 1 from a 16bit field at offset 2 in a word. We want {0,0,0,1} (0x10000000 from host POV) to turn into 0, so the value to add would be 0xff000000. Except that {0, 0, 1, 0} would turn into {0, 0, 1, 0xff} that way, not the expected {0, 0, 0, 0xff}. Granted, there's not a lot of wider-than-octet fields where arithmetics would've made sense, but we probably ought to refuse allowing such operations. Especially since on big-endian hosts they will work just fine until you try to move that over to a little-endian box... Alternatively, we could do something like val = htonl(be32_to_cpup(ptr) + ntohl(tkey->val)) & ~tkey->mask; but I'm not sure if that's worth doing. It's not as if there would be a major overhead, but still... Comments?