diff options
Diffstat (limited to 'arch/x86/kernel/ds.c')
| -rw-r--r-- | arch/x86/kernel/ds.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 2b69994fd3a..d1a121443bd 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c | |||
| @@ -236,17 +236,33 @@ static inline struct ds_context *ds_alloc_context(struct task_struct *task) | |||
| 236 | struct ds_context *context = *p_context; | 236 | struct ds_context *context = *p_context; |
| 237 | 237 | ||
| 238 | if (!context) { | 238 | if (!context) { |
| 239 | spin_unlock(&ds_lock); | ||
| 240 | |||
| 239 | context = kzalloc(sizeof(*context), GFP_KERNEL); | 241 | context = kzalloc(sizeof(*context), GFP_KERNEL); |
| 240 | 242 | ||
| 241 | if (!context) | 243 | if (!context) { |
| 244 | spin_lock(&ds_lock); | ||
| 242 | return NULL; | 245 | return NULL; |
| 246 | } | ||
| 243 | 247 | ||
| 244 | context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); | 248 | context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); |
| 245 | if (!context->ds) { | 249 | if (!context->ds) { |
| 246 | kfree(context); | 250 | kfree(context); |
| 251 | spin_lock(&ds_lock); | ||
| 247 | return NULL; | 252 | return NULL; |
| 248 | } | 253 | } |
| 249 | 254 | ||
| 255 | spin_lock(&ds_lock); | ||
| 256 | /* | ||
| 257 | * Check for race - another CPU could have allocated | ||
| 258 | * it meanwhile: | ||
| 259 | */ | ||
| 260 | if (*p_context) { | ||
| 261 | kfree(context->ds); | ||
| 262 | kfree(context); | ||
| 263 | return *p_context; | ||
| 264 | } | ||
| 265 | |||
| 250 | *p_context = context; | 266 | *p_context = context; |
| 251 | 267 | ||
| 252 | context->this = p_context; | 268 | context->this = p_context; |
| @@ -384,14 +400,15 @@ static int ds_request(struct task_struct *task, void *base, size_t size, | |||
| 384 | 400 | ||
| 385 | spin_lock(&ds_lock); | 401 | spin_lock(&ds_lock); |
| 386 | 402 | ||
| 387 | if (!check_tracer(task)) | ||
| 388 | return -EPERM; | ||
| 389 | |||
| 390 | error = -ENOMEM; | 403 | error = -ENOMEM; |
| 391 | context = ds_alloc_context(task); | 404 | context = ds_alloc_context(task); |
| 392 | if (!context) | 405 | if (!context) |
| 393 | goto out_unlock; | 406 | goto out_unlock; |
| 394 | 407 | ||
| 408 | error = -EPERM; | ||
| 409 | if (!check_tracer(task)) | ||
| 410 | goto out_unlock; | ||
| 411 | |||
| 395 | error = -EALREADY; | 412 | error = -EALREADY; |
| 396 | if (context->owner[qual] == current) | 413 | if (context->owner[qual] == current) |
| 397 | goto out_unlock; | 414 | goto out_unlock; |
