From: Xiubo Li Date: Tue, 11 Feb 2020 07:56:23 +0000 (-0500) Subject: mount.ceph: fix incorrect options parsing X-Git-Tag: v15.1.1~382^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fffdd52a7b9c6b41c629960bd16d1da5a2be3e26;p=ceph.git mount.ceph: fix incorrect options parsing The strncmp will only compare the first N bytes, this will be a problem in some case, for example: $ mount.ceph :/ /mnt/cephfs -o remount,room_size=10 We assume the "room_size" is a new option, we will never receive any "room_size=10" data in kernel space, because it will be parsed as "ro". And another example is if we move the "secret" option up and before the "secretfile", the "secretfile" will never be correctly parsed. Signed-off-by: Xiubo Li --- diff --git a/src/mount/mount.ceph.c b/src/mount/mount.ceph.c index e970648c59d6..80e43e3dd31a 100644 --- a/src/mount/mount.ceph.c +++ b/src/mount/mount.ceph.c @@ -218,7 +218,7 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi) if(*data == 0) break; next_keyword = strchr(data,','); - + /* temporarily null terminate end of keyword=value pair */ if(next_keyword) *next_keyword++ = 0; @@ -229,46 +229,46 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi) value++; } - if (strncmp(data, "ro", 2) == 0) { + if (strcmp(data, "ro") == 0) { cmi->cmi_flags |= MS_RDONLY; - } else if (strncmp(data, "rw", 2) == 0) { + } else if (strcmp(data, "rw") == 0) { cmi->cmi_flags &= ~MS_RDONLY; - } else if (strncmp(data, "nosuid", 6) == 0) { + } else if (strcmp(data, "nosuid") == 0) { cmi->cmi_flags |= MS_NOSUID; - } else if (strncmp(data, "suid", 4) == 0) { + } else if (strcmp(data, "suid") == 0) { cmi->cmi_flags &= ~MS_NOSUID; - } else if (strncmp(data, "dev", 3) == 0) { + } else if (strcmp(data, "dev") == 0) { cmi->cmi_flags &= ~MS_NODEV; - } else if (strncmp(data, "nodev", 5) == 0) { + } else if (strcmp(data, "nodev") == 0) { cmi->cmi_flags |= MS_NODEV; - } else if (strncmp(data, "noexec", 6) == 0) { + } else if (strcmp(data, "noexec") == 0) { cmi->cmi_flags |= MS_NOEXEC; - } else if (strncmp(data, "exec", 4) == 0) { + } else if (strcmp(data, "exec") == 0) { cmi->cmi_flags &= ~MS_NOEXEC; - } else if (strncmp(data, "sync", 4) == 0) { + } else if (strcmp(data, "sync") == 0) { cmi->cmi_flags |= MS_SYNCHRONOUS; - } else if (strncmp(data, "remount", 7) == 0) { + } else if (strcmp(data, "remount") == 0) { cmi->cmi_flags |= MS_REMOUNT; - } else if (strncmp(data, "mandlock", 8) == 0) { + } else if (strcmp(data, "mandlock") == 0) { cmi->cmi_flags |= MS_MANDLOCK; - } else if ((strncmp(data, "nobrl", 5) == 0) || - (strncmp(data, "nolock", 6) == 0)) { + } else if ((strcmp(data, "nobrl") == 0) || + (strcmp(data, "nolock") == 0)) { cmi->cmi_flags &= ~MS_MANDLOCK; - } else if (strncmp(data, "noatime", 7) == 0) { + } else if (strcmp(data, "noatime") == 0) { cmi->cmi_flags |= MS_NOATIME; - } else if (strncmp(data, "nodiratime", 10) == 0) { + } else if (strcmp(data, "nodiratime") == 0) { cmi->cmi_flags |= MS_NODIRATIME; - } else if (strncmp(data, "relatime", 8) == 0) { + } else if (strcmp(data, "relatime") == 0) { cmi->cmi_flags |= MS_RELATIME; - } else if (strncmp(data, "strictatime", 11) == 0) { + } else if (strcmp(data, "strictatime") == 0) { cmi->cmi_flags |= MS_STRICTATIME; - } else if (strncmp(data, "noauto", 6) == 0) { + } else if (strcmp(data, "noauto") == 0) { /* ignore */ - } else if (strncmp(data, "_netdev", 7) == 0) { + } else if (strcmp(data, "_netdev") == 0) { /* ignore */ - } else if (strncmp(data, "nofail", 6) == 0) { + } else if (strcmp(data, "nofail") == 0) { /* ignore */ - } else if (strncmp(data, "secretfile", 10) == 0) { + } else if (strcmp(data, "secretfile") == 0) { int ret; if (!value || !*value) { @@ -280,7 +280,7 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi) fprintf(stderr, "error reading secret file: %d\n", ret); return ret; } - } else if (strncmp(data, "secret", 6) == 0) { + } else if (strcmp(data, "secret") == 0) { size_t len; if (!value || !*value) { @@ -291,7 +291,7 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi) len = strnlen(value, sizeof(cmi->cmi_secret)) + 1; if (len <= sizeof(cmi->cmi_secret)) memcpy(cmi->cmi_secret, value, len); - } else if (strncmp(data, "conf", 4) == 0) { + } else if (strcmp(data, "conf") == 0) { if (!value || !*value) { fprintf(stderr, "mount option conf requires a value.\n"); return -EINVAL; @@ -300,7 +300,7 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi) cmi->cmi_conf = strdup(value); if (!cmi->cmi_conf) return -ENOMEM; - } else if (strncmp(data, "name", 4) == 0) { + } else if (strcmp(data, "name") == 0) { if (!value || !*value) { fprintf(stderr, "mount option name requires a value.\n"); return -EINVAL; @@ -326,7 +326,6 @@ static int parse_options(const char *data, struct ceph_mount_info *cmi) } else { pos = safe_cat(&cmi->cmi_opts, &cmi->cmi_opts_len, pos, data); } - } data = next_keyword; } while (data);