Re: "here strings" and tmpfiles

2019-03-19 Thread Greg Wooledge
On Mon, Mar 18, 2019 at 05:18:10PM -0400, Daniel Kahn Gillmor wrote:
> strace -o tmp/bash.herestring.strace -f bash -c 'cat <<<"hello there"'
> It turns out that this creates a temporary file, actually touching the
> underlying filesystem:

Yes, just like here documents do.  And have always done, in all shells.

> For example, sending a password or secret key material from the
> environment to stdin would be a typical way to use a herestring.

Note that the environment may also be visible to users on the system,
via "ps eww aux" or similar commands.  The availability of the BSD ps(1)
options and the details about who can see what are OS-specific.

> A few possible options for trying to improve the situation:

Don't put sensitive data in shell scripts?

In general:

1) Do not pass secrets as arguments to external commands.  The arguments
   of a command are generally visible in ps(1).

2) Do not pass secrets as environment variables.  The initial environment
   of a process is generally visible in ps(1).

3) Read the documentation of the thing you're trying to authenticate
   against.  Find out the various ways it can accept authentication
   secrets/tokens and choose the most appropriate.  This may mean using
   ssh keys stored in an ssh-agent, etc.

4) If something requires a password, let it prompt the user for the
   password by itself.  Just run it inside a terminal so that it can
   launch a dialog with the end user if required.  Do not try to "help"
   it by storing the password in your script and then trying to figure
   out how to circumvent its security in order to pass the password to it.

5) If you absolutely MUST store a password somewhere on disk, don't
   store it inside the shell script.  Shell scripts must have read
   permissions in order to be used.  Store the password in a separate
   file that doesn't have universal read permission, and let the
   appropriate process read that file.  The appropriate process may be
   your script in rare cases, but more often it'll be whatever program
   is actually going to use that password.

Thus, there is absolutely no reason you should ever have a secret password
inside a here document or here string.  That would mean the password
is hard-coded inside a shell script, which violates several of my points.

If the password has been read from a file and is now inside a shell
variable (NOT environment variable) in memory, and you want to pass it
on stdin to a process, you do that by running something like

printf %s\\n "$secret" | program

No here strings are wanted.  printf is a builtin, so you aren't violating
point 1.  $secret is not exported, so you aren't violating point 2.

https://mywiki.wooledge.org/BashFAQ/069 and
https://mywiki.wooledge.org/BashFAQ/078 also touch on this, but they
could both use some expansion/rewriting, I see.



cd "" return value

2019-03-19 Thread furrymcgee


Good morning,  

In GNU bash, version 5.0.2(1)-release (x86_64-pc-linux-gnu):
The command cd "" is successful but cd -P "" fails.
This is inconsistent and not evident in man bash.
Expected is that cd "$(mktemp -d)" returns error if mktemp fails.

BASH(1)

cd
...
The  return  value  is  true  if  the directory was successfully
changed; false otherwise.




Re: "here strings" and tmpfiles

2019-03-19 Thread Daniel Kahn Gillmor
On Mon 2019-03-18 17:18:10 -0400, Daniel Kahn Gillmor wrote:
> A few possible options for trying to improve the situation:
>
>  a) use socketpair(2) or pipe(2) instead of making a tmpfile.  this has
> the potential downside that the semantics of access to the remaining
> file descriptor would be subtly different from "regular file"
> semantics.
>
>  b) On systems that support O_TMPFILE, try something like
> open("/dev/shm", O_RDWR|O_CREAT|O_EXCL|O_TMPFILE).  /dev/shm tends
> to be a globally-writable tmpfs, so that avoids touching any disk,
> and O_TMPFILE avoids tmpfile-style race conditions.  This might need
> a fallback (to the current tmpdir selection mechanics?) in case
> /dev/shm isn't available.
>
>  c) Just use O_TMPFILE with the current tmpdir selection mechanics, if
> it's supported.  This isn't quite as clever as trying to use
> /dev/shm first, and it won't fix the herestrings hitting the disk,
> but it at least avoids tmpfile races.
>
>  d) If none of the above can be done, at the very least, bash(1)'s
> section on here docs and here strings should warn that the contents
> of these documents are likely to get written to the disk
> unprotected.

One more possibility for an implementation fix occurs to me (at least on
systems with Linux >= 3.17 and glibc >= 2.27):

 e) bash could use use memfd_create(2) for heredocs and herestrings --
that should preserve "regular file" semantics, avoid tmpfile races,
and avoid hitting the disks.

--dkg


signature.asc
Description: PGP signature


Re: "here strings" and tmpfiles

2019-03-19 Thread Daniel Kahn Gillmor
Thanks for the feedback, Eduardo--

On Mon 2019-03-18 17:40:17 -0700, Eduardo A. Bustamante López wrote:
> I don't think the implementation details of herestrings are documented 
> anywhere,
> and I'm not too sure if they should (i.e. IMO if you need that degree of 
> control
> over the implementation details, then you should use something other than
> shell).

I hear you in general -- i also don't want the documentation to be as
detailed as the source code.  But casually sending ephemeral data to
disk is a risk that i think ought to be avoided or at least avoidable.
If bash was in the habit of writing the environment to disk, i think
users would rightly complain.

