]> git.samba.org - sfrench/cifs-2.6.git/blob - fs/dlm/midcomms.c
selinux: kill 'flags' argument in avc_has_perm_flags() and avc_audit()
[sfrench/cifs-2.6.git] / fs / dlm / midcomms.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /******************************************************************************
3 *******************************************************************************
4 **
5 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
6 **  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
7 **
8 **
9 *******************************************************************************
10 ******************************************************************************/
11
12 /*
13  * midcomms.c
14  *
15  * This is the appallingly named "mid-level" comms layer.
16  *
17  * Its purpose is to take packets from the "real" comms layer,
18  * split them up into packets and pass them to the interested
19  * part of the locking mechanism.
20  *
21  * It also takes messages from the locking layer, formats them
22  * into packets and sends them to the comms layer.
23  */
24
25 #include "dlm_internal.h"
26 #include "lowcomms.h"
27 #include "config.h"
28 #include "lock.h"
29 #include "midcomms.h"
30
31 /*
32  * Called from the low-level comms layer to process a buffer of
33  * commands.
34  */
35
36 int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
37 {
38         const unsigned char *ptr = buf;
39         const struct dlm_header *hd;
40         uint16_t msglen;
41         int ret = 0;
42
43         while (len >= sizeof(struct dlm_header)) {
44                 hd = (struct dlm_header *)ptr;
45
46                 /* no message should be more than DEFAULT_BUFFER_SIZE or
47                  * less than dlm_header size.
48                  *
49                  * Some messages does not have a 8 byte length boundary yet
50                  * which can occur in a unaligned memory access of some dlm
51                  * messages. However this problem need to be fixed at the
52                  * sending side, for now it seems nobody run into architecture
53                  * related issues yet but it slows down some processing.
54                  * Fixing this issue should be scheduled in future by doing
55                  * the next major version bump.
56                  */
57                 msglen = le16_to_cpu(hd->h_length);
58                 if (msglen > DEFAULT_BUFFER_SIZE ||
59                     msglen < sizeof(struct dlm_header)) {
60                         log_print("received invalid length header: %u from node %d, will abort message parsing",
61                                   msglen, nodeid);
62                         return -EBADMSG;
63                 }
64
65                 /* caller will take care that leftover
66                  * will be parsed next call with more data
67                  */
68                 if (msglen > len)
69                         break;
70
71                 switch (hd->h_cmd) {
72                 case DLM_MSG:
73                         if (msglen < sizeof(struct dlm_message)) {
74                                 log_print("dlm msg too small: %u, will skip this message",
75                                           msglen);
76                                 goto skip;
77                         }
78
79                         break;
80                 case DLM_RCOM:
81                         if (msglen < sizeof(struct dlm_rcom)) {
82                                 log_print("dlm rcom msg too small: %u, will skip this message",
83                                           msglen);
84                                 goto skip;
85                         }
86
87                         break;
88                 default:
89                         log_print("unsupported h_cmd received: %u, will skip this message",
90                                   hd->h_cmd);
91                         goto skip;
92                 }
93
94                 dlm_receive_buffer((union dlm_packet *)ptr, nodeid);
95
96 skip:
97                 ret += msglen;
98                 len -= msglen;
99                 ptr += msglen;
100         }
101
102         return ret;
103 }
104