Whamcloud - gitweb
LU-1746 osd-zfs: fix LU_BUF_NULL in osd_xattr_list()
authorMinh Diep <minh.diep@intel.com>
Fri, 31 Aug 2012 15:33:39 +0000 (08:33 -0700)
committerOleg Drokin <green@whamcloud.com>
Mon, 17 Sep 2012 22:12:45 +0000 (18:12 -0400)
== sanity test 17k: symlinks: rsync with xattrs enabled
=========================== 17:49:09 (1344332949)
sending incremental file list
rsync: get_xattr_names: llistxattr(".",0) failed: Numerical
result out of range (34)
[...]

It happened like this:

  osd_sa_xattr_list()
  osd_xattr_list()
  ...
  mdt_getxattr_pack_reply()
  mdt_getxattr()

mdt_getxattr_pack_reply() passed LU_BUF_NULL as lu_buf to
learn how big the buffer should be.  osd_xattr_list() does
not support such queries with NULL buffers.

Test-Parameters: envdefinition=USE_OFD=yes,LOAD_MODULES_REMOTE=true
Signed-off-by: Minh Diep <minh.diep@intel.com>
Change-Id: I1aa63d9774770c14db2b332e634734cda3a160b6
Reviewed-on: http://review.whamcloud.com/3863
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Li Wei <liwei@whamcloud.com>
lustre/osd-zfs/osd_xattr.c

index 614067c..9ea4fd1 100644 (file)
@@ -728,14 +728,16 @@ osd_sa_xattr_list(const struct lu_env *env, struct osd_object *obj,
 
        while ((nvp = nvlist_next_nvpair(obj->oo_sa_xattr, nvp)) != NULL) {
                len = strlen(nvpair_name(nvp));
-               if (len >= remain)
-                       return -ERANGE;
-
-               memcpy(lb->lb_buf, nvpair_name(nvp), len);
-               lb->lb_buf += len;
-               *((char *)lb->lb_buf) = '\0';
-               lb->lb_buf++;
-               remain -= len + 1;
+               if (lb->lb_buf != NULL) {
+                       if (len + 1 > remain)
+                               return -ERANGE;
+
+                       memcpy(lb->lb_buf, nvpair_name(nvp), len);
+                       lb->lb_buf += len;
+                       *((char *)lb->lb_buf) = '\0';
+                       lb->lb_buf++;
+                       remain -= len + 1;
+               }
                counted += len + 1;
        }
        return counted;
@@ -775,14 +777,16 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
        while ((rc = -udmu_zap_cursor_retrieve_key(env, zc, oti->oti_key,
                                                MAXNAMELEN)) == 0) {
                rc = strlen(oti->oti_key);
-               if (rc >= remain)
-                       GOTO(out_fini, rc = -ERANGE);
-
-               memcpy(lb->lb_buf, oti->oti_key, rc);
-               lb->lb_buf += rc;
-               *((char *)lb->lb_buf) = '\0';
-               lb->lb_buf++;
-               remain -= rc + 1;
+               if (lb->lb_buf != NULL) {
+                       if (rc + 1 > remain)
+                               RETURN(-ERANGE);
+
+                       memcpy(lb->lb_buf, oti->oti_key, rc);
+                       lb->lb_buf += rc;
+                       *((char *)lb->lb_buf) = '\0';
+                       lb->lb_buf++;
+                       remain -= rc + 1;
+               }
                counted += rc + 1;
 
                zap_cursor_advance(zc);