> Having said that, have you tried process substitution as an option?

sure, that's an option (as long as process substitution is enabled on
the platform -- apparently that's not universal either).  Also possible
(for stdin in particular) is sending data via a pipeline using bash
builtins.  Both of these require users of bash to rewrite their scripts
though.

It seems like it'd be preferable for the shell itself to avoid these
problems automatically, at least on platforms where it's possible to do
so.  Otherwise, we *require* users of the shell to know which things are
"safe" and which things aren't before they can use the shell safely.

  --dkg



Re: "here strings" and tmpfiles

2019-03-19 Thread Greg Wooledge
On Tue, Mar 19, 2019 at 09:20:33AM -0400, Daniel Kahn Gillmor wrote:
> On Tue 2019-03-19 08:25:50 -0400, Greg Wooledge wrote:
> > On Mon, Mar 18, 2019 at 05:18:10PM -0400, Daniel Kahn Gillmor wrote:
> >> strace -o tmp/bash.herestring.strace -f bash -c 'cat <<<"hello there"'
> >> It turns out that this creates a temporary file, actually touching the
> >> underlying filesystem:
> >
> > Yes, just like here documents do.  And have always done, in all shells.
> 
> Apologies for being unaware of the history.  It looks like there are a
> handful of possible approaches today that minimize these fixes, which
> may not have been possible on older systems, which i listed upthread.
> And they work on arbitrary file descriptors, not just stdin.
> 
> Do you think that bash should not improve the situation, at least on
> platforms that support these other approaches?

There are scripts that *rely* on the seekability of the temporary files
created by here-documents and here-strings.  "Improving" the "situation"
would break backward compatibility.

I already showed how to use a pipeline to send information from a shell
variable to another process's stdin without using a here-string (which
is a bashism that is much less portable than the pipeline, in addition
to being less "safe" in the incredibly narrow niche situation being
described in this thread).

There is simply NO valid reason to write <<<"$secret" in a script, and
thus there is no need to "improve" anything other than the scripts
that are doing that.  Use a pipe instead.



Re: "here strings" and tmpfiles

2019-03-19 Thread Daniel Kahn Gillmor
On Tue 2019-03-19 08:25:50 -0400, Greg Wooledge wrote:
> On Mon, Mar 18, 2019 at 05:18:10PM -0400, Daniel Kahn Gillmor wrote:
>> strace -o tmp/bash.herestring.strace -f bash -c 'cat <<<"hello there"'
>> It turns out that this creates a temporary file, actually touching the
>> underlying filesystem:
>
> Yes, just like here documents do.  And have always done, in all shells.

Apologies for being unaware of the history.  It looks like there are a
handful of possible approaches today that minimize these fixes, which
may not have been possible on older systems, which i listed upthread.
And they work on arbitrary file descriptors, not just stdin.

Do you think that bash should not improve the situation, at least on
platforms that support these other approaches?

--dkg


signature.asc
Description: PGP signature


Re: cd "" return value

2019-03-19 Thread Chet Ramey
On 3/19/19 4:21 AM, furrymc...@lippydanger.jumpingcrab.com wrote:
> 
> Good morning,  
> 
> In GNU bash, version 5.0.2(1)-release (x86_64-pc-linux-gnu):
> The command cd "" is successful but cd -P "" fails.
> This is inconsistent and not evident in man bash.
> Expected is that cd "$(mktemp -d)" returns error if mktemp fails.

This is a consequence of the pathname canonicalization that takes place
using the supplied argument, because the -L option is the default. Pretty
much every POSIX-conformant shell behaves like this.

>   The  return  value  is  true  if  the directory was successfully
>   changed; false otherwise.

After canonicalization, it's equivalent to cd $PWD, which is successful.
The -P option forces an attempt to cd to "" directly, which fails because
chdir(2) fails with ENOENT when its argument is the empty string.


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: "here strings" and tmpfiles

2019-03-19 Thread Robert Elz
Date:Tue, 19 Mar 2019 08:25:50 -0400
From:Greg Wooledge 
Message-ID:  <20190319122550.khv5jp66iobjo...@eeg.ccf.org>

  | Yes, just like here documents do.  And have always done, in all shells.

That's not correct.   There are shells that don't use files for here
docs.   Any application that relies on stdin being seekable is broken
(unless it makes that happen for itself) - the most obvious example
which is not seekable is when stdin is a terminal.

The same applies to any other file descriptor which is opened when
an application is started.

POSIX (XCU section 2.7.4) explicitly says (of here docs):

It is unspecified whether the file descriptor is opened as a
regular file, a special file, or a pipe. Portable applications
cannot rely on the file descriptor being seekable (see XSH lseek( )).

Note: I am not suggesting bash should change - using files for here docs
is the way they were originally implemented (in the Bourne sh) (though it
had bugs, which could leave the files lying around in some cases).

However, using files for here docs makes here docs unusable in a shell
running in single user mode with no writable filesystems (whatever is
mounted is read only, until after file system checks are finished).

kre