From 341f9c97c5926cb37ca51de047c70e0fa44b3f1e Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Fri, 25 Apr 2014 18:00:48 -0500 Subject: [PATCH] LU-4954 mdd: validate names before create, link, and rename 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 Change-Id: I66413b796177f042fc9bd87e98338de9e5125cae Reviewed-on: http://review.whamcloud.com/10111 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Mike Pershin Reviewed-by: Fan Yong Reviewed-by: Andreas Dilger --- lustre/include/lu_object.h | 5 +++-- lustre/mdd/mdd_dir.c | 28 ++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index 989e0f9..702bc61 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -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" diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index bce304b..c84f820 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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)); -- 1.8.3.1