Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipmi: Rework user message limit handling

The limit on the number of user messages had a number of issues,
improper counting in some cases and a use after free.

Restructure how this is all done to handle more in the receive message
allocation routine, so all refcouting and user message limit counts
are done in that routine. It's a lot cleaner and safer.

Reported-by: Gilles BULOZ <gilles.buloz@kontron.com>
Closes: https://lore.kernel.org/lkml/aLsw6G0GyqfpKs2S@mail.minyard.net/
Fixes: 8e76741c3d8b ("ipmi: Add a limit on the number of users that may use IPMI")
Cc: <stable@vger.kernel.org> # 4.19
Signed-off-by: Corey Minyard <corey@minyard.net>
Tested-by: Gilles BULOZ <gilles.buloz@kontron.com>

+203 -223
+203 -223
drivers/char/ipmi/ipmi_msghandler.c
··· 38 38 39 39 #define IPMI_DRIVER_VERSION "39.2" 40 40 41 - static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); 41 + static struct ipmi_recv_msg *ipmi_alloc_recv_msg(struct ipmi_user *user); 42 + static void ipmi_set_recv_msg_user(struct ipmi_recv_msg *msg, 43 + struct ipmi_user *user); 42 44 static int ipmi_init_msghandler(void); 43 45 static void smi_work(struct work_struct *t); 44 46 static void handle_new_recv_msgs(struct ipmi_smi *intf); ··· 957 955 * risk. At this moment, simply skip it in that case. 958 956 */ 959 957 ipmi_free_recv_msg(msg); 960 - atomic_dec(&msg->user->nr_msgs); 961 958 } else { 962 959 /* 963 960 * Deliver it in smi_work. The message will hold a ··· 1612 1611 } 1613 1612 1614 1613 list_for_each_entry_safe(msg, msg2, &msgs, link) { 1615 - msg->user = user; 1616 - kref_get(&user->refcount); 1614 + ipmi_set_recv_msg_user(msg, user); 1617 1615 deliver_local_response(intf, msg); 1618 1616 } 1619 1617 } ··· 2277 2277 int run_to_completion = READ_ONCE(intf->run_to_completion); 2278 2278 int rv = 0; 2279 2279 2280 - if (user) { 2281 - if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) { 2282 - /* Decrement will happen at the end of the routine. */ 2283 - rv = -EBUSY; 2284 - goto out; 2285 - } 2286 - } 2287 - 2288 - if (supplied_recv) 2280 + if (supplied_recv) { 2289 2281 recv_msg = supplied_recv; 2290 - else { 2291 - recv_msg = ipmi_alloc_recv_msg(); 2292 - if (recv_msg == NULL) { 2293 - rv = -ENOMEM; 2294 - goto out; 2295 - } 2282 + recv_msg->user = user; 2283 + if (user) 2284 + atomic_inc(&user->nr_msgs); 2285 + } else { 2286 + recv_msg = ipmi_alloc_recv_msg(user); 2287 + if (IS_ERR(recv_msg)) 2288 + return PTR_ERR(recv_msg); 2296 2289 } 2297 2290 recv_msg->user_msg_data = user_msg_data; 2298 2291 ··· 2296 2303 if (smi_msg == NULL) { 2297 2304 if (!supplied_recv) 2298 2305 ipmi_free_recv_msg(recv_msg); 2299 - rv = -ENOMEM; 2300 - goto out; 2306 + return -ENOMEM; 2301 2307 } 2302 2308 } 2303 2309 ··· 2307 2315 goto out_err; 2308 2316 } 2309 2317 2310 - recv_msg->user = user; 2311 - if (user) 2312 - /* The put happens when the message is freed. */ 2313 - kref_get(&user->refcount); 2314 2318 recv_msg->msgid = msgid; 2315 2319 /* 2316 2320 * Store the message to send in the receive message so timeout ··· 2335 2347 2336 2348 if (rv) { 2337 2349 out_err: 2338 - ipmi_free_smi_msg(smi_msg); 2339 - ipmi_free_recv_msg(recv_msg); 2350 + if (!supplied_smi) 2351 + ipmi_free_smi_msg(smi_msg); 2352 + if (!supplied_recv) 2353 + ipmi_free_recv_msg(recv_msg); 2340 2354 } else { 2341 2355 dev_dbg(intf->si_dev, "Send: %*ph\n", 2342 2356 smi_msg->data_size, smi_msg->data); ··· 2348 2358 if (!run_to_completion) 2349 2359 mutex_unlock(&intf->users_mutex); 2350 2360 2351 - out: 2352 - if (rv && user) 2353 - atomic_dec(&user->nr_msgs); 2354 2361 return rv; 2355 2362 } 2356 2363 ··· 3838 3851 unsigned char chan; 3839 3852 struct ipmi_user *user = NULL; 3840 3853 struct ipmi_ipmb_addr *ipmb_addr; 3841 - struct ipmi_recv_msg *recv_msg; 3854 + struct ipmi_recv_msg *recv_msg = NULL; 3842 3855 3843 3856 if (msg->rsp_size < 10) { 3844 3857 /* Message not big enough, just ignore it. */ ··· 3859 3872 rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); 3860 3873 if (rcvr) { 3861 3874 user = rcvr->user; 3862 - kref_get(&user->refcount); 3863 - } else 3864 - user = NULL; 3875 + recv_msg = ipmi_alloc_recv_msg(user); 3876 + } 3865 3877 rcu_read_unlock(); 3866 3878 3867 3879 if (user == NULL) { ··· 3890 3904 * causes it to not be freed or queued. 3891 3905 */ 3892 3906 rv = -1; 3907 + } else if (!IS_ERR(recv_msg)) { 3908 + /* Extract the source address from the data. */ 3909 + ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; 3910 + ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE; 3911 + ipmb_addr->slave_addr = msg->rsp[6]; 3912 + ipmb_addr->lun = msg->rsp[7] & 3; 3913 + ipmb_addr->channel = msg->rsp[3] & 0xf; 3914 + 3915 + /* 3916 + * Extract the rest of the message information 3917 + * from the IPMB header. 3918 + */ 3919 + recv_msg->recv_type = IPMI_CMD_RECV_TYPE; 3920 + recv_msg->msgid = msg->rsp[7] >> 2; 3921 + recv_msg->msg.netfn = msg->rsp[4] >> 2; 3922 + recv_msg->msg.cmd = msg->rsp[8]; 3923 + recv_msg->msg.data = recv_msg->msg_data; 3924 + 3925 + /* 3926 + * We chop off 10, not 9 bytes because the checksum 3927 + * at the end also needs to be removed. 3928 + */ 3929 + recv_msg->msg.data_len = msg->rsp_size - 10; 3930 + memcpy(recv_msg->msg_data, &msg->rsp[9], 3931 + msg->rsp_size - 10); 3932 + if (deliver_response(intf, recv_msg)) 3933 + ipmi_inc_stat(intf, unhandled_commands); 3934 + else 3935 + ipmi_inc_stat(intf, handled_commands); 3893 3936 } else { 3894 - recv_msg = ipmi_alloc_recv_msg(); 3895 - if (!recv_msg) { 3896 - /* 3897 - * We couldn't allocate memory for the 3898 - * message, so requeue it for handling 3899 - * later. 3900 - */ 3901 - rv = 1; 3902 - kref_put(&user->refcount, free_ipmi_user); 3903 - } else { 3904 - /* Extract the source address from the data. */ 3905 - ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; 3906 - ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE; 3907 - ipmb_addr->slave_addr = msg->rsp[6]; 3908 - ipmb_addr->lun = msg->rsp[7] & 3; 3909 - ipmb_addr->channel = msg->rsp[3] & 0xf; 3910 - 3911 - /* 3912 - * Extract the rest of the message information 3913 - * from the IPMB header. 3914 - */ 3915 - recv_msg->user = user; 3916 - recv_msg->recv_type = IPMI_CMD_RECV_TYPE; 3917 - recv_msg->msgid = msg->rsp[7] >> 2; 3918 - recv_msg->msg.netfn = msg->rsp[4] >> 2; 3919 - recv_msg->msg.cmd = msg->rsp[8]; 3920 - recv_msg->msg.data = recv_msg->msg_data; 3921 - 3922 - /* 3923 - * We chop off 10, not 9 bytes because the checksum 3924 - * at the end also needs to be removed. 3925 - */ 3926 - recv_msg->msg.data_len = msg->rsp_size - 10; 3927 - memcpy(recv_msg->msg_data, &msg->rsp[9], 3928 - msg->rsp_size - 10); 3929 - if (deliver_response(intf, recv_msg)) 3930 - ipmi_inc_stat(intf, unhandled_commands); 3931 - else 3932 - ipmi_inc_stat(intf, handled_commands); 3933 - } 3937 + /* 3938 + * We couldn't allocate memory for the message, so 3939 + * requeue it for handling later. 3940 + */ 3941 + rv = 1; 3934 3942 } 3935 3943 3936 3944 return rv; ··· 3937 3957 int rv = 0; 3938 3958 struct ipmi_user *user = NULL; 3939 3959 struct ipmi_ipmb_direct_addr *daddr; 3940 - struct ipmi_recv_msg *recv_msg; 3960 + struct ipmi_recv_msg *recv_msg = NULL; 3941 3961 unsigned char netfn = msg->rsp[0] >> 2; 3942 3962 unsigned char cmd = msg->rsp[3]; 3943 3963 ··· 3946 3966 rcvr = find_cmd_rcvr(intf, netfn, cmd, 0); 3947 3967 if (rcvr) { 3948 3968 user = rcvr->user; 3949 - kref_get(&user->refcount); 3950 - } else 3951 - user = NULL; 3969 + recv_msg = ipmi_alloc_recv_msg(user); 3970 + } 3952 3971 rcu_read_unlock(); 3953 3972 3954 3973 if (user == NULL) { ··· 3969 3990 * causes it to not be freed or queued. 3970 3991 */ 3971 3992 rv = -1; 3993 + } else if (!IS_ERR(recv_msg)) { 3994 + /* Extract the source address from the data. */ 3995 + daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; 3996 + daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; 3997 + daddr->channel = 0; 3998 + daddr->slave_addr = msg->rsp[1]; 3999 + daddr->rs_lun = msg->rsp[0] & 3; 4000 + daddr->rq_lun = msg->rsp[2] & 3; 4001 + 4002 + /* 4003 + * Extract the rest of the message information 4004 + * from the IPMB header. 4005 + */ 4006 + recv_msg->recv_type = IPMI_CMD_RECV_TYPE; 4007 + recv_msg->msgid = (msg->rsp[2] >> 2); 4008 + recv_msg->msg.netfn = msg->rsp[0] >> 2; 4009 + recv_msg->msg.cmd = msg->rsp[3]; 4010 + recv_msg->msg.data = recv_msg->msg_data; 4011 + 4012 + recv_msg->msg.data_len = msg->rsp_size - 4; 4013 + memcpy(recv_msg->msg_data, msg->rsp + 4, 4014 + msg->rsp_size - 4); 4015 + if (deliver_response(intf, recv_msg)) 4016 + ipmi_inc_stat(intf, unhandled_commands); 4017 + else 4018 + ipmi_inc_stat(intf, handled_commands); 3972 4019 } else { 3973 - recv_msg = ipmi_alloc_recv_msg(); 3974 - if (!recv_msg) { 3975 - /* 3976 - * We couldn't allocate memory for the 3977 - * message, so requeue it for handling 3978 - * later. 3979 - */ 3980 - rv = 1; 3981 - kref_put(&user->refcount, free_ipmi_user); 3982 - } else { 3983 - /* Extract the source address from the data. */ 3984 - daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; 3985 - daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; 3986 - daddr->channel = 0; 3987 - daddr->slave_addr = msg->rsp[1]; 3988 - daddr->rs_lun = msg->rsp[0] & 3; 3989 - daddr->rq_lun = msg->rsp[2] & 3; 3990 - 3991 - /* 3992 - * Extract the rest of the message information 3993 - * from the IPMB header. 3994 - */ 3995 - recv_msg->user = user; 3996 - recv_msg->recv_type = IPMI_CMD_RECV_TYPE; 3997 - recv_msg->msgid = (msg->rsp[2] >> 2); 3998 - recv_msg->msg.netfn = msg->rsp[0] >> 2; 3999 - recv_msg->msg.cmd = msg->rsp[3]; 4000 - recv_msg->msg.data = recv_msg->msg_data; 4001 - 4002 - recv_msg->msg.data_len = msg->rsp_size - 4; 4003 - memcpy(recv_msg->msg_data, msg->rsp + 4, 4004 - msg->rsp_size - 4); 4005 - if (deliver_response(intf, recv_msg)) 4006 - ipmi_inc_stat(intf, unhandled_commands); 4007 - else 4008 - ipmi_inc_stat(intf, handled_commands); 4009 - } 4020 + /* 4021 + * We couldn't allocate memory for the message, so 4022 + * requeue it for handling later. 4023 + */ 4024 + rv = 1; 4010 4025 } 4011 4026 4012 4027 return rv; ··· 4114 4141 unsigned char chan; 4115 4142 struct ipmi_user *user = NULL; 4116 4143 struct ipmi_lan_addr *lan_addr; 4117 - struct ipmi_recv_msg *recv_msg; 4144 + struct ipmi_recv_msg *recv_msg = NULL; 4118 4145 4119 4146 if (msg->rsp_size < 12) { 4120 4147 /* Message not big enough, just ignore it. */ ··· 4135 4162 rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); 4136 4163 if (rcvr) { 4137 4164 user = rcvr->user; 4138 - kref_get(&user->refcount); 4139 - } else 4140 - user = NULL; 4165 + recv_msg = ipmi_alloc_recv_msg(user); 4166 + } 4141 4167 rcu_read_unlock(); 4142 4168 4143 4169 if (user == NULL) { ··· 4167 4195 * causes it to not be freed or queued. 4168 4196 */ 4169 4197 rv = -1; 4198 + } else if (!IS_ERR(recv_msg)) { 4199 + /* Extract the source address from the data. */ 4200 + lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; 4201 + lan_addr->addr_type = IPMI_LAN_ADDR_TYPE; 4202 + lan_addr->session_handle = msg->rsp[4]; 4203 + lan_addr->remote_SWID = msg->rsp[8]; 4204 + lan_addr->local_SWID = msg->rsp[5]; 4205 + lan_addr->lun = msg->rsp[9] & 3; 4206 + lan_addr->channel = msg->rsp[3] & 0xf; 4207 + lan_addr->privilege = msg->rsp[3] >> 4; 4208 + 4209 + /* 4210 + * Extract the rest of the message information 4211 + * from the IPMB header. 4212 + */ 4213 + recv_msg->recv_type = IPMI_CMD_RECV_TYPE; 4214 + recv_msg->msgid = msg->rsp[9] >> 2; 4215 + recv_msg->msg.netfn = msg->rsp[6] >> 2; 4216 + recv_msg->msg.cmd = msg->rsp[10]; 4217 + recv_msg->msg.data = recv_msg->msg_data; 4218 + 4219 + /* 4220 + * We chop off 12, not 11 bytes because the checksum 4221 + * at the end also needs to be removed. 4222 + */ 4223 + recv_msg->msg.data_len = msg->rsp_size - 12; 4224 + memcpy(recv_msg->msg_data, &msg->rsp[11], 4225 + msg->rsp_size - 12); 4226 + if (deliver_response(intf, recv_msg)) 4227 + ipmi_inc_stat(intf, unhandled_commands); 4228 + else 4229 + ipmi_inc_stat(intf, handled_commands); 4170 4230 } else { 4171 - recv_msg = ipmi_alloc_recv_msg(); 4172 - if (!recv_msg) { 4173 - /* 4174 - * We couldn't allocate memory for the 4175 - * message, so requeue it for handling later. 4176 - */ 4177 - rv = 1; 4178 - kref_put(&user->refcount, free_ipmi_user); 4179 - } else { 4180 - /* Extract the source address from the data. */ 4181 - lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; 4182 - lan_addr->addr_type = IPMI_LAN_ADDR_TYPE; 4183 - lan_addr->session_handle = msg->rsp[4]; 4184 - lan_addr->remote_SWID = msg->rsp[8]; 4185 - lan_addr->local_SWID = msg->rsp[5]; 4186 - lan_addr->lun = msg->rsp[9] & 3; 4187 - lan_addr->channel = msg->rsp[3] & 0xf; 4188 - lan_addr->privilege = msg->rsp[3] >> 4; 4189 - 4190 - /* 4191 - * Extract the rest of the message information 4192 - * from the IPMB header. 4193 - */ 4194 - recv_msg->user = user; 4195 - recv_msg->recv_type = IPMI_CMD_RECV_TYPE; 4196 - recv_msg->msgid = msg->rsp[9] >> 2; 4197 - recv_msg->msg.netfn = msg->rsp[6] >> 2; 4198 - recv_msg->msg.cmd = msg->rsp[10]; 4199 - recv_msg->msg.data = recv_msg->msg_data; 4200 - 4201 - /* 4202 - * We chop off 12, not 11 bytes because the checksum 4203 - * at the end also needs to be removed. 4204 - */ 4205 - recv_msg->msg.data_len = msg->rsp_size - 12; 4206 - memcpy(recv_msg->msg_data, &msg->rsp[11], 4207 - msg->rsp_size - 12); 4208 - if (deliver_response(intf, recv_msg)) 4209 - ipmi_inc_stat(intf, unhandled_commands); 4210 - else 4211 - ipmi_inc_stat(intf, handled_commands); 4212 - } 4231 + /* 4232 + * We couldn't allocate memory for the message, so 4233 + * requeue it for handling later. 4234 + */ 4235 + rv = 1; 4213 4236 } 4214 4237 4215 4238 return rv; ··· 4226 4259 unsigned char chan; 4227 4260 struct ipmi_user *user = NULL; 4228 4261 struct ipmi_system_interface_addr *smi_addr; 4229 - struct ipmi_recv_msg *recv_msg; 4262 + struct ipmi_recv_msg *recv_msg = NULL; 4230 4263 4231 4264 /* 4232 4265 * We expect the OEM SW to perform error checking ··· 4255 4288 rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); 4256 4289 if (rcvr) { 4257 4290 user = rcvr->user; 4258 - kref_get(&user->refcount); 4259 - } else 4260 - user = NULL; 4291 + recv_msg = ipmi_alloc_recv_msg(user); 4292 + } 4261 4293 rcu_read_unlock(); 4262 4294 4263 4295 if (user == NULL) { ··· 4269 4303 */ 4270 4304 4271 4305 rv = 0; 4306 + } else if (!IS_ERR(recv_msg)) { 4307 + /* 4308 + * OEM Messages are expected to be delivered via 4309 + * the system interface to SMS software. We might 4310 + * need to visit this again depending on OEM 4311 + * requirements 4312 + */ 4313 + smi_addr = ((struct ipmi_system_interface_addr *) 4314 + &recv_msg->addr); 4315 + smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; 4316 + smi_addr->channel = IPMI_BMC_CHANNEL; 4317 + smi_addr->lun = msg->rsp[0] & 3; 4318 + 4319 + recv_msg->user_msg_data = NULL; 4320 + recv_msg->recv_type = IPMI_OEM_RECV_TYPE; 4321 + recv_msg->msg.netfn = msg->rsp[0] >> 2; 4322 + recv_msg->msg.cmd = msg->rsp[1]; 4323 + recv_msg->msg.data = recv_msg->msg_data; 4324 + 4325 + /* 4326 + * The message starts at byte 4 which follows the 4327 + * Channel Byte in the "GET MESSAGE" command 4328 + */ 4329 + recv_msg->msg.data_len = msg->rsp_size - 4; 4330 + memcpy(recv_msg->msg_data, &msg->rsp[4], 4331 + msg->rsp_size - 4); 4332 + if (deliver_response(intf, recv_msg)) 4333 + ipmi_inc_stat(intf, unhandled_commands); 4334 + else 4335 + ipmi_inc_stat(intf, handled_commands); 4272 4336 } else { 4273 - recv_msg = ipmi_alloc_recv_msg(); 4274 - if (!recv_msg) { 4275 - /* 4276 - * We couldn't allocate memory for the 4277 - * message, so requeue it for handling 4278 - * later. 4279 - */ 4280 - rv = 1; 4281 - kref_put(&user->refcount, free_ipmi_user); 4282 - } else { 4283 - /* 4284 - * OEM Messages are expected to be delivered via 4285 - * the system interface to SMS software. We might 4286 - * need to visit this again depending on OEM 4287 - * requirements 4288 - */ 4289 - smi_addr = ((struct ipmi_system_interface_addr *) 4290 - &recv_msg->addr); 4291 - smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; 4292 - smi_addr->channel = IPMI_BMC_CHANNEL; 4293 - smi_addr->lun = msg->rsp[0] & 3; 4294 - 4295 - recv_msg->user = user; 4296 - recv_msg->user_msg_data = NULL; 4297 - recv_msg->recv_type = IPMI_OEM_RECV_TYPE; 4298 - recv_msg->msg.netfn = msg->rsp[0] >> 2; 4299 - recv_msg->msg.cmd = msg->rsp[1]; 4300 - recv_msg->msg.data = recv_msg->msg_data; 4301 - 4302 - /* 4303 - * The message starts at byte 4 which follows the 4304 - * Channel Byte in the "GET MESSAGE" command 4305 - */ 4306 - recv_msg->msg.data_len = msg->rsp_size - 4; 4307 - memcpy(recv_msg->msg_data, &msg->rsp[4], 4308 - msg->rsp_size - 4); 4309 - if (deliver_response(intf, recv_msg)) 4310 - ipmi_inc_stat(intf, unhandled_commands); 4311 - else 4312 - ipmi_inc_stat(intf, handled_commands); 4313 - } 4337 + /* 4338 + * We couldn't allocate memory for the message, so 4339 + * requeue it for handling later. 4340 + */ 4341 + rv = 1; 4314 4342 } 4315 4343 4316 4344 return rv; ··· 4362 4402 if (!user->gets_events) 4363 4403 continue; 4364 4404 4365 - recv_msg = ipmi_alloc_recv_msg(); 4366 - if (!recv_msg) { 4405 + recv_msg = ipmi_alloc_recv_msg(user); 4406 + if (IS_ERR(recv_msg)) { 4367 4407 mutex_unlock(&intf->users_mutex); 4368 4408 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, 4369 4409 link) { ··· 4384 4424 deliver_count++; 4385 4425 4386 4426 copy_event_into_recv_msg(recv_msg, msg); 4387 - recv_msg->user = user; 4388 - kref_get(&user->refcount); 4389 4427 list_add_tail(&recv_msg->link, &msgs); 4390 4428 } 4391 4429 mutex_unlock(&intf->users_mutex); ··· 4399 4441 * No one to receive the message, put it in queue if there's 4400 4442 * not already too many things in the queue. 4401 4443 */ 4402 - recv_msg = ipmi_alloc_recv_msg(); 4403 - if (!recv_msg) { 4444 + recv_msg = ipmi_alloc_recv_msg(NULL); 4445 + if (IS_ERR(recv_msg)) { 4404 4446 /* 4405 4447 * We couldn't allocate memory for the 4406 4448 * message, so requeue it for handling ··· 4816 4858 4817 4859 list_del(&msg->link); 4818 4860 4819 - if (refcount_read(&user->destroyed) == 0) { 4861 + if (refcount_read(&user->destroyed) == 0) 4820 4862 ipmi_free_recv_msg(msg); 4821 - } else { 4822 - atomic_dec(&user->nr_msgs); 4863 + else 4823 4864 user->handler->ipmi_recv_hndl(msg, user->handler_data); 4824 - } 4825 4865 } 4826 4866 mutex_unlock(&intf->user_msgs_mutex); 4827 4867 ··· 5135 5179 kfree(msg); 5136 5180 } 5137 5181 5138 - static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) 5182 + static struct ipmi_recv_msg *ipmi_alloc_recv_msg(struct ipmi_user *user) 5139 5183 { 5140 5184 struct ipmi_recv_msg *rv; 5141 5185 5142 - rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC); 5143 - if (rv) { 5144 - rv->user = NULL; 5145 - rv->done = free_recv_msg; 5146 - atomic_inc(&recv_msg_inuse_count); 5186 + if (user) { 5187 + if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) { 5188 + atomic_dec(&user->nr_msgs); 5189 + return ERR_PTR(-EBUSY); 5190 + } 5147 5191 } 5192 + 5193 + rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC); 5194 + if (!rv) { 5195 + if (user) 5196 + atomic_dec(&user->nr_msgs); 5197 + return ERR_PTR(-ENOMEM); 5198 + } 5199 + 5200 + rv->user = user; 5201 + rv->done = free_recv_msg; 5202 + if (user) 5203 + kref_get(&user->refcount); 5204 + atomic_inc(&recv_msg_inuse_count); 5148 5205 return rv; 5149 5206 } 5150 5207 5151 5208 void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) 5152 5209 { 5153 - if (msg->user && !oops_in_progress) 5210 + if (msg->user && !oops_in_progress) { 5211 + atomic_dec(&msg->user->nr_msgs); 5154 5212 kref_put(&msg->user->refcount, free_ipmi_user); 5213 + } 5155 5214 msg->done(msg); 5156 5215 } 5157 5216 EXPORT_SYMBOL(ipmi_free_recv_msg); 5217 + 5218 + static void ipmi_set_recv_msg_user(struct ipmi_recv_msg *msg, 5219 + struct ipmi_user *user) 5220 + { 5221 + WARN_ON_ONCE(msg->user); /* User should not be set. */ 5222 + msg->user = user; 5223 + atomic_inc(&user->nr_msgs); 5224 + kref_get(&user->refcount); 5225 + } 5158 5226 5159 5227 static atomic_t panic_done_count = ATOMIC_INIT(0); 5160 5228