From: sandeen@sandeen.net
To: xfs@oss.sgi.com
Cc: hch@infradead.org
Subject: [patch 08/11] Hook up compat XFS_IOC_ATTRLIST_BY_HANDLE ioctl handler
Date: Tue, 18 Nov 2008 22:44:09 -0600 [thread overview]
Message-ID: <20081119044909.981142660@sandeen.net> (raw)
In-Reply-To: 20081119044401.573365619@sandeen.net
[-- Attachment #1: compat_ioctl_attrlist --]
[-- Type: text/plain, Size: 5604 bytes --]
Add a compat handler for XFS_IOC_ATTRLIST_BY_HANDLE
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
--
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_ioctl32.h
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_ioctl32.h
+++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_ioctl32.h
@@ -119,6 +119,18 @@ typedef struct compat_xfs_swapext
#define XFS_IOC_SWAPEXT_32 _IOWR('X', 109, struct compat_xfs_swapext)
+typedef struct compat_xfs_fsop_attrlist_handlereq {
+ struct compat_xfs_fsop_handlereq hreq; /* handle interface structure */
+ struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */
+ __u32 flags; /* which namespace to use */
+ __u32 buflen; /* length of buffer supplied */
+ compat_uptr_t buffer; /* returned names */
+} _PACKED compat_xfs_fsop_attrlist_handlereq_t;
+
+/* Note: actually this is read/write */
+#define XFS_IOC_ATTRLIST_BY_HANDLE_32 \
+ _IOW ('X', 122, struct compat_xfs_fsop_attrlist_handlereq)
+
#ifdef BROKEN_X86_ALIGNMENT
/* on ia32 l_start is on a 32-bit boundary */
typedef struct compat_xfs_flock64 {
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_ioctl32.c
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -45,6 +45,7 @@
#include "xfs_dfrag.h"
#include "xfs_vnodeops.h"
#include "xfs_fsops.h"
+#include "xfs_attr.h"
#include "xfs_ioctl32.h"
#define _NATIVE_IOC(cmd, type) \
@@ -360,6 +361,138 @@ xfs_ioctl32_fshandle_copyin(unsigned lon
return (unsigned long)p;
}
+/*
+ * Convert userspace handle data into inode.
+ *
+ * We use the fact that all the fsop_handlereq ioctl calls have a data
+ * structure argument whose first component is always a xfs_fsop_handlereq_t,
+ * so we can pass that sub structure into this handy, shared routine.
+ *
+ * If no error, caller must always iput the returned inode.
+ */
+STATIC int
+xfs_vget_fsop_handlereq_compat(
+ xfs_mount_t *mp,
+ struct inode *parinode, /* parent inode pointer */
+ compat_xfs_fsop_handlereq_t *hreq,
+ struct inode **inode)
+{
+ void __user *hanp;
+ size_t hlen;
+ xfs_fid_t *xfid;
+ xfs_handle_t *handlep;
+ xfs_handle_t handle;
+ xfs_inode_t *ip;
+ xfs_ino_t ino;
+ __u32 igen;
+ int error;
+
+ /*
+ * Only allow handle opens under a directory.
+ */
+ if (!S_ISDIR(parinode->i_mode))
+ return XFS_ERROR(ENOTDIR);
+
+ hanp = compat_ptr(hreq->ihandle);
+ hlen = hreq->ihandlen;
+ handlep = &handle;
+
+ if (hlen < sizeof(handlep->ha_fsid) || hlen > sizeof(*handlep))
+ return XFS_ERROR(EINVAL);
+ if (copy_from_user(handlep, hanp, hlen))
+ return XFS_ERROR(EFAULT);
+ if (hlen < sizeof(*handlep))
+ memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen);
+ if (hlen > sizeof(handlep->ha_fsid)) {
+ if (handlep->ha_fid.fid_len !=
+ (hlen - sizeof(handlep->ha_fsid) -
+ sizeof(handlep->ha_fid.fid_len)) ||
+ handlep->ha_fid.fid_pad)
+ return XFS_ERROR(EINVAL);
+ }
+
+ /*
+ * Crack the handle, obtain the inode # & generation #
+ */
+ xfid = (struct xfs_fid *)&handlep->ha_fid;
+ if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) {
+ ino = xfid->fid_ino;
+ igen = xfid->fid_gen;
+ } else {
+ return XFS_ERROR(EINVAL);
+ }
+
+ /*
+ * Get the XFS inode, building a Linux inode to go with it.
+ */
+ error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
+ if (error)
+ return error;
+ if (ip == NULL)
+ return XFS_ERROR(EIO);
+ if (ip->i_d.di_gen != igen) {
+ xfs_iput_new(ip, XFS_ILOCK_SHARED);
+ return XFS_ERROR(ENOENT);
+ }
+
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+ *inode = VFS_I(ip);
+ return 0;
+}
+
+STATIC int
+xfs_attrlist_by_handle_compat(
+ void __user *arg,
+ struct inode *parinode)
+{
+ int error;
+ attrlist_cursor_kern_t *cursor;
+ compat_xfs_fsop_attrlist_handlereq_t al_hreq;
+ struct inode *inode;
+ char *kbuf;
+ xfs_mount_t *mp = XFS_I(parinode)->i_mount;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -XFS_ERROR(EPERM);
+ if (copy_from_user(&al_hreq, arg,
+ sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
+ return -XFS_ERROR(EFAULT);
+ if (al_hreq.buflen > XATTR_LIST_MAX)
+ return -XFS_ERROR(EINVAL);
+
+ /*
+ * Reject flags, only allow namespaces.
+ */
+ if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
+ return -XFS_ERROR(EINVAL);
+
+ error = xfs_vget_fsop_handlereq_compat(mp, parinode, &al_hreq.hreq,
+ &inode);
+ if (error)
+ goto out;
+
+ kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL);
+ if (!kbuf)
+ goto out_vn_rele;
+
+ cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
+ error = xfs_attr_list(XFS_I(inode), kbuf, al_hreq.buflen,
+ al_hreq.flags, cursor);
+ if (error)
+ goto out_kfree;
+
+ if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
+ error = -EFAULT;
+
+ out_kfree:
+ kfree(kbuf);
+ out_vn_rele:
+ iput(inode);
+ out:
+ return -error;
+}
+
STATIC long
xfs_compat_ioctl(
int mode,
@@ -382,7 +515,6 @@ xfs_compat_ioctl(
case XFS_IOC_GETBMAPX:
/* not handled
case XFS_IOC_FSSETDM_BY_HANDLE:
- case XFS_IOC_ATTRLIST_BY_HANDLE:
case XFS_IOC_ATTRMULTI_BY_HANDLE:
*/
case XFS_IOC_FSCOUNTS:
@@ -456,6 +588,8 @@ xfs_compat_ioctl(
arg = xfs_ioctl32_fshandle_copyin(arg);
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq);
break;
+ case XFS_IOC_ATTRLIST_BY_HANDLE_32:
+ return xfs_attrlist_by_handle_compat((void __user*)arg, inode);
default:
return -XFS_ERROR(ENOIOCTLCMD);
}
--
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2008-11-19 4:49 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-19 4:44 [patch 00/11] RFC: compat ioctl fixes/cleanups/additions sandeen
2008-11-19 4:44 ` [patch 01/11] Move compat ioctl structs & numbers into xfs_ioctl32.h sandeen
[not found] ` <20081119145941.GA13050@infradead.org>
2008-11-19 15:24 ` Eric Sandeen
2008-11-20 1:54 ` Eric Sandeen
2008-11-19 4:44 ` [patch 02/11] Fix the compat XFS_IOC_FSGEOMETRY_V1 ioctl sandeen
2008-11-19 4:44 ` [patch 03/11] Add compat handlers for data & rt growfs ioctls sandeen
2008-11-19 4:44 ` [patch 04/11] Add compat handlers for swapext ioctl sandeen
2008-11-19 4:44 ` [patch 05/11] Make the bulkstat_one compat ioctl handling more sane sandeen
2008-11-19 4:44 ` [patch 06/11] Fix xfs_bulkstat_one size checks & error handling sandeen
2008-11-19 4:44 ` [patch 07/11] Fix compat XFS_IOC_FSBULKSTAT_SINGLE ioctl sandeen
2008-11-19 4:44 ` sandeen [this message]
2008-11-19 4:44 ` [patch 09/11] Hook up compat XFS_IOC_ATTRMULTI_BY_HANDLE ioctl handler sandeen
[not found] ` <20081119151628.GI13050@infradead.org>
2008-11-19 15:30 ` Eric Sandeen
2008-11-19 4:44 ` [patch 10/11] Hook up compat XFS_IOC_FSSETDM_BY_HANDLE " sandeen
2008-11-19 4:44 ` [patch 11/11] Reorder xfs_ioctl32.c for some tidiness sandeen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081119044909.981142660@sandeen.net \
--to=sandeen@sandeen.net \
--cc=hch@infradead.org \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.