Skip to content

MDEV-6733: Add DEFINER support to ALTER PROCEDURE#5060

Open
amrSherif12 wants to merge 1 commit intoMariaDB:mainfrom
amrSherif12:MDEV-6733
Open

MDEV-6733: Add DEFINER support to ALTER PROCEDURE#5060
amrSherif12 wants to merge 1 commit intoMariaDB:mainfrom
amrSherif12:MDEV-6733

Conversation

@amrSherif12
Copy link
Copy Markdown

This PR implements the ALTER PROCEDURE ... DEFINER = ... syntax

  • users with sufficient privileges (SUPER or SET USER) can change the definer of an existing stored procedure.
  • no whitespace changes
  • .test and .result commited

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the ability to change the definer of a stored procedure using the ALTER PROCEDURE statement. The changes include updates to the parser, the routine update handler, and the addition of privilege checks. Feedback includes addressing a potential buffer overflow when handling user/host strings, utilizing existing helper functions for more robust privilege and hostname checks, ensuring the procedure cache is invalidated only upon successful updates, and correcting a type mismatch in the grammar definition.

Comment thread sql/sp.cc
Comment on lines +1775 to +1781
char definer_str[USER_HOST_BUFF_SIZE];
uint definer_len= strxmov(definer_str, definer->user.str, "@",
definer->host.str, NullS) -
definer_str;
table->field[MYSQL_PROC_FIELD_DEFINER]->set_notnull();
table->field[MYSQL_PROC_FIELD_DEFINER]->store(definer_str, definer_len,
system_charset_info);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Using a fixed-size buffer of USER_HOST_BUFF_SIZE (142 bytes) is unsafe. In modern MariaDB, usernames can be up to 128 characters, which in UTF-8 can exceed this buffer size when combined with the hostname. This could lead to a buffer overflow. It is safer to use the String class which handles dynamic allocation and correctly manages lengths.

        String definer_str;
        definer_str.append(definer->user.str, definer->user.length);
        definer_str.append('@');
        definer_str.append(definer->host.str, definer->host.length);
        table->field[MYSQL_PROC_FIELD_DEFINER]->set_notnull();
        table->field[MYSQL_PROC_FIELD_DEFINER]->store(definer_str.ptr(),
                                                      definer_str.length(),
                                                      system_charset_info);

Comment thread sql/sql_parse.cc
Comment on lines +6451 to +6457
if (lex->definer)
{
if ((!lex_string_eq(&lex->definer->user, thd->security_ctx->priv_user, strlen(thd->security_ctx->priv_user)) ||
!lex_string_eq(&lex->definer->host, thd->security_ctx->priv_host, strlen(thd->security_ctx->priv_host))) &&
check_global_access(thd, SET_USER_ACL | SUPER_ACL))
return 1;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Instead of manually implementing the privilege check, you should use the existing check_definer_access() function. This improves maintainability and fixes a bug in the current implementation: lex_string_eq is case-sensitive, but hostnames in MariaDB should be compared case-insensitively. check_definer_access() handles this correctly using my_strcasecmp for the host part.

  if (lex->definer && check_definer_access(thd, lex->definer))
    return 1;

Comment thread sql/sp.cc
table->field[MYSQL_PROC_FIELD_DEFINER]->set_notnull();
table->field[MYSQL_PROC_FIELD_DEFINER]->store(definer_str, definer_len,
system_charset_info);
sp_cache_invalidate();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The call to sp_cache_invalidate() should ideally be placed after the successful execution of ha_update_row(). This ensures the cache is only invalidated if the database record was actually updated. Furthermore, consider if the cache should be invalidated for any characteristic change (like COMMENT), as the cached sp_head object contains these values and might become stale.

Comment thread sql/sql_yacc.yy
%type <lex_user> user grant_user grant_role user_or_role current_role
admin_option_for_role user_maybe_role role_name
user_name
user_name sp_a_chistic
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Declaring sp_a_chistic as <lex_user> is technically incorrect because the sp_chistic branch of this rule does not return a LEX_USER* value. Since the value of sp_a_chistic is not used by the parent sp_a_chistics rule, it should remain untyped to avoid potential issues with uninitialized values in the parser.

                 user_name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant