Replacement in 3.x kernel for ioctl?


Recommended Posts

So I'm attempting to get pgrdm (program guard) working on arch linux with a 3.6 kernel...

Had to google loads of errors and work out solutions (mostly adding stdio.h etc. includes) but now I'm against a problem I don't know the answer to...

So the whole daemon, kernel module and GUI compiles fine if I remove a line from the kernel module, but if I leave the line in, the kernel module refuses to compile. If I compile and run without this line the output I get is;

Conf file settings: LOG_ALL=1, QUERY_MODE=1, QUERY_TEST_MODE=0, BE_A_DAEMON=0, CHECK_ALL=0, LOG_STD_OUT=1.

SignalThread: MarkActive was successful

SignalThread: PID FROM IsActive IS 0

Signal thread started pid=16373

Opening firewall module.

Entering Debug Mode.

Error requesting the firewall to print debug messages; errno=25.

/opt/pgrd/pgmgrdgui: Unable to connect to client cmd socket; errno=-2.

Which I believe is because of this 'ioctl' thing which appears to allow communication with kernel modules like it's a normal named file or something.

So here is the code causing the problems;

/*
** init_firewall - Module entry routine.
*/
int init_firewall()
{
int rc;

   myprintk(KERN_ALERT "entering module_init\n");
   Firewall.FileOps.ioctl = FirewallIoctl;
   Firewall.FileOps.open = FirewallOpen;
   Firewall.FileOps.read = FirewallRead;
   Firewall.FileOps.release = FirewallClose;
   rc = FirewallInit();
   if(rc == 0)

/tmp/pgrd-7.0/pgrdm/firewall.c: In function ?init_firewall?:
/tmp/pgrd-7.0/pgrdm/firewall.c:1009:20: error: ?struct file_operations? has no member named ?ioctl?

Any ideas on how to solve this error and get the program working?

Link to comment
https://www.neowin.net/forum/topic/1123360-replacement-in-3x-kernel-for-ioctl/
Share on other sites

According to this page, the file_operations structure is sourced in linux/fs.h. The reference structure on the aforementioned page (from Linux 2.4.2) indicates that your code should be correct. However, the same structure from Linux 3.7 RC2 looks somewhat different.


/* These macros are for out of kernel modules to test that
* the kernel supports the unlocked_ioctl and compat_ioctl
* fields in struct file_operations. */
#define HAVE_COMPAT_IOCTL 1
#define HAVE_UNLOCKED_IOCTL 1

struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
};
[/CODE]

Notice in particular that there is no longer a member named [i]ioctl[/i], but rather [i]unlocked_ioctl[/i] and [i]compat_ioctl[/i]. Also notice that the [i]ioctl[/i] function pointer prototypes are different.

[CODE]
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
[/CODE]

versus

[CODE]
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
[/CODE]

Theoretically, all you need to do is modify the existing FirewallIoctl function to conform to the new prototype and assign it to compat_ioctl.

