Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754075AbbHYDMr (ORCPT ); Mon, 24 Aug 2015 23:12:47 -0400 Received: from mail-ig0-f177.google.com ([209.85.213.177]:37212 "EHLO mail-ig0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751352AbbHYDMp (ORCPT ); Mon, 24 Aug 2015 23:12:45 -0400 MIME-Version: 1.0 In-Reply-To: References: <20150824125902.4ba11ec6@gandalf.local.home> Date: Tue, 25 Aug 2015 11:12:44 +0800 Message-ID: Subject: Re: [PATCH] kernel/sysctl.c: If "count" including the terminating byte '\0' the write system call should retrun success. From: Sean Fu To: Steven Rostedt Cc: Andrey Ryabinin , Ulrich Obergfell , Prarit Bhargava , Eric B Munson , "Paul E. McKenney" , Johannes Weiner , "Eric W. Biederman" , Andrew Morton , Thomas Gleixner , Don Zickus , Heinrich Schuchardt , David Rientjes , linux-kernel@vger.kernel.org Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4289 Lines: 129 Call path is "proc_dointvec-->do_proc_dointvec-->__do_proc_dointvec-->proc_get_long". file: kernel/sysctl.c function: proc_get_long ... 1927 if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len)) //this line should accept two bytes "1\0". 1928 return -EINVAL; ... The latest upstream kernel is also tested, and it is same as 3.16.7 kernel. 3.16.7 kernel: sean@linux-dunz:~/work/suse_lab/proc_test> cat /proc/version Linux version 3.16.7-7-desktop (geeko@buildhost) (gcc version 4.8.3 20140627 [gcc-4_8-branch revision 212064] (SUSE Linux) ) #1 SMP PREEMPT Wed Dec 17 18:00:44 UTC 2014 (762f27a) sean@linux-dunz:~/work/suse_lab/proc_test> gcc ./proc_test.c -o proc_test sean@linux-dunz:~/work/suse_lab/proc_test> sudo ./proc_test enp0s25 Input: ./proc_test, enp0s25 file is: /proc/sys/net/ipv4/conf/enp0s25/rp_filter. open /proc/sys/net/ipv4/conf/enp0s25/rp_filter ok, fd=3 write 3: len=-1, errno=22, Invalid argument 2.6.16.60 kernel: linux-8lij:~ # gcc ./proc_test.c -o ./proc_test linux-8lij:~ # cat /proc/version Linux version 2.6.16.60-0.83.2-bigsmp (geeko@buildhost) (gcc version 4.1.2 20070115 (SUSE Linux)) #1 SMP Fri Sep 2 13:49:16 UTC 2011 linux-8lij:~ # gcc ./proc_test.c -o ./proc_test linux-8lij:~ # ./proc_test eth7 Input: ./proc_test, eth7 file is: /proc/sys/net/ipv4/conf/eth7/rp_filter. open /proc/sys/net/ipv4/conf/eth7/rp_filter ok, fd=3 write 3: len=1, errno=0, Success On Tue, Aug 25, 2015 at 8:57 AM, Sean Fu wrote: > An application from HuaWei which works fine on 2.6 encounters this > issue on 3.0 or later kernel. > > Test code: > > #include > #include > #include > #include > #include > #include > #include > > #define MAXLEN (100) > > int main(int argc, char** argv) > { > int fd = 0; > int len = 0; > char pathname[MAXLEN] = {0}; > char buf[2] = {0}; > int ret = 0xF; > int value = 0xF; > > if (argc < 2) > { > printf("Input param error, less 2 param: %s, %s.\n", > argv[0], argv[1]); > return 1; > } > > printf("Input: %s, %s \n", argv[0], argv[1]); > > ret = sprintf(pathname, > "/proc/sys/net/ipv4/conf/%s/rp_filter", argv[1]); > if (ret < 0) > printf("sprintf error, errno %d, %s\n", errno, strerror(errno)); > printf("file is: %s. \n", pathname); > > fd = open(pathname, O_RDWR, S_IRUSR); > if (fd <=0 ) > { > printf("open %s failed, errno=%d, %s.\n", pathname, > errno, strerror(errno)); > return 1; > } > printf("open %s ok, fd=%d\n", pathname, fd); > > len = write(fd, "0\0", 2); > printf("write %d: len=%d, errno=%d, %s\n", fd, len, errno, > strerror(errno)); > > close(fd); > return 0; > } > > On Tue, Aug 25, 2015 at 12:59 AM, Steven Rostedt wrote: >> On Mon, 24 Aug 2015 16:56:13 +0800 >> Sean Fu wrote: >> >>> when the input argument "count" including the terminating byte "\0", >>> The write system call return EINVAL on proc file. >>> But it return success on regular file. >>> >>> E.g. Writting two bytes ("1\0") to "/proc/sys/net/ipv4/conf/eth0/rp_filter". >>> write(fd, "1\0", 2) return EINVAL. >> >> And what would do that? What tool broke because of this? >> >> echo 1 > /proc/sys/net/ipv4/conf/eth0/rp_filter >> >> works just fine. strlen("string") would not include the nul character. >> The only thing I could think of would be a sizeof(str), but then that >> would include someone hardcoding an integer in a string, like: >> >> char val[] = "1" >> >> write(fd, val, sizeof(val)); >> >> Again, what tool does that? >> >> If there is a tool out in the wild that use to work on 2.6 (and was >> running on 2.6 then, and not something that was created after that >> change), then we can consider this fix. >> >> -- Steve -- 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/