On hidpi screens, label-freetype will trigger a use-after-free in
set_font_for_control() via the call in update_scale_factor_from_pixel_buffer().
That call passes label->font as the font parameter to set_font_for_control().
set_font_for_control() then calls strdup() on its font argument, and
frees label->font. In this case this causes font to point into freed
memory, causing a read use-after-free in the following strstr() and
strrchr() calls.
Fix the issue by only using the freshly strdup()'d new_font variable
after freeing label->font.
When multiple displays of different resolutions are attached, the Plymouth script
plugin uses a virtual "max canvas" (defined by max_width and max_height) for
rendering. Individual displays calculate their offsets (display->x, display->y)
relative to this max canvas for mirroring/centering.
The script-level centering formula, as seen in example themes:
logo.sprite.SetX (Window.GetX() + Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
Issue:
For the script to correctly calculate the absolute center position on the max canvas,
Window.GetX() must conceptually return the origin of the max canvas, which is 0.
However, the non-indexed implementation of sprite_window_get_x (and GetY) currently
returns the maximum calculated display offset (MAX(display->x)), which corresponds to
the offset of the smallest display. This incorrect, non-zero return value introduces
an unintended shift, pushing sprites (like the logo) off-center, and breaking the
centering logic.
Solution:
Update sprite_window_get_x and sprite_window_get_y to return the minimum calculated
display offset (MIN(display->x)). Since the largest display always has an offset of 0,
this guarantees that Window.GetX() and Window.GetY() return 0 when called without
parameters, correctly anchoring the script-calculated center position to the absolute
max canvas origin.
Signed-off-by: xinpeng.wang <wangxinpeng@uniontech.com>
The keymap and capslock code in src/plugins/renderers/drm/plugin.c relies
on the terminal passed to backend_create() to get the keymap and current
capslock state (when not using evdev input because of e.g. no XKBLAYOUT
in /etc/vconsole.conf which is the default in at least Fedora).
When 2 GPUs which both have displays attached are used only the first
one gets passed the local_console_terminal as terminal (it is considered
the terminal owner and e.g. listens for keypresses). This leads to keymap
and capslock icons not being shown on displays attached to the second GPU.
To fix this add a second ply_terminal_t argument to backend_create() called
local_console_terminal, which will pass the local_console_terminal to both
drm plugin instances. And modify the drm plugin capslock and keymap code to
use this instead of the normal terminal argument which will be NULL on
the second GPU.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2375854
Signed-off-by: Hans de Goede <hansg@kernel.org>
Add a UseSimpledrmNoLuks config file keyword this enables simpledrm use,
like the existing "UseSimpledrm" config file keyword. Except when using
LUKS. Showing the LUKS unlock screen using simpledrm has 2 problems:
1. If the GPU drivers are built into the initrd then typically the
unlock screen will briefly show and then the screen goes black
2. The i915 driver uses the firmware framebuffer as fallback when
userspace has not installed a fb to scan out from. This happens
e.g. on logout between the user-session and the display-manager.
Drawing the unlock screen on the simpledrm fb results in it briefly
showing when logging out, which looks quite ugly.
This allows distributions to chose to only enable simpledrm when
LUKS is not used.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2359283
Signed-off-by: Hans de Goede <hansg@kernel.org>
The drm plugin code installs a fd disconnect handler for the terminal fd
which simply calls open_input_source () again.
This assumes that the ply-terminal code's disconnect handler has run first
(which it should) and that ply_terminal_reopen_device () has successfully
re-opened the terminal. This last condition is not always true, resulting
in open_input_source () calling ply_event_loop_watch_fd () with a -1 fd
triggerig an assert in ply_event_loop_watch_fd ():
5 0x00007f62d39a1c6f in __assert_fail (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at assert.c:127
6 0x00007f62d3bc22c7 in ply_event_loop_watch_fd (loop=<optimized out>, fd=-1, status=status@entry=PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
status_met_handler=status_met_handler@entry=0x7f62d3790870 <on_terminal_key_event>,
disconnected_handler=disconnected_handler@entry=0x7f62d3790c70 <on_input_source_disconnected>, user_data=user_data@entry=0x5647f7dd9fb8)
at ../src/libply/ply-event-loop.c:732
7 0x00007f62d3790bf6 in open_input_source (backend=0x5647f7dd9f90, input_source=0x5647f7dd9fb8) at ../src/plugins/renderers/drm/plugin.c:1930
8 0x00007f62d3bcbd53 in ply_event_loop_handle_disconnect_for_source (loop=<optimized out>, source=0x5647f7dd69f0) at ../src/libply/ply-event-loop.c:1065
9 ply_event_loop_disconnect_source (loop=<optimized out>, source=0x5647f7dd69f0) at ../src/libply/ply-event-loop.c:1157
10 ply_event_loop_process_pending_events (loop=0x5647f7dd13e0) at ../src/libply/ply-event-loop.c:1277
11 0x00007f62d3bcc068 in ply_event_loop_run (loop=0x5647f7dd13e0) at ../src/libply/ply-event-loop.c:1311
12 0x00005647c99bba48 in main (argc=<optimized out>, argv=<optimized out>) at ../src/main.c:2572
Fix this by checking that the fd >= 0 before calling
ply_event_loop_watch_fd ().
The above backtrace is from the drm plugin, but the same problem exists
in the frame-buffer plugin. So this fix is applied to both.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2370979
Signed-off-by: Hans de Goede <hansg@kernel.org>