Skip to content

Commit fcd98d4

Browse files
hfreudeVasily Gorbik
authored andcommitted
s390/zcrypt: fix card and queue total counter wrap
The internal statistic counters for the total number of requests processed per card and per queue used integers. So they do wrap after a rather huge amount of crypto requests processed. This patch introduces uint64 counters which should hold much longer but still may wrap. The sysfs attributes request_count for card and queue also used only %ld and now display the counter value with %llu. This is not a security relevant fix. The int overflow which happened is not in any way exploitable as a security breach. Signed-off-by: Harald Freudenberger <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent aab73d2 commit fcd98d4

File tree

4 files changed

+18
-16
lines changed

4 files changed

+18
-16
lines changed

drivers/s390/crypto/ap_bus.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ struct ap_card {
162162
unsigned int functions; /* AP device function bitfield. */
163163
int queue_depth; /* AP queue depth.*/
164164
int id; /* AP card number. */
165-
atomic_t total_request_count; /* # requests ever for this AP device.*/
165+
atomic64_t total_request_count; /* # requests ever for this AP device.*/
166166
};
167167

168168
#define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device)
@@ -179,7 +179,7 @@ struct ap_queue {
179179
enum ap_state state; /* State of the AP device. */
180180
int pendingq_count; /* # requests on pendingq list. */
181181
int requestq_count; /* # requests on requestq list. */
182-
int total_request_count; /* # requests ever for this AP device.*/
182+
u64 total_request_count; /* # requests ever for this AP device.*/
183183
int request_timeout; /* Request timeout in jiffies. */
184184
struct timer_list timeout; /* Timer for request timeouts. */
185185
struct list_head pendingq; /* List of message sent to AP queue. */

drivers/s390/crypto/ap_card.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ static ssize_t request_count_show(struct device *dev,
6363
char *buf)
6464
{
6565
struct ap_card *ac = to_ap_card(dev);
66-
unsigned int req_cnt;
66+
u64 req_cnt;
6767

6868
req_cnt = 0;
6969
spin_lock_bh(&ap_list_lock);
70-
req_cnt = atomic_read(&ac->total_request_count);
70+
req_cnt = atomic64_read(&ac->total_request_count);
7171
spin_unlock_bh(&ap_list_lock);
72-
return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
72+
return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
7373
}
7474

7575
static ssize_t request_count_store(struct device *dev,
@@ -83,7 +83,7 @@ static ssize_t request_count_store(struct device *dev,
8383
for_each_ap_queue(aq, ac)
8484
aq->total_request_count = 0;
8585
spin_unlock_bh(&ap_list_lock);
86-
atomic_set(&ac->total_request_count, 0);
86+
atomic64_set(&ac->total_request_count, 0);
8787

8888
return count;
8989
}

drivers/s390/crypto/ap_queue.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,12 @@ static ssize_t request_count_show(struct device *dev,
479479
char *buf)
480480
{
481481
struct ap_queue *aq = to_ap_queue(dev);
482-
unsigned int req_cnt;
482+
u64 req_cnt;
483483

484484
spin_lock_bh(&aq->lock);
485485
req_cnt = aq->total_request_count;
486486
spin_unlock_bh(&aq->lock);
487-
return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
487+
return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
488488
}
489489

490490
static ssize_t request_count_store(struct device *dev,
@@ -676,7 +676,7 @@ void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg)
676676
list_add_tail(&ap_msg->list, &aq->requestq);
677677
aq->requestq_count++;
678678
aq->total_request_count++;
679-
atomic_inc(&aq->card->total_request_count);
679+
atomic64_inc(&aq->card->total_request_count);
680680
/* Send/receive as many request from the queue as possible. */
681681
ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL));
682682
spin_unlock_bh(&aq->lock);

drivers/s390/crypto/zcrypt_api.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,8 @@ static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
606606
weight += atomic_read(&zc->load);
607607
pref_weight += atomic_read(&pref_zc->load);
608608
if (weight == pref_weight)
609-
return atomic_read(&zc->card->total_request_count) >
610-
atomic_read(&pref_zc->card->total_request_count);
609+
return atomic64_read(&zc->card->total_request_count) >
610+
atomic64_read(&pref_zc->card->total_request_count);
611611
return weight > pref_weight;
612612
}
613613

@@ -1226,11 +1226,12 @@ static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters)
12261226
spin_unlock(&zcrypt_list_lock);
12271227
}
12281228

1229-
static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters)
1229+
static void zcrypt_perdev_reqcnt(u32 reqcnt[], size_t max_adapters)
12301230
{
12311231
struct zcrypt_card *zc;
12321232
struct zcrypt_queue *zq;
12331233
int card;
1234+
u64 cnt;
12341235

12351236
memset(reqcnt, 0, sizeof(int) * max_adapters);
12361237
spin_lock(&zcrypt_list_lock);
@@ -1242,8 +1243,9 @@ static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters)
12421243
|| card >= max_adapters)
12431244
continue;
12441245
spin_lock(&zq->queue->lock);
1245-
reqcnt[card] = zq->queue->total_request_count;
1246+
cnt = zq->queue->total_request_count;
12461247
spin_unlock(&zq->queue->lock);
1248+
reqcnt[card] = (cnt < UINT_MAX) ? (u32) cnt : UINT_MAX;
12471249
}
12481250
}
12491251
local_bh_enable();
@@ -1421,9 +1423,9 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
14211423
return 0;
14221424
}
14231425
case ZCRYPT_PERDEV_REQCNT: {
1424-
int *reqcnt;
1426+
u32 *reqcnt;
14251427

1426-
reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL);
1428+
reqcnt = kcalloc(AP_DEVICES, sizeof(u32), GFP_KERNEL);
14271429
if (!reqcnt)
14281430
return -ENOMEM;
14291431
zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES);
@@ -1480,7 +1482,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
14801482
}
14811483
case Z90STAT_PERDEV_REQCNT: {
14821484
/* the old ioctl supports only 64 adapters */
1483-
int reqcnt[MAX_ZDEV_CARDIDS];
1485+
u32 reqcnt[MAX_ZDEV_CARDIDS];
14841486

14851487
zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS);
14861488
if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt)))

0 commit comments

Comments
 (0)