File: use-memfd_create-syscall.patch

package info (click to toggle)
rust-libsystemd 0.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 420 kB
  • sloc: makefile: 2
file content (74 lines) | stat: -rw-r--r-- 2,955 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
This patch is based on the upstream commit described below, adapted for use
in the Debian package by Peter Michael Green.

commit 3037b5d110e035ff60c6f7b6fd5440aa56091b4e
Author: Daniel Estévez <daniel@destevez.net>
Date:   Fri Apr 28 10:03:04 2023 +0200

    call memfd_create as syscall instead of through libc
    
    In order to support glibc < 2.27, we call memfd_create() through
    syscall() instead of as a libc function, since memfd_create() was
    added in glibc 2.27.

Index: libsystemd/src/logging.rs
===================================================================
--- libsystemd.orig/src/logging.rs
+++ libsystemd/src/logging.rs
@@ -1,12 +1,13 @@
 use crate::errors::SdError;
 use libc::{dev_t, ino_t};
 use nix::fcntl::*;
-use nix::sys::memfd::memfd_create;
+use nix::errno::Errno;
 use nix::sys::memfd::MemFdCreateFlag;
 use nix::sys::socket::{sendmsg, ControlMessage, MsgFlags, UnixAddr};
 use once_cell::sync::OnceCell;
 use std::collections::HashMap;
-use std::ffi::{CString, OsStr};
+use std::ffi::{CStr, CString, OsStr};
+use std::os::unix::prelude::RawFd;
 use std::fs::File;
 use std::io::Write;
 use std::os::unix::io::AsRawFd;
@@ -185,6 +186,27 @@ pub fn journal_print(priority: Priority,
     journal_send(priority, msg, map.iter())
 }
 
+// Implementation of memfd_create() using a syscall instead of calling the libc
+// function.
+//
+// The memfd_create() function is only available in glibc >= 2.27 (and other
+// libc implementations). To support older versions of glibc, we perform a raw
+// syscall (this will fail in Linux < 3.17, where the syscall was not
+// available).
+//
+// nix::sys::memfd::memfd_create chooses at compile time between calling libc
+// and performing a syscall, since platforms such as Android and uclibc don't
+// have memfd_create() in libc. Here we always use the syscall.
+fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<File, Errno> {
+    unsafe {
+        let res = libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits());
+        Errno::result(res).map(|r| {
+            // SAFETY: `memfd_create` just returned this FD, so we own it now.
+            File::from_raw_fd(r as RawFd)
+        })
+    }
+}
+
 /// Send an overlarge payload to systemd-journald socket.
 ///
 /// This is a slow-path for sending a large payload that could not otherwise fit
@@ -193,11 +215,9 @@ pub fn journal_print(priority: Priority,
 fn send_memfd_payload(sock: &UnixDatagram, data: &[u8]) -> Result<usize, SdError> {
     let memfd = {
         let fdname = &CString::new("libsystemd-rs-logging").map_err(|e| e.to_string())?;
-        let tmpfd =
+        let mut file =
             memfd_create(fdname, MemFdCreateFlag::MFD_ALLOW_SEALING).map_err(|e| e.to_string())?;
 
-        // SAFETY: `memfd_create` just returned this FD.
-        let mut file = unsafe { File::from_raw_fd(tmpfd) };
         file.write_all(data).map_err(|e| e.to_string())?;
         file
     };