Stefan Hagen wrote:
> Sebastien Marie wrote:
>> On Sat, Jan 23, 2021 at 09:04:22PM +0100, Stefan Hagen wrote:
>>> Sebastien Marie wrote:
>>>> On Sat, Jan 23, 2021 at 07:14:33PM +0100, Stefan Hagen wrote:
>>>>> Hi,
>>>>>
>>>>> Spectrwm on Sparc64 wants the wpath pledge: 
>>>>>
>>>>>  70801 spectrwm CALL  open(0x7904d18380,0x10002<O_RDWR|O_CLOEXEC>)
>>>>>  70801 spectrwm NAMI  
>>>>> "/var/cache/fontconfig//7908e75dfa020c169504380270e5263a-be64.cache-7"
>>>>>  70801 spectrwm PLDG  open, "wpath", errno 1 Operation not permitted
>>>>>  70801 spectrwm PSIG  SIGABRT SIG_DFL
>>>>>
>>>>> I've sent the fix upstream and it got merged already.
>>>>> Meanwhile, here is the fixed port.
>>>>>
>>>>> Changes:
>>>>>  - added wpath pledge where needed
>>>>>  - added revision
>>>>
>>>> I am a bit unsure about adding "wpath" in promises. Usually when
>>>> fontconfig write is involved, it means the cache is out of sync (and
>>>> it is odd it is happening for the system cache). If I didn't mess
>>>> myself, I recall about something like that previously.
>>>>
>>>> If adding "wpath" is really required, it would be interesting to use
>>>> also unveil to restrict the promise added.
>>>
>>> You're right. I can reproduce it on amd64 now:
>>>
>>> If I fiddle with my font paths and then (re)start X, spectrwm crashes
>>> with a wpath violation on amd64 too.
>>>
>>> This is something that can happen with any X application...
>>>
>>> Instead of allowing wpath and catching it again with unveil, wouldn't
>>> it be worth thinking about a pledge promise that allows X font cache
>>> updates?
>>
>> no. the kernel shouldn't have to know what all libraries could do :)
>>
>> the responsability is shared between the compoments:
>>
>> - it is the application responsability to pledge for what the
>>   application and all linked libraries will need (like sthen@
>>   mentioned)
>>
>> - it is the library responsability to not doing silly things
>>   (regarding fontconfig, we patched out chmod(2) usage from it for
>>   example: https://marc.info/?l=openbsd-cvs&m=157229154821950&w=2).
>>
>> - it is the responsability of the kernel to enforce, in a generic way,
>>   what the application pledge for, without having a complex interface.
>>
>>   you could compare pledge(2) usage in cat(1) (it was tame(2) in first
>>   ages)
>>   
>> https://github.com/openbsd/src/commit/b7db428a8107ad20577d7c8416bf55a8f875e621
>>   and capsicum
>>   
>> https://cgit.freebsd.org/src/commit/bin/cat/cat.c?id=aefe30c5437159a5399bdbc1974d6fbf40f2ba0f
>>  .
>>
>>
>>> There is still a difference. On amd64, I can start another WM or an
>>> xterm and on the next start spectrwm works. The same does not work on
>>> the sparc64 machine. I don't know what fontconfig is doing there. It
>>> looks like the font cache is always out of sync here.
>>
>> in your ktrace extract, fontconfig is trying to revalidate the
>> *system* cache (/var/cache/fontconfig). only root could do that (but
>> fontconfig tries to do it, and will fail due to EPERM - and when
>> pledged, the fact to try to use O_RDWR makes it to die).
>>
>> in "fiddle with my font paths", it should rewrite the user cache
>> (usually ~/.cache/fontconfig), which is something it has permission to
>> do (if not killed by pledge).
>>
>> I am suspecting some issue in the way your x11 sets were installed
>> (did you use bsd.rd ? installing from source ?)
>
> My system is fairly standard, all sets installed. I upgrade every few
> days with sysupgrade to the next snapshot and update my ports with
> pkg_add -u. I'm not installing anything that's not a port or package.
>
>> system fontconfig cache comes from xbase68.tgz. Previously, we made
>> some adjustements too keep it in sync with fonts directories
>> (https://marc.info/?l=openbsd-cvs&m=153117126409370&w=2).
>
>> Please note I am also unsure how fonts from ports are managed.
>>
>> A possible workaround would be to run `fc-cache -s' as root, but it
>> will only correct the immediate problem (out-of-sync) and not the
>> underline problem (why the cache is out-of-sync).
>
> Yes, I know how to work around this. There are ways - but it shouldn't 
> need those workarounds.
>
> I spend more time on this und this .xsession can reliably reproduce it.
>
> (This is on amd64 now)
>
> $ cat .xsession
> #!/bin/sh
> export PATH=$HOME/.bin:$PATH
> export ENV=$HOME/.kshrc
>
> xset fp+ $HOME/.fonts
>
> if [ -f $HOME/.fonts/a.pcf ];
> then
>     mv $HOME/.fonts/a.pcf $HOME/.fonts/b.pcf
> else
>     mv $HOME/.fonts/b.pcf $HOME/.fonts/a.pcf
> fi
>
> ktrace /usr/local/bin/spectrwm
> fc-cache
> /usr/local/bin/spectrwm
>
> The above can also be reproduced if I change a font in X and then
> restart X before starting another application that updates the font 
> cache.
>
> Now the interesting part:
>
> ktrace without wpath pledge (same as above):
>  74576 spectrwm CALL  open(0x60aca42e2c0,0x10000<O_RDONLY|O_CLOEXEC>)
>  74576 spectrwm NAMI  "/home/sdk/.fonts"
>  74576 spectrwm RET   open 4
>  74576 spectrwm CALL  fstatfs(4,0x7f7ffffc5b20)
>  74576 spectrwm RET   fstatfs 0
>  74576 spectrwm CALL  close(4)
>  74576 spectrwm RET   close 0
>  74576 spectrwm CALL  open(0x60b68610580,0x10002<O_RDWR|O_CLOEXEC>)
>  74576 spectrwm NAMI  
> "/var/cache/fontconfig//16ed0cc8073ec56eceb979219ebd6117-le64.cache-7"
>  74576 spectrwm PLDG  open, "wpath", errno 1 Operation not permitted
>  74576 spectrwm PSIG  SIGABRT SIG_DFL
>
> ktrace with wpath pledge:
>  43198 spectrwm CALL  open(0xe8a4ebca400,0x10000<O_RDONLY|O_CLOEXEC>)
>  43198 spectrwm NAMI  
> "/home/sdk/.fontconfig//16ed0cc8073ec56eceb979219ebd6117-le64.cache-7"
>  43198 spectrwm RET   open -1 errno 2 No such file or directory
>  43198 spectrwm CALL  stat(0xe8a729bc620,0x7f7fffff3f08)
>  43198 spectrwm NAMI  "/home/sdk/.fonts"
>  43198 spectrwm STRU  struct stat { [...] }
>  43198 spectrwm RET   stat 0
>  43198 spectrwm CALL  open(0xe8a729bc620,0x10000<O_RDONLY|O_CLOEXEC>)
>  43198 spectrwm NAMI  "/home/sdk/.fonts"
>  43198 spectrwm RET   open 4
>  43198 spectrwm CALL  fstatfs(4,0x7f7fffff3c30)
>  43198 spectrwm RET   fstatfs 0
>  43198 spectrwm CALL  close(4)
>  43198 spectrwm RET   close 0
>  43198 spectrwm CALL  open(0xe898828b280,0x10002<O_RDWR|O_CLOEXEC>)
>  43198 spectrwm NAMI  
> "/var/cache/fontconfig//16ed0cc8073ec56eceb979219ebd6117-le64.cache-7"
>  43198 spectrwm RET   open -1 errno 2 No such file or directory
>  43198 spectrwm CALL  open(0xe8a14b2e480,0x10002<O_RDWR|O_CLOEXEC>)
>  43198 spectrwm NAMI  
> "/home/sdk/.cache/fontconfig//16ed0cc8073ec56eceb979219ebd6117-le64.cache-7"
>  43198 spectrwm RET   open 4
>  43198 spectrwm CALL  kbind(0x7f7fffff3da8,24,0x972bc9d9d6b346c2)
>  43198 spectrwm RET   kbind 0
>  43198 spectrwm CALL  getpid()
>  43198 spectrwm RET   getpid 43198/0xa8be
>  43198 spectrwm CALL  kbind(0x7f7fffff3da8,24,0x972bc9d9d6b346c2)
>  43198 spectrwm RET   kbind 0
>  43198 spectrwm CALL  fcntl(4,F_SETLKW,0xffff3ea0)
>  43198 spectrwm PLDG  fcntl, "flock", errno 1 Operation not permitted
>  43198 spectrwm PSIG  SIGABRT SIG_DFL code <-73839872>
>
> What I see here is a bug in fontconfig, right?
>
> 1. O_RDONLY open in the user cache
> 2. O_RDWR open to _check_ the system cache
> 3. O_RDWR open to create the cache file in the user cache
>
> I believe that number 2 could as well be O_RDONLY.

The same thing is happening in CWM:

  1190 cwm      CALL  open(0x15960894580,0x10002<O_RDWR|O_CLOEXEC>)
  1190 cwm      NAMI  
"/var/cache/fontconfig//16ed0cc8073ec56eceb979219ebd6117-le64.cache-7"
  1190 cwm      RET   open -1 errno 2 No such file or directory
  1190 cwm      CALL  open(0x15960894000,0x10002<O_RDWR|O_CLOEXEC>)
  1190 cwm      NAMI  
"/home/sdk/.cache/fontconfig//16ed0cc8073ec56eceb979219ebd6117-le64.cache-7"

I compared how pledge is implemented in spectrwm and CWM, I see that CWM
is first setting everything up. Then it goes into a "running" state and
restricts itself via pledge.

It's different in spectrwm. Pledge is called multiple times and
privileges are dropped gradually. I've added wpath to the first three
pledge calls. But there are more following that reduce the set of
privileges further until spectrwm is fully initialized and running.

I think adding wpath to spectrwm as proposed is fine and does not need
additional unveiling because pledge is called again and drops wpath
there.

Nevertheless, I believe fontconfig could do the system cache check
read-only.

Why the font-cache is always out of sync on the sparc64 machine is 
something I still need to look into.

Best Regards,
Stefan

Reply via email to