From: Dan Carpenter <dan.carpenter@oracle.com>
To: sgarzare@redhat.com
Cc: virtualization@lists.linux-foundation.org
Subject: [bug report] vdpa_sim_blk: implement ramdisk behaviour
Date: Wed, 29 Sep 2021 14:37:42 +0300 [thread overview]
Message-ID: <20210929113742.GA7928@kili> (raw)
Hello Stefano Garzarella,
The patch 7d189f617f83: "vdpa_sim_blk: implement ramdisk behaviour"
from Mar 15, 2021, leads to the following
Smatch static checker warning:
drivers/vdpa/vdpa_sim/vdpa_sim_blk.c:179 vdpasim_blk_handle_req()
warn: unsigned subtraction: 'to_push - pushed' use '!='
drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
61 static bool vdpasim_blk_handle_req(struct vdpasim *vdpasim,
62 struct vdpasim_virtqueue *vq)
63 {
64 size_t pushed = 0, to_pull, to_push;
65 struct virtio_blk_outhdr hdr;
66 ssize_t bytes;
67 loff_t offset;
68 u64 sector;
69 u8 status;
70 u32 type;
71 int ret;
72
73 ret = vringh_getdesc_iotlb(&vq->vring, &vq->out_iov, &vq->in_iov,
74 &vq->head, GFP_ATOMIC);
75 if (ret != 1)
76 return false;
77
78 if (vq->out_iov.used < 1 || vq->in_iov.used < 1) {
79 dev_err(&vdpasim->vdpa.dev, "missing headers - out_iov: %u in_iov %u\n",
80 vq->out_iov.used, vq->in_iov.used);
81 return false;
82 }
83
84 if (vq->in_iov.iov[vq->in_iov.used - 1].iov_len < 1) {
85 dev_err(&vdpasim->vdpa.dev, "request in header too short\n");
86 return false;
87 }
88
89 /* The last byte is the status and we checked if the last iov has
90 * enough room for it.
91 */
92 to_push = vringh_kiov_length(&vq->in_iov) - 1;
Are you positive that vringh_kiov_length() cannot be zero? I looked at
the range_check() and there is no check for "if (*len == 0)".
93
94 to_pull = vringh_kiov_length(&vq->out_iov);
95
96 bytes = vringh_iov_pull_iotlb(&vq->vring, &vq->out_iov, &hdr,
97 sizeof(hdr));
98 if (bytes != sizeof(hdr)) {
99 dev_err(&vdpasim->vdpa.dev, "request out header too short\n");
100 return false;
101 }
102
103 to_pull -= bytes;
The same "bytes" is used for both to_pull and to_push. In this
assignment it would only be used for the default case which prints an
error message.
104
105 type = vdpasim32_to_cpu(vdpasim, hdr.type);
106 sector = vdpasim64_to_cpu(vdpasim, hdr.sector);
107 offset = sector << SECTOR_SHIFT;
108 status = VIRTIO_BLK_S_OK;
109
110 switch (type) {
111 case VIRTIO_BLK_T_IN:
112 if (!vdpasim_blk_check_range(sector, to_push)) {
113 dev_err(&vdpasim->vdpa.dev,
114 "reading over the capacity - offset: 0x%llx len: 0x%zx\n",
115 offset, to_push);
116 status = VIRTIO_BLK_S_IOERR;
117 break;
118 }
119
120 bytes = vringh_iov_push_iotlb(&vq->vring, &vq->in_iov,
121 vdpasim->buffer + offset,
122 to_push);
123 if (bytes < 0) {
124 dev_err(&vdpasim->vdpa.dev,
125 "vringh_iov_push_iotlb() error: %zd offset: 0x%llx len: 0x%zx\n",
126 bytes, offset, to_push);
127 status = VIRTIO_BLK_S_IOERR;
128 break;
129 }
130
131 pushed += bytes;
132 break;
133
134 case VIRTIO_BLK_T_OUT:
135 if (!vdpasim_blk_check_range(sector, to_pull)) {
136 dev_err(&vdpasim->vdpa.dev,
137 "writing over the capacity - offset: 0x%llx len: 0x%zx\n",
138 offset, to_pull);
139 status = VIRTIO_BLK_S_IOERR;
140 break;
141 }
142
143 bytes = vringh_iov_pull_iotlb(&vq->vring, &vq->out_iov,
144 vdpasim->buffer + offset,
145 to_pull);
Here "bytes" is to_pull again.
146 if (bytes < 0) {
147 dev_err(&vdpasim->vdpa.dev,
148 "vringh_iov_pull_iotlb() error: %zd offset: 0x%llx len: 0x%zx\n",
149 bytes, offset, to_pull);
150 status = VIRTIO_BLK_S_IOERR;
151 break;
152 }
153 break;
154
155 case VIRTIO_BLK_T_GET_ID:
156 bytes = vringh_iov_push_iotlb(&vq->vring, &vq->in_iov,
157 vdpasim_blk_id,
158 VIRTIO_BLK_ID_BYTES);
Do we know that to_push is larger than VIRTIO_BLK_ID_BYTES?
159 if (bytes < 0) {
160 dev_err(&vdpasim->vdpa.dev,
161 "vringh_iov_push_iotlb() error: %zd\n", bytes);
162 status = VIRTIO_BLK_S_IOERR;
163 break;
164 }
165
166 pushed += bytes;
167 break;
168
169 default:
170 dev_warn(&vdpasim->vdpa.dev,
171 "Unsupported request type %d\n", type);
172 status = VIRTIO_BLK_S_IOERR;
173 break;
174 }
175
176 /* If some operations fail, we need to skip the remaining bytes
177 * to put the status in the last byte
178 */
--> 179 if (to_push - pushed > 0)
What I'm doing here is I'm looking for places where there are signedness
bugs such that "pushed > to_push" and the subtraction results in a high
positive value instead of a negative value.
I think there are potential issues here. It's definitely not clear
without reading a lot of context whether this code is safe.
180 vringh_kiov_advance(&vq->in_iov, to_push - pushed);
181
182 /* Last byte is the status */
183 bytes = vringh_iov_push_iotlb(&vq->vring, &vq->in_iov, &status, 1);
184 if (bytes != 1)
185 return false;
186
187 pushed += bytes;
188
189 /* Make sure data is wrote before advancing index */
190 smp_wmb();
191
192 vringh_complete_iotlb(&vq->vring, vq->head, pushed);
193
194 return true;
195 }
regards,
dan carpenter
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
next reply other threads:[~2021-09-29 11:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-29 11:37 Dan Carpenter [this message]
2021-09-29 11:46 ` [bug report] vdpa_sim_blk: implement ramdisk behaviour Dan Carpenter
2021-09-29 12:07 ` Stefano Garzarella
2021-09-29 13:22 ` Dan Carpenter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210929113742.GA7928@kili \
--to=dan.carpenter@oracle.com \
--cc=sgarzare@redhat.com \
--cc=virtualization@lists.linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.