Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bug or feature? Handling of $var is different to ${var} #178

Open
poWer4aiX opened this issue Sep 20, 2022 · 1 comment
Open

Bug or feature? Handling of $var is different to ${var} #178

poWer4aiX opened this issue Sep 20, 2022 · 1 comment

Comments

@poWer4aiX
Copy link

I'm not sure if it is bug or a feature, but if you try to execute a command in a login shell, then the behavior when using $var and ${var} is different (which is unusual).

To replicate execute:

$ sudo -i bash -c '(export var=/etc; cd $var; pwd)'
/root
$ sudo -i bash -c '(export var=/etc; cd ${var}; pwd)'
/etc

In our case we are glad that ${var} is working as expected, i.e. is is NOT expanded before, so that cd would change into /etc in this example.

I guess the reason is the escape handling in parse_args in src/parse_args.c:

sudo/src/parse_args.c

Lines 626 to 634 in 304726a

for (dst = cmnd, av = argv; *av != NULL; av++) {
for (src = *av; *src != '\0'; src++) {
/* quote potential meta characters */
if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')
*dst++ = '\\';
*dst++ = *src;
}
*dst++ = ' ';
}

As the $ is not being escaped but the { and } (is not alnum), the resulting arguments passed to the shell are different, which can also be verified in the debug log:

Sep 20 14:48:40 sudo[9839] -> sudo_execve @ ./exec_common.c:184
Sep 20 14:48:40 sudo[9839] exec /bin/bash [-bash --login -c bash -c \(export\ var\=\/etc\;\ cd\ $\{var\}\;\ pwd\;\ env\|grep\ SUDO_C\)] [HOSTNAME=
...
Sep 20 14:51:08 sudo[10689] -> sudo_execve @ ./exec_common.c:184
Sep 20 14:51:08 sudo[10689] exec /bin/bash [-bash --login -c bash -c \(export\ var\=\/etc\;\ cd\ $var\;\ pwd\;\ env\|grep\ SUDO_C\)] [HOSTNAME=

The main question here is, is this a bug or a feature? We are using the ${var} variant in tons of productive workflow environments and we don't want to fall into a trap, once the behavior get changed and we are updating to a newer version.

Environment details:

  • sudo version: 1.8.23
  • OS: RHEL 7.9 running in AWS (same behavior can be seen in ubuntu 22.04 and others)

Thanks, Christian

@ljluestc
Copy link

ljluestc commented Sep 4, 2023

The behavior you're observing is due to how the shell interprets variable expansion and escaping. The distinction between $var and ${var} is not specific to sudo but is a characteristic of how shells handle variable expansion.

  • $var: This form directly substitutes the value of the variable var into the command line. In your example, it substitutes /etc into the cd command before the command is executed.

  • ${var}: This form separates the variable name from any surrounding characters. It is often used to disambiguate the variable name from adjacent characters. In your example, ${var} is treated as a whole and substituted as /etc after the cd command is executed.

The behavior you're observing is consistent with how shells work. It's not a bug in sudo but rather a behavior of shell variable expansion.

As for using ${var} in your productive workflow environments, you should be safe to continue using it. Shells have been behaving this way for a long time, and changes in behavior are unlikely unless there's a major change in shell behavior across various operating systems.

In summary, the behavior you're observing is not a bug in sudo or any specific tool; it's how shells handle variable expansion. You can continue to use ${var} in your workflow environments without concerns about unexpected changes in behavior.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants