[HN Gopher] Modifying the Linux Kernel - New Syscalls
       ___________________________________________________________________
        
       Modifying the Linux Kernel - New Syscalls
        
       Author : elirant
       Score  : 151 points
       Date   : 2021-09-18 08:34 UTC (14 hours ago)
        
 (HTM) web link (codingkaiser.blog)
 (TXT) w3m dump (codingkaiser.blog)
        
       | autoliteInline wrote:
       | I don't know a thing about how this works, but if it's a
       | collision problem it sounds like these entry points need the
       | equivalent of a GUID.
        
         | blincoln wrote:
         | There aren't very many syscalls in Linux - 335 for x86_64[1],
         | 190 for i386[2], etc. I tend to like GUIDs, but AFAIK it would
         | cause a massive backward-compatibility problem to switch to
         | something other than an integer.
         | 
         | If I'm reading the kernel source[3] correctly, the syscall
         | interface itself accepts a 32-bit unsigned integer for the call
         | number, but only the lowest 16 bits can be used because the
         | upper 16 bits are used to represent the version. That would
         | still mean that something like 80% of the effective ID space is
         | unused at present.
         | 
         | [1]
         | http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x...
         | [2] http://asm.sourceforge.net/syscall.html [3]
         | https://github.com/torvalds/linux/blob/master/ipc/syscall.c
        
           | autoliteInline wrote:
           | 'it would cause a massive backward-compatibility problem to
           | switch to something other than an integer.'
           | 
           | lol. of course.
           | 
           | Suggestion numero two. A dedicated syscall for additional
           | syscalls that has a dedicated parameter for a GUID. We can
           | add a third level in 2050 or so.
        
             | phendrenad2 wrote:
             | Registering paths in /dev, /proc, or /sys seems like the
             | way to go. Slightly slower than a syscall, because the
             | kernel has to do text comparison with the path (such as
             | /dev/foobar) you're reading/writing/ioctling.
        
         | [deleted]
        
       | themulticaster wrote:
       | I'm a little confused on how this tutorial somehow explains
       | several tasks at completely different levels of difficulty
       | (setting up a VM, installing a compiler via apt-get,
       | modifying/updating the bootloader, building a custom kernel, and
       | finally creating a new syscall) with a relatively constant depth
       | of explanations.
       | 
       | It's difficult for me to judge the usefulness of this guide
       | because I'm familiar with those steps, but I'm wondering if it
       | might have been better to define a more narrow scope for this
       | tutorial with certain prerequisites, and going into detail about
       | the ramifications of adding a new syscall? Especially since I
       | feel the guide barely mentions a few interesting details:
       | 
       | 1. Only arch/x86/entry/syscalls/syscall_64.tbl is modified in
       | this tutorial, glossing over the fact that that file only affects
       | x86_64 syscalls (disclaimer: I'm 90% sure on this one, but don't
       | quote me on this). Of course I wouldn't expect the tutorial to
       | explain how to modify all the architecture-specific files, but
       | I'd say this fact is worth noting.
       | 
       | 2. The user-space story: The post doesn't mention how to actually
       | use this syscall - even though that's one of the critical parts
       | of a syscall. Essentially, if you call open() in a C program,
       | you're not actually issuing any syscall directly. Rather the C
       | library (e.g. glibc) implements an open() function that
       | internally performs the syscall. This is primarily because many
       | syscalls don't map 1:1 to C library functions, in addition to
       | some differences between platforms and architectures. So if you'd
       | want to use the syscall you'd have to implement a syscall wrapper
       | yourself or use the low-level syscall(2) [1] function that allows
       | you to access system calls not provided by glibc.
       | 
       | There is also some political drama attached to this, essentially
       | the glibc maintainers don't want to implement/provide functions
       | for certain Linux syscalls because of certain reasons (IIRC it's
       | mostly about portability concerns, but I think there are some
       | syscalls that the glibc maintainers just don't like for whatever
       | reason).
       | 
       | 3. The "What if you _really_ wanted to add a syscall to Linux? "
       | story, which boils down to: The Linux maintainers don't want to
       | add any new syscalls except in very few cases (because syscalls
       | generally can't be changed once they're introduced). Instead,
       | you're supposed to use more flexible kernel interfaces, such as
       | sysfs or debugfs (or previously, ioctl and procfs, but they're
       | frowned upon nowadays and only used in certain areas). See the
       | Linux documentation on adding syscalls [2].
       | 
       | [1] https://man7.org/linux/man-pages/man2/syscall.2.html
       | 
       | [2] https://www.kernel.org/doc/html/v5.14/process/adding-
       | syscall...
        
         | WoodenChair wrote:
         | This tutorial was the perfect level of depth for me -- someone
         | who has experience programming but never experienced modifying
         | the Linux kernel. I don't need a lot of info on setting up a VM
         | or installing tools. I just need info on where the hooks are in
         | the kernel itself. How do you compile it and where do you put
         | the new stuff in?
        
       | denysvitali wrote:
       | To totally complete the tutorial, it would have been awesome to
       | have an example of an userspace software using the new syscalls
       | :)
        
       | sigmonsays wrote:
       | typo when it says "And let's start with the implementation of
       | sys_set_weight" the example code says "asmlinkage long
       | sys_get_weight(int weight){"
        
       | phendrenad2 wrote:
       | This is an awesome comprehensive How-To guide.
       | 
       | One suggestion, though: Choose higher syscall numbers. The
       | syscall numbers that this guide uses (334) is already taken in a
       | recent kernel update. Syscalls are added to almost every kernel
       | version, so if you choose, say, syscall #400, in a decade or so
       | you'll have to make a choice between your syscall and the new
       | "official" one.
        
         | isatty wrote:
         | According to the tweet linked above using device local ioctls
         | are better if you're not upstreaming.
        
           | _hilro wrote:
           | > using device local ioctls are better
           | 
           | Sure but is that not because the tweet concerns a NAS and the
           | ioctls would relate to an actual device(the storage devices)?
           | 
           | Would 'device local ioctls' work in the blog post scenario
           | where it's just a general purpose process attribute?:
           | 
           | > ..we will assign every process a weight
        
             | lokedhs wrote:
             | Yes. A device doesn't even need to support reading and
             | writing. The driver simply registers some name in /dev and
             | the userspace code opens it and does ioctl.
             | 
             | You could also register a name under /proc. There is really
             | no reason to have custom system calls.
        
               | _hilro wrote:
               | Hmm, interesting thanks.
               | 
               | Given the name IO..ctl, is this unintended or unavoidable
               | behaviour?
        
               | phendrenad2 wrote:
               | The name probably originally came from controlling i/o
               | ports and devices at a meta level. But they're just a
               | mechanism for sending a chunk of data to the kernel, and
               | if something in the kernel is watching that path (e.g.
               | /sys/foobar) then it'll be in invoked.
               | 
               | This is apparently how audio works on Linux. The kernel
               | abstracts over sound devices, and provides a sort of
               | "virtual device" at /proc/asound (https://www.kernel.org/
               | doc/html/latest/sound/designs/procfil...)
        
       | leohonexus wrote:
       | I remember Synology ships their NAS with custom vendor syscalls
       | that used unassigned syscall numbers at the time, but those
       | numbers are now clashing with real syscalls - causing undefined
       | behaviour when running arbitrary code (e.g. Docker)
       | 
       | So TL;DR only implement custom syscalls if you intend to maintain
       | for all of its consequences in the future.
       | 
       | Here's the tweet on Synology -
       | https://twitter.com/RichFelker/status/1357733309737021444
        
         | kzrdude wrote:
         | There must be a safer way to do this - a kernel module and
         | custom ioctls, or what is it?
        
           | adwn wrote:
           | Yes, create a kernel module which registers a custom device,
           | then change those syscalls to ioctls on that device.
        
         | edderly wrote:
         | Don't you think the TL;DR is never add your own syscalls when
         | implementing your own character device driver is almost always
         | the better option if you want something to run in the kernel?
        
         | jart wrote:
         | Foolish but that's still a much smarter mistake to make than
         | the ones we've seen from Western Digital exposing system calls
         | over the network where some blogger can root your NAS by
         | sending an abc123 cookie XHR to its unsecured PHP CGI script
         | interface. If the guys making my NAS are smart enough to make
         | mistakes hacking the kernel then that's reassuring.
        
           | justinsaccount wrote:
           | You are confusing
           | 
           | https://man7.org/linux/man-pages/man3/system.3.html
           | 
           | with
           | 
           | https://man7.org/linux/man-pages/man2/syscall.2.html
        
         | mike256 wrote:
         | Synology is a bad example. Many of their custom syscalls are
         | related to filesystem things like btrfs raid5 self repair and
         | carefully removed from their gpl source code. Ianal but imho
         | this is a gpl violation.
        
           | junon wrote:
           | How would modifying code be a violation of the GPL?
        
             | sjburt wrote:
             | If the modified code is distributed in binary form but not
             | in source form.
        
               | junon wrote:
               | IIRC that's not a violation. The source form needs to be
               | available upon request, though I could be wrong.
        
               | hosteur wrote:
               | The source to the derived work that you distribute must
               | be available for the user.
        
               | junon wrote:
               | Available, not necessarily proactively published.
        
               | IntelMiner wrote:
               | If they remove it from their GPL code release but provide
               | it in the GPL licensed binary then it's violating the GPL
        
               | sigg3 wrote:
               | Is it though?
               | 
               | It's misleading, I'll give you that, but let's be
               | pedantic (lawyers are)!
               | 
               | They can probably provide the missing bits in dead tree
               | letter format upon written formal request received at
               | their post address.
        
               | R0b0t1 wrote:
               | It's definitely against the license terms. You're
               | supposed to distribute the code that generated the
               | distributed binaries.
        
               | growse wrote:
               | > It's definitely against the license terms. You're
               | supposed to distribute the code that generated the
               | distributed binaries.
               | 
               | It does look like Synology are not abiding by the GPL
               | here, but a minor nitpick: GPL v2 has no such requirement
               | to distribute the source with the binaries. But if you
               | don't, you do have to tell people they can get it and
               | provide it in "machine-readable" format on request.
               | 
               | See https://www.gnu.org/licenses/old-
               | licenses/gpl-2.0.en.html section 3b
        
       | lbj wrote:
       | Wow. I cant believe how simple the building of a custom kernel
       | has become. I fiddled with this 15 years ago and it all seemed
       | very unapproachable at the time.
       | 
       | Great writeup, thats going straight to bookmarks.
        
         | trulyme wrote:
         | Interesting, my thought is opposite, that not much has changed
         | - download, unzip, modify (optional), make menuconfig, make,
         | make install, fix grub config, profit. :)
         | 
         | EDIT: it is true however that someone has shown me the steps, I
         | would have wasted a lot of time without their guidance.
        
           | lbj wrote:
           | Confirms my theory that I was not very bright in my younger
           | years :)
           | 
           | But I also had almost zero help when I first took on Linux,
           | except manpages.
        
             | trulyme wrote:
             | That matters a lot - having someone to show you the ropes
             | makes the learning process much smoother.
        
               | lbj wrote:
               | Indeed. It was a different world back then. I remember
               | "searching the BBS" not for topics, but for specific
               | files I had heard would help me out :)
        
         | phendrenad2 wrote:
         | Honestly, a lot of these steps feel like BASH-fu fanciness and
         | Debian-specific package management headaches. :)
        
         | fragmede wrote:
         | Technology has come so far! What used to take overnight on a
         | very expensive new machine can be done in a matter of minutes
         | on a late model laptop. _git bisect run_ , connected to a
         | script that boots a VM to test the kernel is the holy Grail
         | of... something, not sure what, but looking back at how things
         | used to be, that's a feat of software (and hardware, eg CPU vmx
         | extensions) engineering and progress that blows my mind.
        
       | marcodiego wrote:
       | It is missing examples of how to call it. Also, that feature
       | would be better implemented by an interface on /proc/$pid
        
       | sharmin123 wrote:
       | HackersList Inside: Top Notorious Cybercriminals In The World:
       | https://www.hackerslist.co/hackerslist-inside-top-notorious-...
        
       ___________________________________________________________________
       (page generated 2021-09-18 23:02 UTC)