bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] allow file modes up to 7777 instead of 777


From: Martijn Dekker
Subject: [PATCH] allow file modes up to 7777 instead of 777
Date: Wed, 14 Mar 2018 16:49:55 +0100
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

This fixes two bugs:

1. The example 'mkdir' builtin, examples/loadables/mkdir.c, has a broken
'-m' option that doesn't accept sticky/setuid/setgid.

$ ./bash -c '(cd examples/loadables && make mkdir) &&
        enable -f examples/loadables/mkdir mkdir &&
        mkdir -m2775 foo'
['make' output skipped]
./bash: line 2: mkdir: invalid file mode: 2775

2. The 'umask' builtin doesn't accept modes > 0777.

$ ./bash -c 'umask 7777'
./bash: line 0: umask: 7777: octal number out of range

While POSIX says the effect of specifying sticky/setuid/setgid bits is
unspecified[*], the 'umask' builtin should still accept these bits, as
it does in every other shell.

It is also not consistent as bash will happily inherit an umask of 7777
from another process. For example:
$ ksh -c 'umask 7777; bash -c "umask"'
7777
This is on MacOS and the BSDs; Linux seems to clear the first 8 bits at
the kernel level, so '0777' is output. That is a Linux-specific
constraint, though, and bash should still not accept through one route
what it rejects through another.

Patch:

diff --git a/builtins/common.c b/builtins/common.c
index a5f2584..0752f0d 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -537,7 +537,7 @@ read_octal (string)
     {
       digits++;
       result = (result * 8) + (*string++ - '0');
-      if (result > 0777)
+      if (result > 07777)
        return -1;
     }

By the way, why does that function repeatedly check the bounds for every
digit? Wouldn't this be more efficient:

diff --git a/builtins/common.c b/builtins/common.c
index a5f2584..6f1273f 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -537,11 +537,9 @@ read_octal (string)
     {
       digits++;
       result = (result * 8) + (*string++ - '0');
-      if (result > 0777)
-       return -1;
     }

-  if (digits == 0 || *string)
+  if (digits == 0 || *string || result > 07777)
     result = -1;

   return (result);

Note: parse.y also uses read_octal() for $PS1, but it enforces a
three-character limit, so it's inherently limited to octal 777 and the
bounds check change in read_octal() doesn't affect it. I cannot find any
other uses of read_octal().

Thanks,

- M.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]