[CODE]
/*
** init_firewall - Module entry routine.
*/
int init_firewall()
{
int rc;

myprintk(KERN_ALERT "entering module_init\n");
Firewall.FileOps.compat_ioctl = FirewallIoctlCompat;
Firewall.FileOps.open = FirewallOpen;
Firewall.FileOps.read = FirewallRead;
Firewall.FileOps.release = FirewallClose;
rc = FirewallInit();
if(rc == 0)
[/CODE]

[b]PS:[/b] If you're going to be writing kernel-level code, it might be a good idea to keep a local copy of the Linux git repository. That way you can see not only the code and comments for any version of Linux, but also the commit messages that go along with them.

And changed! It does now compile but ermm...

Conf file settings: LOG_ALL=1, QUERY_MODE=1, QUERY_TEST_MODE=0, BE_A_DAEMON=0, CHECK_ALL=0, LOG_STD_OUT=1.

SignalThread: MarkActive was successful

SignalThread: PID FROM IsActive IS 0

Signal thread started pid=1405

Opening firewall module.

Entering Debug Mode.

Error requesting the firewall to print debug messages; errno=25.

/opt/pgrd/pgmgrdgui: Unable to connect to client cmd socket; errno=-2

Think this old code is broken somewhere :/

I'm not sure exactly how far back the introduction of compat_ioctl goes, but it is present in every release of Linux since they moved to git for their SCM (Linux 2.6.12 RC2). Considering that the older version of the structure I found was from a 2.4 series release, I'm guessing that compat_ioctl was introduced in Linux 2.6. If you're trying to compile a kernel module written for Linux 2.4 on Linux 3.6, its quite likely that other things have changed as well. For example, the return value of compat_ioctl is long while the return value of ioctl is int. You're probably going to need to audit the code for compatibility problems such as that. (KGDB is likely to be very helpful as well.) May the force be with you.

Edit: Ah. I see from the README that the version you uploaded was specifically designed to compile against a 2.6 series kernel and is incompatible with 2.4. Based on that information, compat_ioctl must have been introduced somewhere between Linux 2.6.0 and Linux 2.6.12 RC2. You could download a copy of Fedora Core 3 and try it out if you're that interested!

Edit 2: Based on the description of Program Guard in its README, you could probably accomplish the same thing using a properly targeted SELinux security policy and iptables.

Haha nope, no point having it run just on an old kernel :p.

All the decent security software for *nix only runs in old kernels, dig_sig, this, tuxguardian, etc. :/

That's not true at all! Especially considering its widespread use in industry and government, security experts have put a lot of time into securing Linux. Some of the old security tools, such as the ones you mentioned, are no longer supported, but there is a reason for that: they were replaced by some something better. If you're interested in hardening your installation, I recommend that you read the RHEL 6 Security Guide. It is bound to have some practical application no matter which distro you're using. (This advice is coming from a heavy Debian user, not a RHEL/CentOS/Fedora user.)

Can't replace it with SElinux and iptables, leopard flower does that but it does it on a per-applcation basis, with no support for per-port and will including all child applications in the parent application, e.g. firefox access controls plugin_container and flash plugin.

SElinux can't do what dig_sig does, the closest to it is IMA and I've never been able to get it working at all, other than that, there's no run-only-signed-programs system for current linux kernels :(

Can't replace it with SElinux and iptables, leopard flower does that but it does it on a per-applcation basis, with no support for per-port and will including all child applications in the parent application, e.g. firefox access controls plugin_container and flash plugin.

SElinux can't do what dig_sig does, the closest to it is IMA and I've never been able to get it working at all, other than that, there's no run-only-signed-programs system for current linux kernels :(

SELinux lets you limit permissions per-application, and iptables lets you limit access per-route and per-port. You also have standard Linux permissions in the mix. SELinux is merely meant to complement them, not replace them. If you target your SELinux security policy properly, you can make it limit each child process individually as well. However, this could have some unintended consequences, I think.

If you really want to run some of the older security programs, I say go for it. No one is stopping you. One of the greatest things about open-source software is that you can download the source code and modify it to fit your needs. Maybe you will pickup new techniques, discover why the software was abandoned in the first place, or create the next amazing security program for Linux. That's how you become a better developer: just do it. I have learned a lot that way; I'm sure you can too.

This topic is now closed to further replies.
  • Posts

    • Forza Horizon 6 gets another hotfix for one of the game's online modes by Taras Buria Recently, Forza Horizon 6 players discovered an interesting glitch that allowed farming a crazy amount of in-game credits in a few minutes. Playground Games quickly pulled the plug on the exploit by disabling one of the game's online modes, and today, the studio is rolling out another hotfix. In my review, I complained about the game still showering gamers with cars, credits, and wheelspins. As such, earning money in Forza Horizon 6 is not a particularly difficult task. You simply have to play the game, crazy, I know. However, people still found an easier path to becoming a billionaire in Forza Horizon 6. All you had to do was purchase the Hummer EV, install a specific tune, shift in reverse while going at about 15 MPH, hit a wall, and get launched into the stratosphere at the speed of light. While mid-air, launch Eliminator and quickly get eliminated. Boom, the game just awarded you with a few million in-game credits. Initially, Playground Games disabled Eliminator to prevent people from farming credits. Now, following the release of the first balancing update, developers are rolling out a new update that re-enables Eliminator and gives users a free McLaren Sabre as a gesture of goodwill. Here is the changelog: One critical issue remains unpatched, though. There are quite a few reports of the game wiping gamers' saves, and developers are still looking into that. To avoid potential data loss, Playground Games recommends taking one of the steps outlined in a previously published support article.
    • Dead by Daylight, Two Point Museum, and more join Xbox Free Play Days for the weekend by Pulasthi Ariyasinghe There is a brand-new Free Play Days offer available to Xbox players, giving them a chance to try out a new selection of games over the weekend. Microsoft's latest promotion brings some high-profile titles, including the sports title PGA TOUR 2K25 and the racing sim Assetto Corsa. Almost all the games being offered this time require an Xbox Game Pass subscription, with only one title being available for all players. Starting with the fully free-to-play section, Dead by Daylight is populating it solo. This asymmetric survival horror title should be the most familiar to most gamers, considering its age. The multiplayer four-versus-one asymmetric survival horror game has you assuming the roles of survivors or the killer to see who can come out on top. This Dead by Daylight offer will be available to play until Monday, June 22, giving you an extra day of play compared to the remainder of the Free Play Days titles. Meanwhile, Xbox Game Pass Ultimate, Premium, and Essential members can now try out the well-received tycoon game Two Point Museum, the circuit racing sim Assetto Corsa, as well as 2K's golf sim experience that gives players a career to develop alongside real-world pros and courses. Here are the announced games and the platforms they are available to play on: PGA TOUR 2K25 (Xbox Series X|S) Two Point Museum (Xbox Series X|S) Assetto Corsa (Xbox Series X|S, Xbox One) Dead by Daylight (Xbox Series X|S, Xbox One) To easily find the titles on Xbox consoles, first head to the Store, and then in the sidebar, find the Home section. In there, open the Subscriptions tab. All the games from the Free Play Days collection will show up in this section for quick access. Apart from Dead by Daylight's offer, this week's Free Play Days promotions will end on Sunday, June 21, at 11:59 pm PT.
  • Recent Achievements

    • Week One Done
      Huge Trailer earned a badge
      Week One Done
    • Week One Done
      Classifyskilleducation earned a badge
      Week One Done
    • One Month Later
      eurospharma62 earned a badge
      One Month Later
    • Week One Done
      With What earned a badge
      Week One Done
    • Week One Done
      Harris Gilbert earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      589
    2. 2
      +Edouard
      171
    3. 3
      PsYcHoKiLLa
      74
    4. 4
      Michael Scrip
      67
    5. 5
      neufuse
      64
  • Tell a friend

    Love Neowin? Tell a friend!