Change proc/<pid>/cmdline to 8k

Navin P navinp1912 at gmail.com
Thu Jun 4 23:21:03 EDT 2015


On Fri, Jun 5, 2015 at 3:49 AM,  <Valdis.Kletnieks at vt.edu> wrote:
> On Thu, 04 Jun 2015 21:06:10 +0530, Navin P said:
>> have this 3rd party application with deeply mounted dir that runs as a
>> testcase more than 5k chars . We can change it , i thought if that was
>> the problem ?
>
> So why is a long commandline a problem that needs solving? Are you actually
> caring what the command line says?  If so, why?
>
> Hint: There's no guarantee that your commandline contain the actual full
> command string.  Consider this on an x86_84 kernel (yes, my $HOME does
> need a good cleaning))
>
> % /bin/echo * | wc
>       1    1884   25797
>
> 1,884 parameters in argv[], totalling some 24K of data.  Which means that
> 20k isn't displayable.  And extending it to 64k won't fix the problem, as
> demonstrated by looking at a rather large mail folder I have:
>
> % /bin/echo ietf/* | wc
>       1   62257  673721
>
> OK, how far can we take this?
>
> %  echo | xargs --show-limits echo
> Your environment variables take up 1918 bytes
> POSIX upper limit on argument length (this system): 2093186
> POSIX smallest allowable upper limit on argument length (all systems): 4096
> Maximum length of command we could actually use: 2091268
> Size of command buffer we are actually using: 131072
>
> Apparently, up to 2M or so...
>
> So what problem are you trying to solve, and why?

Thanks.

In fs/proc/base.c

static int proc_pid_cmdline(struct seq_file *m, struct pid_namespace *ns,
200                             struct pid *pid, struct task_struct *task)
201 {
202         /*
203          * Rely on struct seq_operations::show() being called once
204          * per internal buffer allocation. See single_open(), traverse().
205          */
206         BUG_ON(m->size < PAGE_SIZE);
207         m->count += get_cmdline(task, m->buf, PAGE_SIZE);
208         return 0;
209 }


396 int get_cmdline(struct task_struct *task, char *buffer, int buflen)
397 {
398         int res = 0;
399         unsigned int len;
400         struct mm_struct *mm = get_task_mm(task);
401         if (!mm)
402                 goto out;
403         if (!mm->arg_end)
404                 goto out_mm;    /* Shh! No looking before we're done */
405
406         len = mm->arg_end - mm->arg_start;
407
408         if (len > buflen)
409                 len = buflen;

We are truncating the cmdline to PAGE_SIZE in mm/util.c

I did created a program that prints argv[1] and counts wc -c ie
./longarg 12345...5k | wc -c you get 4096  on i686.

I also need this for things like  perl -e 'running code' that is
longer and i want to grep for some strings that are present at the end
so the code can be around 5k-8k by multiple users.



More information about the Kernelnewbies mailing list