For example, if I have the file hello.c which just contains:

int main() {
   printf("Hello world");
   return 0;

and I built it in gcc with gcc hello.c -o hello I can then run ./hello and it runs.

However, if I try to download a binary from the web with e.g. curl, I first have to set the permissions with chmod before I can run it. Is there a reason why? Do gcc and/or curl set some default permissions on the files?

  • did you get your question answered? If yes please accept one of the answers to reward the respondents for the time they spent answering you. Thanks. – MLu Sep 20 '18 at 3:31

How could curl know that the file is executable? Well technically it could examine its contents but it's well beyond what curl is meant to do.

The default permissions are determined by umask (http://en.wikipedia.org/wiki/Umask) and on top of the permissions derived from umask the program may add the executable bit (or use different permissions altogether). For example gcc knows that it's making executable files and therefore sets the exec bit. On the other hand curl isn't meant to create executable files and therefore only uses the default perms.

  • file is (mostly) able to tell if the file was meant to be an executable file or not. Curl could use the output from file without having to implement any content analysis, then flip the executable bit. Someone should write a patch for adding a flag to curl that could do this. – Alexander Jul 11 '13 at 9:47
  • 2
    @Alexander someone should most certainly not. If I want a file to be executable, I can set it to be so, I don't want random binaries to be downloaded executable by default, that is a security risk. – terdon Jul 11 '13 at 12:50
  • 1
    @terdon If you don't want there to be an executable binary on your disk, you should not download it. And if you did download it on purpose, what are you planning to do with it that does not involve turning on the executable bit? Any script that has the power to download such a file also has the power to make it executable, exactly where is the additional security risk? – Alexander Jul 11 '13 at 14:18
  • 1
    @Alexander For example, say userA can download a file because he has write access. If it is executable, UserB (who does not have write access and cannot change the permissions) can now execute it if he has read access. Depending on the system you are running this can be dangerous. I agree that this is not a big deal on a single-user machine but it could be on a large server. – terdon Jul 11 '13 at 14:27
  • @terdon If userB has both read and executable access to a file, it's not a security problem that userB is able to read and execute a file. I agree that not configuring a system properly can be a security problem, but that is a security problem regardless of if it's a large server or not, and regardless of if curl turned on the executable bit. – Alexander Jul 11 '13 at 14:33

When you download a file over HTTP, you only receive the contents of the file, not its metadata such as its creation date, permissions, etc.

Use a different protocol which includes this metainformation, or, if you have access to the server, serve the file in a container which includes the metadata information, such as a tar file.

If this is a serious recurring frustration, you could also write a wrapper for curl which tries to guess the correct permissions and set them when the download finishes (hint: file guesses file types).


In unix systems, whether a file is executable or not depends solely on its permissions, not on its name or its content. (If the file format is not a valid executable, the system will attempt to execute and treat it as one of the possible errors when executing a program, alongside insufficient resources, missing libraries, etc.)

Most files that you download from the web are not meant to be executable, so curl doesn't attempt to make the file executable. Even if the file was meant to be executed, you might not want to execute it now; for example, you might want to review it, and only make the file executable if it passes your review.

On the other hand, gcc or any other compiler intends to produce an executable program, so it's not surprising that it would take the necessary steps. With gcc, this is one of the last stages of the compilation process. You can observe it with strace:

$ strace -f gcc a.c
23429 execve("/usr/bin/ld", ["/usr/bin/ld", "--eh-frame-hdr", "-m", "elf_i386", "--hash-style=both", "-dynamic-linker", "/lib/ld-linux.so.2", "-z", "relro", "/usr/lib/gcc/i486-linux-gnu/4.3."..., "/usr/lib/gcc/i486-linux-gnu/4.3."..., "/usr/lib/gcc/i486-linux-gnu/4.3."..., "-L/usr/lib/gcc/i486-linux-gnu/4."..., "-L/usr/lib/gcc/i486-linux-gnu/4."..., "-L/usr/lib/gcc/i486-linux-gnu/4."..., "-L/lib/../lib", ...], [/* 82 vars */]) = 0
23429 chmod("a.out", 0755)              = 0
23429 exit_group(0)                     = ?

In other words, the linker, which is the last stage in the compilation and produces the executable, changes the permissions on the output file to be executable as its very last step.

  1. "Binary" is not the same as "executable". Designating a file as "binary" is simply a heuristic, meaning that the content of the file is generally not going to be human readable. Designating a file as "executable" means that it contains a program of some sort (even in non-binary form such as a shell script) which can be "run". Countless binary formats are simply data containers.
  2. The binary file produced by your gcc command is always going to be a file primarily used as an executable.
  3. You can't trust files from the internet. Instead of trying to guess whether a file should be executable, which anyway is impossible since even prose can be used as shell scripts, curl and other programs will simply apply the umask and leave any gun.shoot(self.foot) to the user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.