Multi-homed NFS servers was Re: 1.1.81 seems to break NFS

Multi-homed NFS servers was Re: 1.1.81 seems to break NFS

Post by Swen Thuemml » Fri, 20 Jan 1995 19:01:53




>I've had some problems with this as well- at least I think it is the same
>problem.  The source of the problem is NFS mounting from servers that
>have more than one network interface.   In newer kernels, NFS packets
>seem to be accepted only from the interface which negotiated the original
>mount.  This behaviour has been the source of much contention of the
>KERNEL and NET mailing lists, with Linus firmly supporting the present
>(annoying) behaviour, as anything else is spoofable and a security risk.

[...]

Quote:>Unfortunately, changes in routing can happen dynamically and may change
>which interface packets are coming from,
>We need a real solution.

Well, here is a RealSolution^TM, which is unfortunately not (yet)
accepted by Linus. You need to apply the following kernel patch, AND
you will have to patch the mount program (and the automounter amd as
well, if you are using it). Applying the kernel patch alone will not
change the current behaviour. You can find the source to mount in
util-linux-1.10.tar.gz. In the file nfsmount.c, remove or #ifdef 0 the
following code fragment (should be around line 350):

        if (connect(fsock, (struct sockaddr *) &server_addr,
            sizeof (server_addr)) < 0) {
                perror("nfs connect");
                goto fail;
        }

Note, that this change will make the mount program incompatible with
older kernels or kernels without the patch below. You could test for
the kernel release with some code like this:

  uname(&my_utsname)
  if (strcmp(my_utsname.release, "1.1.83") < 0)
    {
        /* code with connect() */
    }
  else
    {
        /* code without connect() */
    }

Unfortunately, you have to do this yourself, since Linus refused to
put in the patch below into the official kernel, so there is no
definite release which could go into the mount program to keep it
compatible. Perhaps you (Yes, I mean _YOU_) can convince Linus, that
this patch is no security hole (perhaps we can add an option to the
mount program, which will connect() the socket regardless of the
kernel revision for security).

Greetings, Swen

Here's the patch. Apply with "cd /usr/src; patch -p < whateveryounamedit"

diff -u -r linux.orig/fs/nfs/inode.c linux/fs/nfs/inode.c
--- linux.orig/fs/nfs/inode.c   Tue Jan 10 16:02:18 1995

        server->acdirmin = data->acdirmin*HZ;
        server->acdirmax = data->acdirmax*HZ;
        strcpy(server->hostname, data->hostname);
+       memcpy(&server->addr, &data->addr, sizeof(struct sockaddr_in));
        sb->u.nfs_sb.s_root = data->root;
        unlock_super(sb);
        if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
diff -u -r linux.orig/fs/nfs/sock.c linux/fs/nfs/sock.c
--- linux.orig/fs/nfs/sock.c    Thu Jan  5 12:55:40 1995

        fs = get_fs();
        set_fs(get_ds());
        for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
-               result = sock->ops->send(sock, (void *) start, len, 0, 0);
+               result = sock->ops->sendto(sock, (void *) start, len, 0, 0, (struct sockaddr *)&server->addr, sizeof(server->addr));
                if (result < 0) {
                        printk("nfs_rpc_call: send error = %d\n", result);

                 * we don't now need, so discard it */
                result = sock->ops->recvfrom(sock, (void *)&recv_xid,
                                             sizeof(recv_xid), 1, MSG_PEEK,
-                                            NULL, &addrlen);
+                                            NULL, NULL);
                if (result < 0) {
                        if (result == -EAGAIN) {

                 * a null buffer yet. */
                (void)sock->ops->recvfrom(sock, (void *)&recv_xid,
                                          sizeof(recv_xid), 1, 0, NULL,
-                                         &addrlen);
+                                         NULL);
 #if 0
                printk("nfs_rpc_call: XID mismatch\n");

         *
         */
        result=sock->ops->recvfrom(sock, (void *)start,
-                                 size + 1024, 1, 0, NULL,
+                                 size + 1024, 1, 0, (struct sockaddr *)&server->addr,
                        /* Here is NFS_SLACK_SPACE..., hack */
                                  &addrlen);
        if (result < 0) {
diff -u -r linux.orig/include/linux/nfs_fs_sb.h linux/include/linux/nfs_fs_sb.h
--- linux.orig/include/linux/nfs_fs_sb.h        Wed Dec  1 13:44:15 1993

 #define _NFS_FS_SB

 #include <linux/nfs.h>
+#include <linux/in.h>

 struct nfs_server {

        int acdirmin;
        int acdirmax;
        char hostname[256];
+       struct sockaddr_in addr;
 };

 /*

 
 
 

Multi-homed NFS servers was Re: 1.1.81 seems to break NFS

Post by Steve McInty » Sun, 22 Jan 1995 23:24:33




>Well, here is a RealSolution^TM, which is unfortunately not (yet)
>accepted by Linus. You need to apply the following kernel patch, AND
>you will have to patch the mount program (and the automounter amd as
>well, if you are using it)

Thanks very much!! 1.1.83 now works fine for me.

 -------------------------------------------------------------------------
| Steve McIntyre            \<a href="http://club.eng.cam.ac.uk/~93sam/"> |

| Room 47C, Churchill College,\ Tongue-tied and twisted,                  |
| Cambridge, England CB3 0DS   \ Just an earth-bound misfit, I" (c) PF    |
| ^^ CURS Secretary 1994/95 ^^  \ ** CUWoCS: Honorary Vice-Chair-Thing ** |
 -------------------------------------------------------------------------

 
 
 

1. NFS-fs is not loadable in 1.1.81

Hi,

I can't load the NFS-code with insmod:

~# cd /usr/src/linux/modules
/usr/src/linux/modules# insmod nfs.o
_socki_lookup undefined
_close_fp undefined
/usr/src/linux/modules#

I think socki_lookup() and close_fp() should be added to
kernel/ksyms.c. Here's my patch:

--- kernel/ksyms.c_old  Sun Jan 15 12:50:25 1995

 #include <asm/irq.h>
 extern char floppy_track_buffer[];
 extern void set_device_ro(int dev,int flag);
+
+extern int close_fp(struct file *filp, unsigned int fd);
+extern struct socket *socki_lookup(struct inode *inode);

 extern void *sys_call_table;

        X(insert_inode_hash),
        X(event),
        X(__down),
+        /* Added to make NFS loadable */
+        X(close_fp),
+        X(socki_lookup),
+

 #if defined(CONFIG_MSDOS_FS) && !defined(CONFIG_UMSDOS_FS)
        /* support for umsdos fs */

-Andi

2. Using Orchid SoundWave with Linux

3. iBCS broken with 1.1.81

4. TCPIP tweaks: I need help.

5. 1.1.81 broke NCSA httpd? Ahhh!

6. Minix and Linux (was Re: CBM and Linux (was:Re:MS adopts UNIX))

7. Problem with nfs mount with multi-homed Server

8. Bash-2.05a available for FTP

9. 1.1.81 kernel panic NCR 53c810

10. 1.1.81 and Mitsumi 4X IDE (ATAPI) CD-ROM problems

11. 1.1.81 PCI probe hang

12. /etc/utmp error - gcc 2.6.2 kernel 1.1.81 XF86 3.1