rm-hacks icon indicating copy to clipboard operation
rm-hacks copied to clipboard

Handle new update mechanism disable

Open Eeems opened this issue 1 year ago • 9 comments

Eeems avatar Jun 05 '24 20:06 Eeems

All swupdate related files I was able to find in a rM1 update image:

/etc/systemd/system/multi-user.target.wants/swupdate.service
/etc/systemd/system/sockets.target.wants/swupdate.socket
/etc/swupdate.cfg
/lib/systemd/system-preset/98-swupdate.preset
/lib/systemd/system/swupdate.service.d
/lib/systemd/system/swupdate.service.d/swupdate-service-override.conf
/lib/systemd/system/swupdate.service
/lib/systemd/system/swupdate.socket.d
/lib/systemd/system/swupdate.socket.d/swupdate-socket-override.conf
/lib/systemd/system/swupdate-progress.service
/lib/systemd/system/swupdate.socket
/usr/bin/swupdate-progress
/usr/bin/swupdate
/usr/bin/swupdate-ipc
/usr/lib/swupdate
/usr/lib/swupdate/conf.d/09-swupdate-args
/usr/lib/swupdate/swupdate.sh
/usr/lib/libswupdate.so.0.1
/usr/lib/tmpfiles.d/swupdate.conf
/usr/sbin/swupdate-from-image-file
/usr/share/common-licenses/swupdate-tools-hawkbit
/usr/share/common-licenses/swupdate-tools-ipc
/usr/share/common-licenses/swupdate-rootdev
/usr/share/common-licenses/swupdate-progress
/usr/share/common-licenses/swupdate
/usr/share/common-licenses/swupdate-helper
/usr/share/swupdate
/usr/share/swupdate/swupdate-payload-key-pub.pem

Some files of interest:

  • /usr/lib/swupdate/conf.d/09-swupdate-args
    rootfs=$(swupdate -g)
    
    if [ "$rootfs" == '/dev/mmcblk1p2' ]; then
        selection="-e stable,copy2"
    else
        selection="-e stable,copy1"
    fi
    
    # Parameters for Suricatta
    # If this variable is empty (e.g. ..=""), Suricatta mode wont run
    # -d disables the polling of the backend. Swupdate now waits for ipc commands
    # -x disables TLS cert verification
    # See swupdate.sh for the logic
    SWUPDATE_SURICATTA_ARGS=" -d -x "
    
    
    CFGFILE="/tmp/swupdate.cfg"
    
    # We now have the swupdate startup parameters we need
    # Disable bootloader transaction and update state markers
    SWUPDATE_ARGS=" -m -M"
    # Public Key
    SWUPDATE_ARGS+=" -k /usr/share/swupdate/swupdate-payload-key-pub.pem"
    # Set hardware-compatibility, update partition and cfg path
    SWUPDATE_ARGS+=" -H reMarkable1:1.0 ${selection} -f ${CFGFILE}"
    
    I would be interested to know what is in /tmp/swupdate.cfg when it exists.
  • /lib/systemd/system/swupdate.service.d/swupdate-service-override.conf
    [Unit]
    PartOf=memfaultd.service
    
  • /lib/systemd/system/swupdate.socket.d/swupdate-socket-override.conf
    [Unit]
    PartOf=swupdate.service
    
  • /lib/systemd/system/swupdate.service
    [Unit]
    Description=SWUpdate daemon
    Documentation=https://github.com/sbabic/swupdate
    Documentation=https://sbabic.github.io/swupdate
    
    [Service]
    Type=notify
    ExecStart=/usr/lib/swupdate/swupdate.sh
    KillMode=mixed
    
    [Install]
    WantedBy=multi-user.target
    
  • /lib/systemd/system/swupdate.socket
    [Unit]
    Description=SWUpdate socket listener
    Documentation=https://github.com/sbabic/swupdate
    Documentation=https://sbabic.github.io/swupdate
    
    [Socket]
    ListenStream=/tmp/sockinstctrl
    ListenStream=/tmp/swupdateprog
    
    [Install]
    WantedBy=sockets.target
    

Eeems avatar Jun 05 '24 20:06 Eeems

More files of interest:

  • /usr/bin/fakeupdateengine_service
  • /lib/systemd/system/update-engine.service.d/override.conf
    [Unit]
    PartOf=swupdate.service
    
  • /etc/systemd/system/multi-user.target.wants/update-engine.service symlink to /etc/systemd/system/update-engine.service
  • /etc/systemd/system/update-engine.service
    [Unit]
    Description=Fake Update Engine
    After=dbus.service swupdate.service
    Requires=dbus.service swupdate.service
    
    [Service]
    Type=dbus
    BusName=no.remarkable.update1
    ExecStart=/usr/bin/fakeupdateengine_service
    User=root
    Restart=on-failure
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target
    

Eeems avatar Jun 06 '24 06:06 Eeems

