cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cmservice.c (16029B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* AFS Cache Manager Service
      3 *
      4 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/init.h>
     10#include <linux/slab.h>
     11#include <linux/sched.h>
     12#include <linux/ip.h>
     13#include "internal.h"
     14#include "afs_cm.h"
     15#include "protocol_yfs.h"
     16
     17static int afs_deliver_cb_init_call_back_state(struct afs_call *);
     18static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
     19static int afs_deliver_cb_probe(struct afs_call *);
     20static int afs_deliver_cb_callback(struct afs_call *);
     21static int afs_deliver_cb_probe_uuid(struct afs_call *);
     22static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
     23static void afs_cm_destructor(struct afs_call *);
     24static void SRXAFSCB_CallBack(struct work_struct *);
     25static void SRXAFSCB_InitCallBackState(struct work_struct *);
     26static void SRXAFSCB_Probe(struct work_struct *);
     27static void SRXAFSCB_ProbeUuid(struct work_struct *);
     28static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
     29
     30static int afs_deliver_yfs_cb_callback(struct afs_call *);
     31
     32/*
     33 * CB.CallBack operation type
     34 */
     35static const struct afs_call_type afs_SRXCBCallBack = {
     36	.name		= "CB.CallBack",
     37	.deliver	= afs_deliver_cb_callback,
     38	.destructor	= afs_cm_destructor,
     39	.work		= SRXAFSCB_CallBack,
     40};
     41
     42/*
     43 * CB.InitCallBackState operation type
     44 */
     45static const struct afs_call_type afs_SRXCBInitCallBackState = {
     46	.name		= "CB.InitCallBackState",
     47	.deliver	= afs_deliver_cb_init_call_back_state,
     48	.destructor	= afs_cm_destructor,
     49	.work		= SRXAFSCB_InitCallBackState,
     50};
     51
     52/*
     53 * CB.InitCallBackState3 operation type
     54 */
     55static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
     56	.name		= "CB.InitCallBackState3",
     57	.deliver	= afs_deliver_cb_init_call_back_state3,
     58	.destructor	= afs_cm_destructor,
     59	.work		= SRXAFSCB_InitCallBackState,
     60};
     61
     62/*
     63 * CB.Probe operation type
     64 */
     65static const struct afs_call_type afs_SRXCBProbe = {
     66	.name		= "CB.Probe",
     67	.deliver	= afs_deliver_cb_probe,
     68	.destructor	= afs_cm_destructor,
     69	.work		= SRXAFSCB_Probe,
     70};
     71
     72/*
     73 * CB.ProbeUuid operation type
     74 */
     75static const struct afs_call_type afs_SRXCBProbeUuid = {
     76	.name		= "CB.ProbeUuid",
     77	.deliver	= afs_deliver_cb_probe_uuid,
     78	.destructor	= afs_cm_destructor,
     79	.work		= SRXAFSCB_ProbeUuid,
     80};
     81
     82/*
     83 * CB.TellMeAboutYourself operation type
     84 */
     85static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
     86	.name		= "CB.TellMeAboutYourself",
     87	.deliver	= afs_deliver_cb_tell_me_about_yourself,
     88	.destructor	= afs_cm_destructor,
     89	.work		= SRXAFSCB_TellMeAboutYourself,
     90};
     91
     92/*
     93 * YFS CB.CallBack operation type
     94 */
     95static const struct afs_call_type afs_SRXYFSCB_CallBack = {
     96	.name		= "YFSCB.CallBack",
     97	.deliver	= afs_deliver_yfs_cb_callback,
     98	.destructor	= afs_cm_destructor,
     99	.work		= SRXAFSCB_CallBack,
    100};
    101
    102/*
    103 * route an incoming cache manager call
    104 * - return T if supported, F if not
    105 */
    106bool afs_cm_incoming_call(struct afs_call *call)
    107{
    108	_enter("{%u, CB.OP %u}", call->service_id, call->operation_ID);
    109
    110	switch (call->operation_ID) {
    111	case CBCallBack:
    112		call->type = &afs_SRXCBCallBack;
    113		return true;
    114	case CBInitCallBackState:
    115		call->type = &afs_SRXCBInitCallBackState;
    116		return true;
    117	case CBInitCallBackState3:
    118		call->type = &afs_SRXCBInitCallBackState3;
    119		return true;
    120	case CBProbe:
    121		call->type = &afs_SRXCBProbe;
    122		return true;
    123	case CBProbeUuid:
    124		call->type = &afs_SRXCBProbeUuid;
    125		return true;
    126	case CBTellMeAboutYourself:
    127		call->type = &afs_SRXCBTellMeAboutYourself;
    128		return true;
    129	case YFSCBCallBack:
    130		if (call->service_id != YFS_CM_SERVICE)
    131			return false;
    132		call->type = &afs_SRXYFSCB_CallBack;
    133		return true;
    134	default:
    135		return false;
    136	}
    137}
    138
    139/*
    140 * Find the server record by peer address and record a probe to the cache
    141 * manager from a server.
    142 */
    143static int afs_find_cm_server_by_peer(struct afs_call *call)
    144{
    145	struct sockaddr_rxrpc srx;
    146	struct afs_server *server;
    147
    148	rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
    149
    150	server = afs_find_server(call->net, &srx);
    151	if (!server) {
    152		trace_afs_cm_no_server(call, &srx);
    153		return 0;
    154	}
    155
    156	call->server = server;
    157	return 0;
    158}
    159
    160/*
    161 * Find the server record by server UUID and record a probe to the cache
    162 * manager from a server.
    163 */
    164static int afs_find_cm_server_by_uuid(struct afs_call *call,
    165				      struct afs_uuid *uuid)
    166{
    167	struct afs_server *server;
    168
    169	rcu_read_lock();
    170	server = afs_find_server_by_uuid(call->net, call->request);
    171	rcu_read_unlock();
    172	if (!server) {
    173		trace_afs_cm_no_server_u(call, call->request);
    174		return 0;
    175	}
    176
    177	call->server = server;
    178	return 0;
    179}
    180
    181/*
    182 * Clean up a cache manager call.
    183 */
    184static void afs_cm_destructor(struct afs_call *call)
    185{
    186	kfree(call->buffer);
    187	call->buffer = NULL;
    188}
    189
    190/*
    191 * Abort a service call from within an action function.
    192 */
    193static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error,
    194				   const char *why)
    195{
    196	rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
    197				abort_code, error, why);
    198	afs_set_call_complete(call, error, 0);
    199}
    200
    201/*
    202 * The server supplied a list of callbacks that it wanted to break.
    203 */
    204static void SRXAFSCB_CallBack(struct work_struct *work)
    205{
    206	struct afs_call *call = container_of(work, struct afs_call, work);
    207
    208	_enter("");
    209
    210	/* We need to break the callbacks before sending the reply as the
    211	 * server holds up change visibility till it receives our reply so as
    212	 * to maintain cache coherency.
    213	 */
    214	if (call->server) {
    215		trace_afs_server(call->server,
    216				 atomic_read(&call->server->ref),
    217				 atomic_read(&call->server->active),
    218				 afs_server_trace_callback);
    219		afs_break_callbacks(call->server, call->count, call->request);
    220	}
    221
    222	afs_send_empty_reply(call);
    223	afs_put_call(call);
    224	_leave("");
    225}
    226
    227/*
    228 * deliver request data to a CB.CallBack call
    229 */
    230static int afs_deliver_cb_callback(struct afs_call *call)
    231{
    232	struct afs_callback_break *cb;
    233	__be32 *bp;
    234	int ret, loop;
    235
    236	_enter("{%u}", call->unmarshall);
    237
    238	switch (call->unmarshall) {
    239	case 0:
    240		afs_extract_to_tmp(call);
    241		call->unmarshall++;
    242
    243		/* extract the FID array and its count in two steps */
    244		fallthrough;
    245	case 1:
    246		_debug("extract FID count");
    247		ret = afs_extract_data(call, true);
    248		if (ret < 0)
    249			return ret;
    250
    251		call->count = ntohl(call->tmp);
    252		_debug("FID count: %u", call->count);
    253		if (call->count > AFSCBMAX)
    254			return afs_protocol_error(call, afs_eproto_cb_fid_count);
    255
    256		call->buffer = kmalloc(array3_size(call->count, 3, 4),
    257				       GFP_KERNEL);
    258		if (!call->buffer)
    259			return -ENOMEM;
    260		afs_extract_to_buf(call, call->count * 3 * 4);
    261		call->unmarshall++;
    262
    263		fallthrough;
    264	case 2:
    265		_debug("extract FID array");
    266		ret = afs_extract_data(call, true);
    267		if (ret < 0)
    268			return ret;
    269
    270		_debug("unmarshall FID array");
    271		call->request = kcalloc(call->count,
    272					sizeof(struct afs_callback_break),
    273					GFP_KERNEL);
    274		if (!call->request)
    275			return -ENOMEM;
    276
    277		cb = call->request;
    278		bp = call->buffer;
    279		for (loop = call->count; loop > 0; loop--, cb++) {
    280			cb->fid.vid	= ntohl(*bp++);
    281			cb->fid.vnode	= ntohl(*bp++);
    282			cb->fid.unique	= ntohl(*bp++);
    283		}
    284
    285		afs_extract_to_tmp(call);
    286		call->unmarshall++;
    287
    288		/* extract the callback array and its count in two steps */
    289		fallthrough;
    290	case 3:
    291		_debug("extract CB count");
    292		ret = afs_extract_data(call, true);
    293		if (ret < 0)
    294			return ret;
    295
    296		call->count2 = ntohl(call->tmp);
    297		_debug("CB count: %u", call->count2);
    298		if (call->count2 != call->count && call->count2 != 0)
    299			return afs_protocol_error(call, afs_eproto_cb_count);
    300		call->iter = &call->def_iter;
    301		iov_iter_discard(&call->def_iter, READ, call->count2 * 3 * 4);
    302		call->unmarshall++;
    303
    304		fallthrough;
    305	case 4:
    306		_debug("extract discard %zu/%u",
    307		       iov_iter_count(call->iter), call->count2 * 3 * 4);
    308
    309		ret = afs_extract_data(call, false);
    310		if (ret < 0)
    311			return ret;
    312
    313		call->unmarshall++;
    314		fallthrough;
    315
    316	case 5:
    317		break;
    318	}
    319
    320	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
    321		return afs_io_error(call, afs_io_error_cm_reply);
    322
    323	/* we'll need the file server record as that tells us which set of
    324	 * vnodes to operate upon */
    325	return afs_find_cm_server_by_peer(call);
    326}
    327
    328/*
    329 * allow the fileserver to request callback state (re-)initialisation
    330 */
    331static void SRXAFSCB_InitCallBackState(struct work_struct *work)
    332{
    333	struct afs_call *call = container_of(work, struct afs_call, work);
    334
    335	_enter("{%p}", call->server);
    336
    337	if (call->server)
    338		afs_init_callback_state(call->server);
    339	afs_send_empty_reply(call);
    340	afs_put_call(call);
    341	_leave("");
    342}
    343
    344/*
    345 * deliver request data to a CB.InitCallBackState call
    346 */
    347static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
    348{
    349	int ret;
    350
    351	_enter("");
    352
    353	afs_extract_discard(call, 0);
    354	ret = afs_extract_data(call, false);
    355	if (ret < 0)
    356		return ret;
    357
    358	/* we'll need the file server record as that tells us which set of
    359	 * vnodes to operate upon */
    360	return afs_find_cm_server_by_peer(call);
    361}
    362
    363/*
    364 * deliver request data to a CB.InitCallBackState3 call
    365 */
    366static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
    367{
    368	struct afs_uuid *r;
    369	unsigned loop;
    370	__be32 *b;
    371	int ret;
    372
    373	_enter("");
    374
    375	_enter("{%u}", call->unmarshall);
    376
    377	switch (call->unmarshall) {
    378	case 0:
    379		call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
    380		if (!call->buffer)
    381			return -ENOMEM;
    382		afs_extract_to_buf(call, 11 * sizeof(__be32));
    383		call->unmarshall++;
    384
    385		fallthrough;
    386	case 1:
    387		_debug("extract UUID");
    388		ret = afs_extract_data(call, false);
    389		switch (ret) {
    390		case 0:		break;
    391		case -EAGAIN:	return 0;
    392		default:	return ret;
    393		}
    394
    395		_debug("unmarshall UUID");
    396		call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
    397		if (!call->request)
    398			return -ENOMEM;
    399
    400		b = call->buffer;
    401		r = call->request;
    402		r->time_low			= b[0];
    403		r->time_mid			= htons(ntohl(b[1]));
    404		r->time_hi_and_version		= htons(ntohl(b[2]));
    405		r->clock_seq_hi_and_reserved 	= ntohl(b[3]);
    406		r->clock_seq_low		= ntohl(b[4]);
    407
    408		for (loop = 0; loop < 6; loop++)
    409			r->node[loop] = ntohl(b[loop + 5]);
    410
    411		call->unmarshall++;
    412		fallthrough;
    413
    414	case 2:
    415		break;
    416	}
    417
    418	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
    419		return afs_io_error(call, afs_io_error_cm_reply);
    420
    421	/* we'll need the file server record as that tells us which set of
    422	 * vnodes to operate upon */
    423	return afs_find_cm_server_by_uuid(call, call->request);
    424}
    425
    426/*
    427 * allow the fileserver to see if the cache manager is still alive
    428 */
    429static void SRXAFSCB_Probe(struct work_struct *work)
    430{
    431	struct afs_call *call = container_of(work, struct afs_call, work);
    432
    433	_enter("");
    434	afs_send_empty_reply(call);
    435	afs_put_call(call);
    436	_leave("");
    437}
    438
    439/*
    440 * deliver request data to a CB.Probe call
    441 */
    442static int afs_deliver_cb_probe(struct afs_call *call)
    443{
    444	int ret;
    445
    446	_enter("");
    447
    448	afs_extract_discard(call, 0);
    449	ret = afs_extract_data(call, false);
    450	if (ret < 0)
    451		return ret;
    452
    453	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
    454		return afs_io_error(call, afs_io_error_cm_reply);
    455	return afs_find_cm_server_by_peer(call);
    456}
    457
    458/*
    459 * Allow the fileserver to quickly find out if the cache manager has been
    460 * rebooted.
    461 */
    462static void SRXAFSCB_ProbeUuid(struct work_struct *work)
    463{
    464	struct afs_call *call = container_of(work, struct afs_call, work);
    465	struct afs_uuid *r = call->request;
    466
    467	_enter("");
    468
    469	if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
    470		afs_send_empty_reply(call);
    471	else
    472		afs_abort_service_call(call, 1, 1, "K-1");
    473
    474	afs_put_call(call);
    475	_leave("");
    476}
    477
    478/*
    479 * deliver request data to a CB.ProbeUuid call
    480 */
    481static int afs_deliver_cb_probe_uuid(struct afs_call *call)
    482{
    483	struct afs_uuid *r;
    484	unsigned loop;
    485	__be32 *b;
    486	int ret;
    487
    488	_enter("{%u}", call->unmarshall);
    489
    490	switch (call->unmarshall) {
    491	case 0:
    492		call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
    493		if (!call->buffer)
    494			return -ENOMEM;
    495		afs_extract_to_buf(call, 11 * sizeof(__be32));
    496		call->unmarshall++;
    497
    498		fallthrough;
    499	case 1:
    500		_debug("extract UUID");
    501		ret = afs_extract_data(call, false);
    502		switch (ret) {
    503		case 0:		break;
    504		case -EAGAIN:	return 0;
    505		default:	return ret;
    506		}
    507
    508		_debug("unmarshall UUID");
    509		call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
    510		if (!call->request)
    511			return -ENOMEM;
    512
    513		b = call->buffer;
    514		r = call->request;
    515		r->time_low			= b[0];
    516		r->time_mid			= htons(ntohl(b[1]));
    517		r->time_hi_and_version		= htons(ntohl(b[2]));
    518		r->clock_seq_hi_and_reserved 	= ntohl(b[3]);
    519		r->clock_seq_low		= ntohl(b[4]);
    520
    521		for (loop = 0; loop < 6; loop++)
    522			r->node[loop] = ntohl(b[loop + 5]);
    523
    524		call->unmarshall++;
    525		fallthrough;
    526
    527	case 2:
    528		break;
    529	}
    530
    531	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
    532		return afs_io_error(call, afs_io_error_cm_reply);
    533	return afs_find_cm_server_by_peer(call);
    534}
    535
    536/*
    537 * allow the fileserver to ask about the cache manager's capabilities
    538 */
    539static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
    540{
    541	struct afs_call *call = container_of(work, struct afs_call, work);
    542	int loop;
    543
    544	struct {
    545		struct /* InterfaceAddr */ {
    546			__be32 nifs;
    547			__be32 uuid[11];
    548			__be32 ifaddr[32];
    549			__be32 netmask[32];
    550			__be32 mtu[32];
    551		} ia;
    552		struct /* Capabilities */ {
    553			__be32 capcount;
    554			__be32 caps[1];
    555		} cap;
    556	} reply;
    557
    558	_enter("");
    559
    560	memset(&reply, 0, sizeof(reply));
    561
    562	reply.ia.uuid[0] = call->net->uuid.time_low;
    563	reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
    564	reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
    565	reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
    566	reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
    567	for (loop = 0; loop < 6; loop++)
    568		reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
    569
    570	reply.cap.capcount = htonl(1);
    571	reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
    572	afs_send_simple_reply(call, &reply, sizeof(reply));
    573	afs_put_call(call);
    574	_leave("");
    575}
    576
    577/*
    578 * deliver request data to a CB.TellMeAboutYourself call
    579 */
    580static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
    581{
    582	int ret;
    583
    584	_enter("");
    585
    586	afs_extract_discard(call, 0);
    587	ret = afs_extract_data(call, false);
    588	if (ret < 0)
    589		return ret;
    590
    591	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
    592		return afs_io_error(call, afs_io_error_cm_reply);
    593	return afs_find_cm_server_by_peer(call);
    594}
    595
    596/*
    597 * deliver request data to a YFS CB.CallBack call
    598 */
    599static int afs_deliver_yfs_cb_callback(struct afs_call *call)
    600{
    601	struct afs_callback_break *cb;
    602	struct yfs_xdr_YFSFid *bp;
    603	size_t size;
    604	int ret, loop;
    605
    606	_enter("{%u}", call->unmarshall);
    607
    608	switch (call->unmarshall) {
    609	case 0:
    610		afs_extract_to_tmp(call);
    611		call->unmarshall++;
    612
    613		/* extract the FID array and its count in two steps */
    614		fallthrough;
    615	case 1:
    616		_debug("extract FID count");
    617		ret = afs_extract_data(call, true);
    618		if (ret < 0)
    619			return ret;
    620
    621		call->count = ntohl(call->tmp);
    622		_debug("FID count: %u", call->count);
    623		if (call->count > YFSCBMAX)
    624			return afs_protocol_error(call, afs_eproto_cb_fid_count);
    625
    626		size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid));
    627		call->buffer = kmalloc(size, GFP_KERNEL);
    628		if (!call->buffer)
    629			return -ENOMEM;
    630		afs_extract_to_buf(call, size);
    631		call->unmarshall++;
    632
    633		fallthrough;
    634	case 2:
    635		_debug("extract FID array");
    636		ret = afs_extract_data(call, false);
    637		if (ret < 0)
    638			return ret;
    639
    640		_debug("unmarshall FID array");
    641		call->request = kcalloc(call->count,
    642					sizeof(struct afs_callback_break),
    643					GFP_KERNEL);
    644		if (!call->request)
    645			return -ENOMEM;
    646
    647		cb = call->request;
    648		bp = call->buffer;
    649		for (loop = call->count; loop > 0; loop--, cb++) {
    650			cb->fid.vid	= xdr_to_u64(bp->volume);
    651			cb->fid.vnode	= xdr_to_u64(bp->vnode.lo);
    652			cb->fid.vnode_hi = ntohl(bp->vnode.hi);
    653			cb->fid.unique	= ntohl(bp->vnode.unique);
    654			bp++;
    655		}
    656
    657		afs_extract_to_tmp(call);
    658		call->unmarshall++;
    659		fallthrough;
    660
    661	case 3:
    662		break;
    663	}
    664
    665	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
    666		return afs_io_error(call, afs_io_error_cm_reply);
    667
    668	/* We'll need the file server record as that tells us which set of
    669	 * vnodes to operate upon.
    670	 */
    671	return afs_find_cm_server_by_peer(call);
    672}