Whamcloud - gitweb
LU-18951 utils: validate ioc_inlbuf in llog_ioctl() 51/59051/4
authorAndreas Dilger <adilger@whamcloud.com>
Wed, 30 Apr 2025 23:49:03 +0000 (17:49 -0600)
committerOleg Drokin <green@whamcloud.com>
Wed, 21 May 2025 05:16:51 +0000 (05:16 +0000)
Validate that the inlbuf is initialized with the log index
for OBD_IOC_LLOG_CANCEL and similarly for other ioctl commands
in llog_ioctl().

Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I237a4f6906dabd64aa2106b6917e9660a92540e5
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59051
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Emoly Liu <emoly@whamcloud.com>
Reviewed-by: Manish Regmi <mregmi@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/obdclass/llog_ioctl.c

index 6be1372..6422401 100644 (file)
@@ -301,13 +301,20 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
               unsigned int cmd, struct obd_ioctl_data *data)
 {
        struct llog_logid logid;
-       int rc = 0;
        struct llog_handle *handle = NULL;
        char *logname, start;
+       int rc = 0;
 
        ENTRY;
 
        logname = data->ioc_inlbuf1;
+       if (logname == NULL || logname[0] == '\0') {
+               rc = -EINVAL;
+               CDEBUG(D_INFO, "%s: missing log name: rc = %d\n",
+                      ctxt->loc_obd->obd_name, rc);
+               RETURN(rc);
+       }
+
        start = logname[0];
        if (start == '#' || start == '[') {
                rc = str2logid(&logid, logname, data->ioc_inllen1);
@@ -339,10 +346,17 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
        switch (cmd) {
        case OBD_IOC_LLOG_INFO: {
                int l;
-               int remains = data->ioc_inllen2 +
-                             ALIGN(data->ioc_inllen1, 8);
-               char *out = data->ioc_bulk;
+               int remains;
+               char *out;
 
+               if (!data->ioc_inllen2) {
+                       rc = -EINVAL;
+                       CERROR("%s: no buffer for log header info: rc = %d\n",
+                              ctxt->loc_obd->obd_name, rc);
+                       GOTO(out_close, rc);
+               }
+               remains = data->ioc_inllen2 + ALIGN(data->ioc_inllen1, 8);
+               out = data->ioc_bulk;
                l = snprintf(out, remains,
                             "logid:            "DFID"\n"
                             "flags:            %x (%s)\n"
@@ -357,14 +371,19 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
                out += l;
                remains -= l;
                if (remains <= 0) {
-                       CERROR("%s: not enough space for log header info\n",
-                              ctxt->loc_obd->obd_name);
                        rc = -ENOSPC;
+                       CERROR("%s: no space for log header info: rc = %d\n",
+                              ctxt->loc_obd->obd_name, rc);
                }
                break;
        }
        case OBD_IOC_LLOG_CHECK:
-               LASSERT(data->ioc_inllen1 > 0);
+               if (!data->ioc_inllen1) {
+                       rc = -EINVAL;
+                       CERROR("%s: no buffer for log header info: rc = %d\n",
+                              ctxt->loc_obd->obd_name, rc);
+                       GOTO(out_close, rc);
+               }
                rc = llog_process(env, handle, llog_check_cb, data, NULL);
                if (rc == -LLOG_EEMPTY)
                        rc = 0;
@@ -379,8 +398,18 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
                        .lpcd_last_idx = 0,
                };
 
-               if (!data->ioc_inllen2 || !data->ioc_inllen3)
-                       GOTO(out_close, rc = -EINVAL);
+               if (!data->ioc_inllen2 || data->ioc_inlbuf2[0] == '\0') {
+                       rc = -EINVAL;
+                       CERROR("%s: no start index to print records: rc = %d\n",
+                              ctxt->loc_obd->obd_name, rc);
+                       GOTO(out_close, rc);
+               }
+               if (!data->ioc_inllen3 || data->ioc_inlbuf3[0] == '\0') {
+                       rc = -EINVAL;
+                       CERROR("%s: no end index to print records: rc = %d\n",
+                              ctxt->loc_obd->obd_name, rc);
+                       GOTO(out_close, rc);
+               }
 
                bufs = data->ioc_inllen4 +
                        ALIGN(data->ioc_inllen1, 8) +
@@ -421,6 +450,12 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
                struct llog_logid plain;
                u32 lgc_index;
 
+               if (!data->ioc_inllen3 || data->ioc_inlbuf3[0] == '\0') {
+                       rc = -EINVAL;
+                       CERROR("%s: no index to cancel record: rc = %d\n",
+                              ctxt->loc_obd->obd_name, rc);
+                       GOTO(out_close, rc);
+               }
                rc = kstrtouint(data->ioc_inlbuf3, 0, &lgc_index);
                if (rc)
                        GOTO(out_close, rc);
@@ -433,7 +468,8 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
                        GOTO(out_close, rc = -EINVAL);
                }
 
-               if (data->ioc_inlbuf2 == NULL) /* catalog but no logid */
+               /* catalog but no logid */
+               if (!data->ioc_inlbuf2 || data->ioc_inlbuf2[0] == '\0')
                        GOTO(out_close, rc = -ENOTTY);
 
                rc = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
@@ -472,9 +508,10 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt,
                break;
        }
        default:
-               CERROR("%s: Unknown ioctl cmd %#x\n",
-                      ctxt->loc_obd->obd_name, cmd);
-               GOTO(out_close, rc = -ENOTTY);
+               rc = -ENOTTY;
+               CERROR("%s: Unknown llog_ioctl cmd %#x: rc = %d\n",
+                      ctxt->loc_obd->obd_name, cmd, rc);
+               GOTO(out_close, rc);
        }
 
 out_close: