From: Ron Yorston
> Sent: 26 April 2022 16:10
> 
> A user reports:
> 
>    I know this code is wrong but it shouldn't cause the shell to exit:
>    echo text >&9999
>    This instead cause the creation of a file:
>    echo text >&9999999999
> 
>    I think it would be better if they report Bad file descriptor
> 
> The first case happens because save_fd_on_redirect() causes an exit
> when dup_CLOEXEC() returns any error other than EBADF.  Despite its
> name dup_CLOEXEC() actually uses fcntl(2) which returns EINVAL when
> the file descriptor is greater than the maximum allowed.
> 
> The second case is due to any numeric string longer than nine digits
> being treated as a file name rather than a number.  Bash doesn't
> do this.
...
> @@ -9635,7 +9634,7 @@ expredir(union node *n)
>                               if (fn.list == NULL)
>                                       ash_msg_and_raise_error("redir error");
>  #if BASH_REDIR_OUTPUT
> -                             if (!isdigit_str9(fn.list->text)) {
> +                             if (!isdigit_str(fn.list->text)) {
>                                       /* >&file, not >&fd */
>                                       if (redir->nfile.fd != 1) /* 123>&file 
> - BAD */
>                                               ash_msg_and_raise_error("redir 
> error");
> @@ -11945,19 +11944,21 @@ static void
>  fixredir(union node *n, const char *text, int err)
>  {
>       int fd;
> +     struct rlimit limit;
> 
>       TRACE(("Fix redir %s %d\n", text, err));
>       if (!err)
>               n->ndup.vname = NULL;
> 
> +     getrlimit(RLIMIT_NOFILE, &limit);

Doing an extra system call seems suboptimal.
Why not just allow EINVAL as equivalent to EBADF later on?

>       fd = bb_strtou(text, NULL, 10);

Can't you do this conversion earlier and check the 'unconverted'
character for being '\0'?
Would save scanning the string twice.

> -     if (!errno && fd >= 0)
> +     if (!errno && fd >= 0 && fd < limit.rlim_cur - 1)
>               n->ndup.dupfd = fd;
>       else if (LONE_DASH(text))
>               n->ndup.dupfd = -1;
>       else {
>               if (err)
> -                     raise_error_syntax("bad fd number");
> +                     raise_error_syntax(strerror(EBADF));
>               n->ndup.vname = makename();
...

        David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to