diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index adfcf71efbda226db86b76a279ce4ad60176f5a2..457dd7e435de539c337e175063985812a1c0e1de 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2361,7 +2361,7 @@ static int lov_get_info(struct obd_export *exp, __u32 keylen, GOTO(out, rc = -ENXIO); } else if (KEY_IS("last_id")) { obd_id *ids = val; - int size = sizeof(obd_id); + unsigned int size = sizeof(obd_id); for (i = 0; i < lov->desc.ld_tgt_count; i++) { if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) continue; diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 76821e47f13a21c8dfbac7c0e350827ca7ff6d2c..450626e0ac77eae603660b263a49ddb0b7307435 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -1301,9 +1301,8 @@ static char *reint_names[] = { static int mds_set_info_rpc(struct obd_export *exp, struct ptlrpc_request *req) { - char *key; - __u32 *val; - int keylen, rc = 0; + void *key, *val; + int keylen, vallen, rc = 0; ENTRY; key = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF, 1); @@ -1313,25 +1312,27 @@ static int mds_set_info_rpc(struct obd_export *exp, struct ptlrpc_request *req) } keylen = lustre_msg_buflen(req->rq_reqmsg, REQ_REC_OFF); - val = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF + 1, sizeof(*val)); - if (val == NULL) { - DEBUG_REQ(D_HA, req, "no set_info val"); - RETURN(-EFAULT); - } + val = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF + 1, 0); + vallen = lustre_msg_buflen(req->rq_reqmsg, REQ_REC_OFF + 1); rc = lustre_pack_reply(req, 1, NULL, NULL); if (rc) RETURN(rc); lustre_msg_set_status(req->rq_repmsg, 0); - if (keylen < strlen("read-only") || - memcmp(key, "read-only", keylen) != 0) - RETURN(-EINVAL); + if (KEY_IS("read-only")) { + if (val == NULL || vallen < sizeof(__u32)) { + DEBUG_REQ(D_HA, req, "no set_info val"); + RETURN(-EFAULT); + } - if (*val) - exp->exp_connect_flags |= OBD_CONNECT_RDONLY; - else - exp->exp_connect_flags &= ~OBD_CONNECT_RDONLY; + if (*(__u32 *)val) + exp->exp_connect_flags |= OBD_CONNECT_RDONLY; + else + exp->exp_connect_flags &= ~OBD_CONNECT_RDONLY; + } else { + RETURN(-EINVAL); + } RETURN(0); } diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index bcdd5f539c3e512e63ac1dacffff81d41bf6ccd1..445e315fd2137a6a8c29e77314c8cfcb0259b1f3 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -3817,28 +3817,40 @@ static int filter_get_info(struct obd_export *exp, __u32 keylen, RETURN(-EINVAL); } - if (keylen == strlen("blocksize") && - memcmp(key, "blocksize", keylen) == 0) { + if (KEY_IS("blocksize")) { __u32 *blocksize = val; + if (blocksize) { + if (*vallen < sizeof(*blocksize)) + RETURN(-EOVERFLOW); + *blocksize = obd->u.obt.obt_sb->s_blocksize; + } *vallen = sizeof(*blocksize); - *blocksize = obd->u.obt.obt_sb->s_blocksize; RETURN(0); } - if (keylen == strlen("blocksize_bits") && - memcmp(key, "blocksize_bits", keylen) == 0) { + if (KEY_IS("blocksize_bits")) { __u32 *blocksize_bits = val; + if (blocksize_bits) { + if (*vallen < sizeof(*blocksize_bits)) + RETURN(-EOVERFLOW); + *blocksize_bits = obd->u.obt.obt_sb->s_blocksize_bits; + } *vallen = sizeof(*blocksize_bits); - *blocksize_bits = obd->u.obt.obt_sb->s_blocksize_bits; RETURN(0); } - if (keylen >= strlen("last_id") && memcmp(key, "last_id", 7) == 0) { + if (KEY_IS("last_id")) { obd_id *last_id = val; /* FIXME: object groups */ - *last_id = filter_last_id(&obd->u.filter, 0); + if (last_id) { + if (*vallen < sizeof(*last_id)) + RETURN(-EOVERFLOW); + *last_id = filter_last_id(&obd->u.filter, 0); + } + *vallen = sizeof(*last_id); RETURN(0); } + CDEBUG(D_IOCTL, "invalid key\n"); RETURN(-EINVAL); } @@ -3871,8 +3883,7 @@ static int filter_set_info_async(struct obd_export *exp, __u32 keylen, RETURN(0); } - if (keylen < strlen(KEY_MDS_CONN) || - memcmp(key, KEY_MDS_CONN, keylen) != 0) + if (!KEY_IS(KEY_MDS_CONN)) RETURN(-EINVAL); LCONSOLE_WARN("%s: received MDS connection from %s\n", obd->obd_name, diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index bab0344ab2d82501222fe0b6ae4335307a193e64..d7bd9ded9d6b763f1e380adb48e871a9b3b6b5a9 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3312,13 +3312,12 @@ static int osc_get_info(struct obd_export *exp, obd_count keylen, if (!vallen || !val) RETURN(-EFAULT); - if (keylen > strlen("lock_to_stripe") && - strcmp(key, "lock_to_stripe") == 0) { + if (KEY_IS("lock_to_stripe")) { __u32 *stripe = val; *vallen = sizeof(*stripe); *stripe = 0; RETURN(0); - } else if (keylen >= strlen("last_id") && strcmp(key, "last_id") == 0) { + } else if (KEY_IS("last_id")) { struct ptlrpc_request *req; obd_id *reply; char *bufs[2] = { NULL, key }; diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 27e25bbd2f9a373fa33fbd97b54ac59aa7649520..4bb2054e7ee61fe653834cde9eae095fee2458ca 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -1268,10 +1268,9 @@ out: static int ost_get_info(struct obd_export *exp, struct ptlrpc_request *req) { - char *key; + void *key, *reply; int keylen, rc = 0; - int size[2] = { sizeof(struct ptlrpc_body), sizeof(obd_id) }; - obd_id *reply; + int size[2] = { sizeof(struct ptlrpc_body), 0 }; ENTRY; key = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF, 1); @@ -1281,16 +1280,20 @@ static int ost_get_info(struct obd_export *exp, struct ptlrpc_request *req) } keylen = lustre_msg_buflen(req->rq_reqmsg, REQ_REC_OFF); - if (keylen < strlen("last_id") || memcmp(key, "last_id", 7) != 0) - RETURN(-EPROTO); + /* call once to get the size to allocate the reply buffer */ + rc = obd_get_info(exp, keylen, key, &size[1], NULL); + if (rc) + RETURN(rc); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) RETURN(rc); reply = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*reply)); + /* call again to fill in the reply buffer */ rc = obd_get_info(exp, keylen, key, size, reply); lustre_msg_set_status(req->rq_repmsg, 0); + RETURN(rc); }