Whamcloud - gitweb
LU-4954 mdd: validate names before create, link, and rename 11/10111/2
authorJohn L. Hammond <john.hammond@intel.com>
Fri, 25 Apr 2014 23:00:48 +0000 (18:00 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 1 May 2014 19:05:25 +0000 (19:05 +0000)
In lu_name_is_valid() check that the length of the ln_name is equal to
ln_namelen and check that there are no embedded slashes. Add
mdd_name_check() which calls lu_name_is_valid() and check against the
mdd ENAMETOOLONG limit. Call mdd_name_check() from
mdd_create_sanity_check(), mdd_link_sanity_check() and mdd_rename().

Signed-off-by: John L. Hammond <john.hammond@intel.com>
Change-Id: I66413b796177f042fc9bd87e98338de9e5125cae
Reviewed-on: http://review.whamcloud.com/10111
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/include/lu_object.h
lustre/mdd/mdd_dir.c

index 989e0f9..702bc61 100644 (file)
@@ -1293,8 +1293,9 @@ static inline bool lu_name_is_valid(const struct lu_name *ln)
 {
        return ln->ln_name != NULL &&
               ln->ln_namelen > 0 &&
-              ln->ln_name[0] != '\0' &&
-              ln->ln_name[ln->ln_namelen] == '\0';
+              ln->ln_name[ln->ln_namelen] == '\0' &&
+              strlen(ln->ln_name) == ln->ln_namelen &&
+              memchr(ln->ln_name, '/', ln->ln_namelen) == NULL;
 }
 
 #define DNAME "%.*s"
index bce304b..c84f820 100644 (file)
@@ -57,6 +57,17 @@ static struct lu_name lname_dotdot = {
         sizeof(dotdot) - 1
 };
 
+static inline int
+mdd_name_check(struct mdd_device *m, const struct lu_name *ln)
+{
+       if (!lu_name_is_valid(ln))
+               return -EINVAL;
+       else if (ln->ln_namelen > m->mdd_dt_conf.ddp_max_name_len)
+               return -ENAMETOOLONG;
+       else
+               return 0;
+}
+
 /* Get FID from name and parent */
 static int
 __mdd_lookup(const struct lu_env *env, struct md_object *pobj,
@@ -81,10 +92,6 @@ __mdd_lookup(const struct lu_env *env, struct md_object *pobj,
                RETURN(-ESTALE);
        }
 
-       /* The common filename length check. */
-       if (unlikely(lname->ln_namelen > m->mdd_dt_conf.ddp_max_name_len))
-               RETURN(-ENAMETOOLONG);
-
        rc = mdd_permission_internal_locked(env, mdd_obj, pattr, mask,
                                            MOR_TGT_PARENT);
        if (rc)
@@ -498,8 +505,9 @@ static int mdd_link_sanity_check(const struct lu_env *env,
                 RETURN(-ESTALE);
 
         /* Local ops, no lookup before link, check filename length here. */
-        if (lname && (lname->ln_namelen > m->mdd_dt_conf.ddp_max_name_len))
-                RETURN(-ENAMETOOLONG);
+       rc = mdd_name_check(m, lname);
+       if (rc < 0)
+               RETURN(rc);
 
         if (mdd_is_immutable(src_obj) || mdd_is_append(src_obj))
                 RETURN(-EPERM);
@@ -1841,6 +1849,10 @@ static int mdd_create_sanity_check(const struct lu_env *env,
                }
        }
 
+       rc = mdd_name_check(m, lname);
+       if (rc < 0)
+               RETURN(rc);
+
        switch (cattr->la_mode & S_IFMT) {
         case S_IFLNK: {
                 unsigned int symlen = strlen(spec->u.sp_symname) + 1;
@@ -2588,6 +2600,10 @@ static int mdd_rename(const struct lu_env *env,
        if (rc)
                GOTO(out_pending, rc);
 
+       rc = mdd_name_check(mdd, ltname);
+       if (rc < 0)
+               GOTO(out_pending, rc);
+
         handle = mdd_trans_create(env, mdd);
         if (IS_ERR(handle))
                 GOTO(out_pending, rc = PTR_ERR(handle));