Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asustor / synology nas devices not restoring session or settings after reload. #149

Closed
userdocs opened this issue May 18, 2024 · 2 comments

Comments

@userdocs
Copy link
Owner

userdocs commented May 18, 2024

Linked issue: #141

Summary

The release of musl 1.2.5 introduced support for statx - https://www.openwall.com/lists/musl/2024/03/01/2. This syscall is broken on kernels used by Synology and Asustor nas (white label synology devices?) for using custom syscalls that are reserved for other syscalls in modern kernels.

Since qtbase 5/6 support using statx it attempts to make use of this syscall via the mis appropriated number and gets nonsense returned to it. Here is an example strace:

openat(AT_FDCWD, "/usr/local/AppCentral/qbittorrent-native/home/.config/qBittorrent/watched_folders.json", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 74
fcntl(74, F_SETFD, FD_CLOEXEC)          = 0
statx(74, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_GID|STATX_INO|STATX_SIZE|0xdb06c000, stx_attributes=STATX_ATTR_IMMUTABLE|STATX_ATTR_ENCRYPTED|STATX_ATTR_AUTOMOUNT|STATX_ATTR_MOUNT_ROOT|STATX_ATTR_VERITY|0x7f7b068080, stx_size=549135500224, ...}) = 0
statx(74, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_TYPE|STATX_ATIME, stx_attributes=STATX_ATTR_IMMUTABLE|STATX_ATTR_APPEND|STATX_ATTR_NODUMP|STATX_ATTR_ENCRYPTED|STATX_ATTR_AUTOMOUNT|STATX_ATTR_MOUNT_ROOT|STATX_ATTR_VERITY|0x7f7b068100, stx_mode=0177, ...}) = 0
close(74)                               = 0

Source of strace: #141 (comment)

Important

It won't attempt to fallback since there is no error returned, the statx call was successful, the problem is that what was returned is junk to statx, resulting in the filesize error.

This issue effects both muslc and glibc. The problem is the device kernel and is not a musl or glibc bug.

Note

Anything linked to a version of musl before v1.2.5 works, such as applications built on Alpine Linux 3.19 which is currently using 1.2.4_git20230717-r4 (latest at the time of writing)

edge is on 1.2.5 - https://pkgs.alpinelinux.org/packages?name=musl

Tip

An assumption may be made that a dependency introduced a regression when you have effectively changed the version of musl it was linked against at build time by downgrading.

The problem

If you see these type of warnings when loading qBittorrent:

Failed to load Categories. File size exceeds limit.
Reason: "File size exceeds limit. File: "..." File size: 548318599328. Size limit: 104857600"

You should use strace to confirm the kernel behaviour described in the summary.

Solutions:

1: Very kindly, I was provided a patch ( richfelker aka dalias @ #musl/Libera ) to disable these newer calls on older devices by the applications https://sprunge.us/Hzz1iT.

  • Original patch URL provided - https://sprunge.us/Hzz1iT
  • Please read patch comment via the sprunge url or below
  • Please read this web.archive.org for more info on this issue
  • The patch will need to be used at build time but I'll still have to work out how to best implement it.
  • Musl contact info can be found here if you need to discuss it - https://musl.libc.org
  • I have included the full patch in this comment, shown below
/*
 * fix for broken synology-kernel NAS devices that stole a bunch of syscall
 * numbers for their own MSDOS emulation purposes. link into application
 * to block SYS_statx and all newer/later syscalls with seccomp. */

#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>

#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <linux/filter.h>

__attribute__((__constructor__))
static void fix_synology(void)
{
	struct sock_filter filter[4];
	struct sock_fprog prog = {
		.len = sizeof filter / sizeof *filter,
		.filter = filter,
	};

	filter[0] = (struct sock_filter)BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, nr));
	filter[1] = (struct sock_filter)BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, SYS_statx, 0, 1);
	filter[2] = (struct sock_filter)BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO|ENOSYS);
	filter[3] = (struct sock_filter)BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW);

	prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) abort();
}

2: Use an application linked against a version of musl less than v1.2.5, so v1.2.4 or a git commit from musl master before 20/02/2024

@userdocs userdocs added the PSA label May 18, 2024
@userdocs userdocs pinned this issue May 18, 2024
@ivan-yu
Copy link

ivan-yu commented May 31, 2024

Will you consider using the patch to build 4.6.5 NOX and future versions?

I am following up with Asustor support on this kernel bug as well.

Thanks.

@userdocs
Copy link
Owner Author

userdocs commented Jun 6, 2024

I don't really want to apply the patch to generic builds. It is probably better if the asustor package maintainer forked the repo and applied the patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants