快速业务通道

linux命令的参数个数限制

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-03-23

在某目录下rm * -f ,然后报了一个,参数长度过长,本来以为是rm报错,仔细看了一下原来是bash出错了,分析bash,bash这个东西貌似自己不会报这个东西,这个限制可能在glibc里面,然后搜索了下,发现了下面的一篇文章.

应该是参数buffer的大小限制.

google了一把,发现已经有人解决了,从中选出最佳答案,那就是本文首行的链接地址.
以作者的思路,确实可以解决实际问题,并且看到许多的实践者的反馈.
就这样的以解决问题为终结?也许我以前会这样就放弃了,但是这次不会,就像是 ext3固定分区后可以设置inode的数量最大为多少?
我这次同样也不会放弃.在开始之前需要准备三个软件,分别是:coreutils-6.12.tar.gz,bash-3.2.tar.gz,以及glibc-2.4.tar.gz.
思路是这样的,ls是coreutils中的程序,而报的错误是bash,但是bash并没有确定的错误信息是参数,而是属于posix标准的一个错误,那只有glibc了.
http://www.kernel.org/doc/man-pages/online/pages/man3/errno.3.html
我们可以看到如下一行内容:

E2BIG Argument list too long (POSIX.1)

在glibc中的sysdeps/gnu/errlist.c中可以看到如下语句:

/*

TRANS Argument list too long; used when the arguments passed to a new program

TRANS being executed with one of the @code{exec} functions (@pxref{Executing a

TRANS File}) occupy too much memory space. This condition never arises in the

TRANS GNU system. */

 [ERR_REMAP (E2BIG)] = N_("Argument list too long"),

# if E2BIG > ERR_MAX

# undef ERR_MAX

# define ERR_MAX E2BIG

# endif

#endif

#ifdef ENOEXEC

/*

好了,报错的信息找到根源了,是什么在使用glibc了呢?由上述参考得一定是kernel所报出的.

然后,就是到kernel-source中,寻找了.

make menuconfig找选项,或是grep .config均不能发现此项.

依然从错误的信息来查找kernel文件,则在include/asm-generic/errno-base.h:#define E2BIG 7 /* Argument list too long */

会看这么一行内容.

到此,本身功夫的欠缺,我已经无法查下去了,想象用户态陷入内核态,内核返回错误,这一系列复杂的过程.

只好跟着作者去读源码了:

include/linux/binfmt.h

struct pt_regs;



/*

 * These are the maximum length and maximum number of strings passed to the

 * execve() system call. MAX_ARG_STRLEN is essentially random but serves to

 * prevent the kernel from being unduly impacted by misaddressed pointers.

 * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer.

 */


拥有帝国一切,皆有可能。欢迎访问phome.net#define MAX_ARG_STRLEN (PAGE_SIZE * 32)

#define MAX_ARG_STRINGS 0x7FFFFFFF



/* sizeof(linux_binprm->buf) */

#define BINPRM_BUF_SIZE 128



#ifdef __KERNEL__



#define CORENAME_MAX_SIZE 128



/*

 * This structure is used to hold the arguments that are used when loading binaries.

 */

struct linux_binprm{

 char buf[BINPRM_BUF_SIZE];

#ifdef CONFIG_MMU

 struct vm_area_struct *vma;

#else

# define MAX_ARG_PAGES 32

 struct page *page[MAX_ARG_PAGES];

#endif

 struct mm_struct *mm;

 unsigned long p; /* current top of mem */

 int sh_bang;

 struct file * file;

 int e_uid, e_gid;

 kernel_cap_t cap_inheritable, cap_permitted;

红色部分即是限制参数的缓冲空间大小的参数,我们可以调节MAX_ARG_PAGES、BINPRM_BUF_SIZE 128
来设置具体的值.
更改内核确实是最直接、有效的方法,但是注意:
缺点也很明显,如果分配给命令行的内存大于可用的系统内存
,可能导致对系统自身的拒绝服务攻击( DoS attack ),引起系统崩溃.
尤其是对于多用户系统,即使增加很小
的内存分配都会有很大影响,每个用户都被分配到额外内存.
因此一定要充分测试来决定是否你的系统可以
使用此方法.

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号