.kicad_sch and .kicad_pcb files now default to no group or world read on Linux

I noticed recently that on Linux, schematic and board files now default to no group or world read. Where in the past those files were created with 0644 permissions, they are created wtth 0600 permissions. Sounds like a umask(0077) or umask(0066) has been added to the code somewhere.

It’s not a biggie but I prefer to allow group and world read permissions, and there doesn’t seem to be a preference to set the umask. I assume this is to prevent inadvertent exposure of info to others.

1 Like

I think this is a Linux issue, not KiCAD.
On xUbuntu, “other” permissions in $HOME are no longer default since a couple of versions (20.10 onwards, I believe).

EDIT: I just checked my own files. Dirs are 750, files are 740. This might not be typical, though, I have UMASK 027.

We don’t interact with permissions on file read/write.

By “We” I suppose you mean the developer team?
I couldn’t imagine that either, no program does that.

Maybe you think you don’t but certainly a program can affect the permissions when a file is created. The base system call for creading a file is creat(2) which has a second argument of mode. If the group and world permission bits are anded out, a file will not have those permission bits on. Generally most programs do creat(path, 0666) and let the user umask mask out the write bit on group and world. Maybe somebody thought KiCad code (or perhaps wx code) should do creat(path, 0600).

This is a different matter. Some Linux distros set the user umask to something a bit more restrictive, usually in the system profile. Yours is 0027, mine is 0022. Thus all my other programs create files with read for group and world, the 2 masks out write.

I just did an experiment. I took a project, updated the schematic date in the title block and saved it. Sure enough the .kicad_sch files both the main and child sheets had 0600 permissions where they had 0644 permissions previously. Maybe it has something to do with the way KiCad saves files to avoid problems with network file systems.

Maybe I’ll run a strace on the process some time.

Ok, here’s the result in the strace output. Turns out that KiCad does a chmod on the saved file, wonder why. Paths redacted for privacy.

chmod("/home/me/.../main.kicad_sch", 0100600) = 0
chmod("/home/me/.../sub.kicad_sch", 0100600) = 0
chmod("/home/me/.local/share/recently-used.xbel", 0600) = 0

We do not use syscalls. In fact, I eliminated the indirect api calls of file syscalls over a year ago because it negatively affected performance. (Unbuffered IO does not work on network shares).

We use fopen with “wt”, we fwrite it, we then fclose it. That’s it.
If there’s a chmod, it’s part of libc.

You may not use syscalls directly but all interaction with the filesystem has to go through the syscalls. It may be via a library, but fopen and fclose will eventually call open or creat.

In this case, something is calling chmod.

Yes, it could be fopen, but that’s not our problem then, it’s libc.

We have zero calls to chmod or fchmod in KiCad

But none of the other usual apps (browsers, editors, etc.) on Linux create files with those restrictions, so it’s unlikely to be libc. Maybe it’s a utility library routine to copy files or something like that to avoid the network file issues.

Nope, we have zero utility libraries here. fopen, fwrite, and fclose.
The only other thought is we write files indirectly via temp files and then switch the files.

The network file issues was just the use of syscalls and poor placement of temp files on the network share rather than on the local disk.

That might be a possibility. The temp file should acquire the permissions of the older version so as not to also turn on permission inadvertently.

Edit: In fact I suspect that’s it. man 3 mkstemp says:

The file is created with permissions 0600, that is, read plus write for
owner  only.  The returned file descriptor provides both read and write
access to the file.  The file is opened with the open(2)  O_EXCL  flag,
guaranteeing that the caller is the process that creates the file.

Yeah, on my Linux system (Arch) schematic & pcb files are saved as 600 as well. The project files (.kicad_pro and .kicad_prl) are 644.

If I just touch a new file, it’s 644, so this seems like a KiCad thing and not a my machine thing.

(edit: 6.0.7 built from source)

Latest Debian but I compile from source

hermit@V6_permissions_test:ls -l
total 12
-rw-r--r-- 1 hermit hermit   50 Sep 27 08:32 V6_permissions_test.kicad_pcb
-rw-r--r-- 1 hermit hermit 1375 Sep 27 08:32 V6_permissions_test.kicad_pro
-rw-r--r-- 1 hermit hermit  105 Sep 27 08:32 V6_permissions_test.kicad_sch

Could you please put a strace on kicad and grep the output for chmod like I did?

I’ve never used strace but I gave it a try. I came up with an empty file on the grep outputted to a file. I may have done it wrong or there may have been nothing too see. If you are using a package I would suspect the friendly privacy police helped out.

Was it the first time you created the project? Try rewriting the schematic, the bug seems to appear when the file is updated. The first time there is no need for a temp file.

I updated. As you can see, the .sch and .pro file have different time stamps.

hermit@fred:ls -l
total 28
drwxr-xr-x 2 hermit hermit 4096 Sep 27 20:05 fred-backups
-rw-r--r-- 1 hermit hermit   50 Sep 27 14:57 fred.kicad_pcb
-rw-r--r-- 1 hermit hermit 1138 Sep 27 14:57 fred.kicad_prl
-rw-r--r-- 1 hermit hermit 5751 Sep 27 20:05 fred.kicad_pro
-rw------- 1 hermit hermit 5043 Sep 27 20:06 fred.kicad_sch

There you go. It’s probably due to the way KiCad rewrites schematics and PCBs via a temp file.

What puzzles me is why KiCad did a chmod on the final saved file as my trace shows. My guess what happened is:

KiCad contained code to propagate the permissions of the old revision to the new one, which is the right thing to do
Code was added to save to a temp file first then rename
The permission transfer now propagated the permissions of the temp file to the new revision

Nope. It never did.

schematics are written to temp file and then wxRenameFile is called which essentially just wraps rename.