This patch fixes the problem for me, using Frank's test program.
The failure Frank was having is due to lis_fattach() having to call sys_mount() (indirectly) which in turn eventually calls do_add_mount() (in the kernel, file fs/namespace.c). do_add_mount() unconditionally tests capable(CAP_SYS_ADMIN), which fails if the process context is not running as effectively as root (as set from the user level via seteuid) and returns EPERM.
I offer the attached patch, Dave, only to demonstrate a potential fix for Frank's problem, for Frank to try and for you to do with as you see fit. It's against 2.16.13.
It sets CAP_SYS_ADMIN inside the lis_mount() and lis_umount2() routines, which are syscall wrappers for sys_mount() and sys_umount2().
For simplicity, it wraps the kernel capability stuff in FATTACH_VIA_MOUNT; which may or may not be appropriate, but I only
have 2.4.22 here right now, so I have no idea when this stuff was
added or how it has changed.
-John
David Grothe wrote:
I'm not an fattach specialist, so maybe someone else can answer this. -- Dave
Subject: fattach failed on application without super user privilege To: [EMAIL PROTECTED] From: [EMAIL PROTECTED] Date: Thu, 25 Sep 2003 09:59:18 -0400
Hi,
I have an application running with LiS-2.16/Linux 2.4.18. The application
create named pipe, and push connld, and attach it (the program showed in
belows). It always failed on the calling fattach fucntion if the
application does not have super-user privilege. I tried fattach utility and
got the same result ("Operation is not permitted"). If the application run
on the super user mode, it succeeded. I need my application run on
non-super user mode, how can I do it ? Thanks
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <memory.h> #include <fcntl.h> #include <errno.h> #include <limits.h> #include <stropts.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/sysmacros.h> #include <sys/ioctl.h>
int main( int argc, char *argv[] ) { int fd[2];
if (pipe(fd) < 0) { fprintf( stderr, "pipe() failed: %s\n", strerror(errno) ); exit(1); } fcntl(fd[1], F_SETFL, O_NONBLOCK); mknod("pipe1", S_IFIFO | 0666, 0);
if (ioctl( fd[1], I_PUSH, "connld" ) < 0) { fprintf( stderr, "ioctl( %d, I_PUSH, connld ) failed: %s\n", fd[1], strerror(errno) ); exit(1); }
if (fattach( fd[1], "pipe1" ) < 0) { fprintf( stderr, "fattach( %d, \"pipe1\" ) failed: %d %s\n", fd[1], errno, strerror(errno) ); exit(1); }
close(fd[0]); close(fd[1]);
exit(0); }
Frank Chi Senior Programming Engineer Ingenico Atlanta (678) 795-2850 Direct (770) 594-6003 Fax
_______________________________________________ Linux-streams mailing list [EMAIL PROTECTED] http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams
--- LiS-2.16.13-orig/head/linux-mdep.c 2003-07-15 15:58:21.000000000 -0400
+++ LiS-2.16.13/head/linux-mdep.c 2003-09-25 20:58:00.000000000 -0400
@@ -77,6 +77,9 @@
#include <linux/pipe_fs_i.h>
#ifdef KERNEL_2_3
#include <linux/mount.h>
+#if defined(FATTACH_VIA_MOUNT)
+#include <linux/capability.h>
+#endif
#endif
#include <linux/time.h>
@@ -4446,12 +4449,23 @@
{
mm_segment_t old_fs;
int ret;
+#if defined(FATTACH_VIA_MOUNT)
+ kernel_cap_t cap = current->cap_effective;
+#endif
old_fs = get_fs();
set_fs(KERNEL_DS);
+#if defined(FATTACH_VIA_MOUNT)
+ cap_raise(current->cap_effective, CAP_SYS_ADMIN);
+#endif
+
ret = syscall_mount(dev_name, dir_name, fstype, rwflag, data) ;
+#if defined(FATTACH_VIA_MOUNT)
+ current->cap_effective = cap;
+#endif
+
set_fs(old_fs);
return(ret < 0 ? -errno : ret) ;
@@ -4471,12 +4485,23 @@
{
mm_segment_t old_fs;
int ret;
+#if defined(FATTACH_VIA_MOUNT)
+ kernel_cap_t cap = current->cap_effective;
+#endif
old_fs = get_fs();
set_fs(KERNEL_DS);
+#if defined(FATTACH_VIA_MOUNT)
+ cap_raise(current->cap_effective, CAP_SYS_ADMIN);
+#endif
+
ret = syscall_umount2(path, flags) ;
+#if defined(FATTACH_VIA_MOUNT)
+ current->cap_effective = cap;
+#endif
+
set_fs(old_fs);
return(ret < 0 ? -errno : ret) ;
