Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753705AbbERJY6 (ORCPT ); Mon, 18 May 2015 05:24:58 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:30642 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752500AbbERJYs (ORCPT ); Mon, 18 May 2015 05:24:48 -0400 X-AuditID: cbfec7f5-f794b6d000001495-de-5559afdd3ab8 Message-id: <5559AFDA.3000808@samsung.com> Date: Mon, 18 May 2015 11:24:42 +0200 From: Krzysztof Opasiak User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-version: 1.0 To: Stefan Agner , balbi@ti.com, gregkh@linuxfoundation.org Cc: andrzej.p@samsung.com, m.szyprowski@samsung.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v3] usb: gadget: ether: Fix MAC address parsing References: <1431622254-24758-1-git-send-email-stefan@agner.ch> In-reply-to: <1431622254-24758-1-git-send-email-stefan@agner.ch> Content-type: text/plain; charset=windows-1252; format=flowed Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrJLMWRmVeSWpSXmKPExsVy+t/xy7p310eGGtw/IGMx62U7i8XB+/UW zYvXs1lc3jWHzWLRslZmi7VH7rJbbF7Xzu7A7rH4+z1mj/1z17B79G1Zxehx/MZ2Jo/Pm+QC WKO4bFJSczLLUov07RK4MtZuusBW8E224vH7nYwNjL/Euhg5OSQETCTaepYxQ9hiEhfurWfr YuTiEBJYyijxafYiZgjnOaPE7AMrWEGqeAW0JI7OPAfWwSKgKrFm8gugDg4ONgF9iXm7REHC ogIREvOPvWaGKBeU+DH5HgtIiYiAj8S9Hm6QMLNAnsSez0sZQWxhAWeJXxenM4HYQgL2Egdv HQSzOQUcJBa2TGKGqLeVWPB+HQuELS+xec1b5gmMArOQbJiFpGwWkrIFjMyrGEVTS5MLipPS c430ihNzi0vz0vWS83M3MUIC/OsOxqXHrA4xCnAwKvHwrvCLDBViTSwrrsw9xCjBwawkwvur GSjEm5JYWZValB9fVJqTWnyIUZqDRUmcd+au9yFCAumJJanZqakFqUUwWSYOTqkGxpUCN5Pb v0z067me+OsG08t3T4Xm7z4/42rWiy4xdm+BkOUZX8+/m1Pvt2Q174knK0SUeDdrm8f0m85s fPQz9e0cJmFunaozSmq3t5/OqbBcFK3epuxae+aObSHLzOUTylcn9rVNvfxw6U22kjviV2bN KG84kqZTEsHW4Fpk1tZ6v7/Te098nRJLcUaioRZzUXEiAJaKIbhsAgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3955 Lines: 125 Hello, On 05/14/2015 06:50 PM, Stefan Agner wrote: > MAC addresses can be written without leading zeros. A popular > example is libc's ether_ntoa_r function which creates such > MAC addresses. > > Example: > 00:14:3d:0f:ff:fe can be written as 0:14:3d:f:ff:fe > > The function get_ether_addr potentially also parsed past the > end of the user provided string. Use the opportunity and fix > the function to never parse beyond the end of the string while > allowing MAC addresses with and without leading zeros. Also > corner cases such as 00:14:3d:0f:ff:0 + new-line character > are parsed correctly. > > Signed-off-by: Stefan Agner > --- > Changes since v2: > - Fix parameter description > - Return with error if invalid charaters are part of the string > > drivers/usb/gadget/function/u_ether.c | 70 ++++++++++++++++++++++++++++------- > 1 file changed, 56 insertions(+), 14 deletions(-) > > diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c > index f1fd777..c71ab21 100644 > --- a/drivers/usb/gadget/function/u_ether.c > +++ b/drivers/usb/gadget/function/u_ether.c > @@ -703,25 +703,62 @@ static int eth_stop(struct net_device *net) > > /*-------------------------------------------------------------------------*/ > > +/** > + * get_ether_addr - parse ethernet address from string > + * @str: string to parse > + * @dev_addr: a buffer in which the parsed ethernet address will be > + * written > + * > + * Several common formats are supported: > + * 1) 00:14:3d:0f:ff:fe (no skipped 0, semicolons) > + * 2) 00.14.3d.0f.ff.fe (no skipped 0, dots) > + * 3) 00143d0ffffe (no skipped 0, no separator) > + * 4) 0:14:3d:f:ff:fe (skipped leading 0, semicolons) > + * 5) 0.14.3d.f.ff.fe (skipped leading 0, dots) > + * > + * The function will not cross the end of the provided string even > + * when the string has the wrong format. > + * > + * Returns 0 on success, or -EINVAL on error > + */ > static int get_ether_addr(const char *str, u8 *dev_addr) > { > - if (str) { > - unsigned i; > + int num, i; > > - for (i = 0; i < 6; i++) { > - unsigned char num; > + for (i = 0; i < ETH_ALEN; i++) { > + int j = 0; > > - if ((*str == '.') || (*str == ':')) > + dev_addr[i] = 0; > + while (*str) { > + char c = *str; > + > + if (c == '.' || c == ':') { > str++; > - num = hex_to_bin(*str++) << 4; > - num |= hex_to_bin(*str++); > - dev_addr [i] = num; > + break; > + } > + > + if (j >= 2) > + break; > + > + /* Ignore newline character, e.g. when using echo */ > + if (c == '\n') > + continue; Unfortunately this line causes livelock if user will place newline character in the middle of MAC address. For example: echo -e "0.14.3d.f\n\n\n.f\nf.fe" > host_addr When you find \n character you are going once again through loop but you are not moving to next character so c is still \n and will never change to anything else as it is incremented in very last line of this loop. In my opinion we should accept \n only at the end of input. > + > + num = hex_to_bin(c); > + if (num < 0) > + return num; > + > + dev_addr[i] <<= 4; > + dev_addr[i] |= num; > + j++; > + str++; > } I'm also not sure if it is a good idea to place 0 in mac address if string is too short. For example: echo -n 0.14.3d.f.ff which is too short MAC address (last byte is missing) will be parsed as 00:14:3d:0f:ff:00 and used as correct MAC address. If this is the way it should be, maybe place at least a comment about it as it was not obvious (at least for me) that too short mac address should be also accepted. Best regards, -- Krzysztof Opasiak Samsung R&D Institute Poland Samsung Electronics -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/