I've been trying to track down what handles getting the update to the device, and from there what the server it's pulling it from is. I believe this is used somehow: https://docs.memfault.com/docs/linux/reference-memfaultd-configuration/

Eeems avatar Jun 06 '24 07:06 Eeems

/etc/memfaultd.conf

{
  "persist_dir": "/home/root/.memfault/",
  "upload_interval_seconds": 1200,
  "heartbeat_interval_seconds": 1200,
  "enable_data_collection": true,
  "software_version": "3.11.2.5",
  "software_type": "device",
  "project_key": "JLPsMk3iNn9rmBptmhVq2NYtO4RaiFM7",
  "base_url": "https://device.cloud.remarkable.com",
  "swupdate": {
    "input_file": "/etc/swupdate.cfg",
    "output_file": "/tmp/swupdate.cfg"
},
  "http_server": {
    "bind_address": "127.0.0.1:8787"
},
  "coredump": {
    "coredump_max_size_kib": 96000,
    "rate_limit_count": 5,
    "rate_limit_duration_seconds": 3600,
    "storage_min_headroom_kib": 10240,
    "storage_max_usage_kib": 96000
  }
}

Eeems avatar Jun 06 '24 07:06 Eeems

  • /lib/systemd/system/memfaultd.service
    [Unit]
    Description=memfaultd daemon
    After=\
    local-fs.target \
    network.target \
    dbus.service \
    
    Before=\
    swupdate.service \
    collectd.service \
    
    [Service]
    Type=forking
    PIDFile=/run/memfaultd.pid
    ExecStart=/usr/bin/memfaultd --daemonize
    # Wait for the PID file to be populated before returning
    ExecStartPost=/bin/sh -c "while [ $(cat /run/memfaultd.pid 2>/dev/null | wc -c) -eq 0 ]; do sleep 0.1; done"
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    
  • /lib/systemd/system/memfaultd.service.d/override.conf
    [Unit]
    After=home.mount
    
    [Service]
    # Default if no override key is found
    Environment=CONF_FILE=/etc/memfaultd.conf
    EnvironmentFile=-/tmp/.memfault.env
    # Generates .memfault.env if override key exists
    ExecStartPre=/usr/libexec/project-key-override-checker.sh
    ExecStart=
    ExecStart=/usr/bin/memfaultd --daemonize --config-file "${CONF_FILE}"
    
  • /usr/libexec/project-key-override-checker.sh
    #!/usr/bin/env bash
    
    set -u
    
    override_key_path="/home/root/.config/remarkable/memfault_project_key.conf"
    conf="/etc/memfaultd.conf"
    custom_override_conf="/tmp/.memfaultd-override.conf"
    env_file="/tmp/.memfault.env"
    
    rm -f "${env_file}"
    rm -f "${custom_override_conf}"
    
    if [ ! -e "${override_key_path}" ]; then
        exit 0
    fi
    
    # Key is expected to be 32 characters of alnum ([A-Za-z0-9])
    override_key="$(head -n 1 "${override_key_path}" | grep -Eo '^[[:alnum:]_-]+$')"
    if [ ! -z "${override_key}" ]; then
        sed "s/^\([[:blank:]]*\"project_key\"[[:blank:]]*:[[:blank:]]*\)\"[[:alnum:]]\+\"[[:blank:]]*,$/\1\"${override_key}\",/" "${conf}" > "${custom_override_conf}"
        echo "CONF_FILE=\"${custom_override_conf}\"" > "${env_file}"
    fi
    

Eeems avatar Jun 06 '24 07:06 Eeems

https://docs.memfault.com/docs/linux/ota/

Eeems avatar Jun 06 '24 08:06 Eeems

/tmp/swupdate.cfg

globals :
{
  verbose = false;
  loglevel = 2;
  syslog = true;
};
download :
{
  retries = 3;
  timeout = 1800;
};
suricatta :
{
  confirm = 0;
  polldelay = 300;
  retry = 4;
  retrywait = 200;
  loglevel = 10;
  userid = 0;
  groupid = 0;
  max_artifacts = 1;
  url = "https://device.cloud.remarkable.com/api/v0/hawkbit";
  id = "...";
  tenant = "default";
  gatewaytoken = "...";
};
identify = (
  {
    name = "memfault__current_version";
    value = "3.11.2.5";
  },
  {
    name = "memfault__hardware_version";
    value = "reMarkable1";
  },
  {
    name = "memfault__software_type";
    value = "device";
  } );

I've snipped two things, as I don't know if they are generated on device or not.

Eeems avatar Jun 06 '24 08:06 Eeems

https://github.com/sbabic/swupdate/blob/master/suricatta/server_hawkbit.c This appears to be what consumes the settings to communicate with the server.

Eeems avatar Jun 06 '24 08:06 Eeems

https://eclipse.dev/hawkbit/apis/ddi_api/

Eeems avatar Jun 10 '24 08:06 Eeems